重新启动后尝试在android中重新安排以前的警报通知的代码?并登录我的手机



我正试图遵循这个答案。然而,它在模拟器中和我的手机上都不起作用,所以我对模拟器日志和手机以及重新启动以模拟这个并调试有疑问

我在底部有非常有趣的笔记,这些笔记让我非常困惑

我正在使用API 24和像素3模拟器和真正的三星8手机

我做典型的清单添加

<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />

<receiver android:name=".biz.alarm.BootupReceiver" >
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>

然而,我从来没有看到过这个日志声明。。。

public class BootupReceiver extends BroadcastReceiver {
private final static String TAG = "BootupReceiver";
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
Log.d(TAG, "booted. action="+action);
}
}

对于模拟,我点击播放按钮,然后看着我的应用程序出现。然后我按住电源按钮,它只会给我一个";"断电";当我真的只想重新启动时。。。奇怪,所以我关闭了电源。这似乎完全退出了模拟,这样当我在安卓工作室的模拟器上再次点击播放时,它就会记录

08/06 19:17:40: Launching 'app' on Pixel 3 API 24.
$ adb shell am start -n "app.mykeepintouch.kit/app.mykeepintouch.kit.MainActivity" -a android.intent.action.MAIN -c android.intent.category.LAUNCHER
...
D/MainActivity: onCreate: starting

没有可供我重新注册通知的启动日志问题1:模拟器不能正确模拟吗

接下来,我的真实手机-我想也是一样,但也许至少我可以在手机上查看一些日志?我遇到的帖子谈到了转储到sd卡,但我插入了android工作室,所以我想我可以以某种方式将日志转储到android工作室?

编辑:我在那篇文章中也使用了示例链接。我做了一个git克隆,导入了项目,选择了API 24,并在PollReceiver中添加了一个日志。当我上床睡觉的时候,它起作用了,今天早上跑步的第二次跑步没有起作用。我会在调试我想到的随机场景时添加更多信息。

怪异场景1:如果我有两个android工作室项目打开,打开我的个人应用程序,然后在我的项目之后打开示例链接应用程序,我会看到一个Toast"定时报警";。然而,在5秒钟后警报响起之前,我在PollReceiver上找不到任何日志。我本来希望在开始时看到PollReceiver的日志,但直到5秒钟才看到。后来的另一次运行没有产生任何日志(除了弹出toast消息,所以我知道它运行了那个代码……非常奇怪)。当时我向ScheduledServiceDemoActivity添加了一条日志消息,现在我无法像那样一次重现0个日志。

奇怪的场景2:我重新启动了手机(或者它一直在启动我的应用程序,场景1一直在工作)。然后我只启动了示例链接应用程序,什么都没发生。我等了90秒,什么也没等。

这可能就是为什么它在昨晚我上床睡觉前起作用的原因,就像我在场景1中一样。

最后的猜测:我永远无法让PollReceiver在启动时启动。ScheduledServiceDemoActivity似乎是真正的切入点,我从未在上面的代码中添加过服务,因为我不想要。。。只是想被通知启动以重新安排警报这让我得出一个可能的结论ScheduledServiceDemoActivity在启动时会在某些设备上启动,而PollReceiver在启动时用于其他设备?如果是这样,什么模拟器可以模拟其他启动场景?

编辑(我有另一个想法)在我的三星手机上,我检查了权限,尽管我在清单中添加了这4行,但只有三行

<!-- So we can make a phone call out -->
<uses-permission android:name="android.permission.CALL_PHONE" />
<!-- so we can send a text -->
<uses-permission android:name="android.permission.SEND_SMS" />
<!-- So we can reschedule alarms that went off while powered off -->
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<!-- read contacts so they can easily choose their friends -->
<uses-permission android:name="android.permission.READ_CONTACTS" />

接收引导不在那里。这就是问题所在吗?或者手机没有向用户列出接收引导完成的情况,因为这可能会令人困惑?

谢谢,院长

尝试将其添加到清单中的意向过滤器:

<receiver android:name=".biz.alarm.BootupReceiver" >
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
<action android:name="android.intent.action.QUICKBOOT_POWERON"/>
</intent-filter>
</receiver> 

当我在某些设备上遇到类似问题时,它对我有所帮助。

您应该研究setExactAndAllowWhileIdle据我所知,无论手机是否处于休眠状态,它都会在指定的时间执行。

您在这里回答了他们自己的问题,但因为该回答使用了WorkManager API;用于可延迟的工作,即不需要立即运行,并且即使应用程序退出或设备重新启动也需要可靠运行;(来源)我觉得使用AlarmManager是处理您试图做的事情的最佳方式。

然而,需要注意的是,这仍然需要在每次启动时重新注册警报,考虑到OP的问题和担忧,这似乎很困难,但我已经在下面解决了这些问题。不过,如果你在警报触发后启动,你应该小心该怎么做。例如,假设你正在制作一个提醒应用程序,你希望能够安排通知的发送和发生,假设你的手机在提醒被触发之前关机,而在提醒被激活5分钟后开机。你仍然触发通知吗?您是否使用AlarmManager重新安排?你只是忽略了这一切吗?如果你确实触发了它,你希望在用户解锁设备之前触发它,还是在他们解锁设备之后触发它?

上述问题会改变确切的实现,但基本原理是完全相同的。

  1. 在系统中注册意向接收器
    <application>
    <!-- ... -->
    <receiver android:name="RECEIVER_NAME">
    <intent-filter>
    <action android:name="android.intent.action.BOOT_COMPLETED"/>
    <!--<action android:name="android.intent.action.LOCKED_BOOT_COMPLETED"/> this action is sent before the user unlocks their device-->
    </intent-filter>
    </receiver>
    <!-- ... -->
    </application>
    
  2. 使用BroadcastReceiver中的AlarmManager重新注册报警
    public class PollReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(final Context context, Intent intent) {
    if (intent.getAction() != null) {
    if (intent.getAction().equals(Intent.ACTION_BOOT_COMPLETED)) {
    AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
    Intent i = new Intent(context, PollReceiver.class);//this will send the intent back to this class, you can make another broadcast receiver for handling the alarm going off though
    i.setAction("ALARM_ACTION");
    PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, i, 0);
    long triggerTime = System.currentTimeMillis() + 60000; //replace this with when you want your alarm to go off (this will trigger 1 minute from now)
    AlarmManagerCompat.setExactAndAllowWhileIdle(alarmManager, AlarmManager.RTC_WAKEUP, triggerTime, pendingIntent);
    } else if (intent.getAction().equals("ALARM_ACTION")) {
    //Show notification or make noise, whatever you are supposed to do when the alarm goes off
    }
    }
    }
    }
    

解决问题中的各种问题

问题1:模拟器不能正确模拟[重新启动]吗?

然而,问题可能是您正在运行项目以启动模拟器,而不是手机的开机方式。与其在Android Studio中按下运行按钮来启动模拟器,不如通过工具自行启动模拟器>AVD管理器>播放按钮(在相应AVD的操作列下)或参阅下面的内容,了解在AVD运行时重新启动AVD的方法。

我想我可以以某种方式将日志转储到android工作室?

是的,你可以,在Android Studio的底部应该有一个名为Logcat的选项卡。此选项卡是任何连接的虚拟设备或物理设备输出日志的位置(如果有多个连接,则必须指定要查看的设备)。此外,还可以通过adb logcat使用命令行,也可以通过命令行通过adb reboot触发重新启动。你也可以将两者结合起来,这样一旦手机能够连接adb,你就可以通过adb reboot && adb wait-for-device logcat开始收听logcat。这对物理设备和模拟器都有效,唯一的问题是这会输出所有内容的日志,如果你想搜索特定的文本,你可以使用adb reboot && adb wait-for-device logcat | grep "string-to-search-for"(Windows可以用"findstr"代替"grep")

奇怪的场景1:如果我有两个android工作室项目打开,打开我的个人应用程序,然后在我的项目后打开示例链接应用程序,我会看到一个Toast"定时报警";。然而,在5秒钟后警报响起之前,我在PollReceiver上找不到任何日志。我本来希望在开始时看到PollReceiver的日志,但直到5秒钟才看到。后来的另一次运行没有产生任何日志(除了弹出toast消息,所以我知道它运行了那个代码……非常奇怪)。当时我向ScheduledServiceDemoActivity添加了一条日志消息,现在我无法像那样一次重现0个日志。

您在第一部分中描述的行为是正确的,无论您打开了多少个Android Studio项目以及首先运行哪个应用程序,都应该发生这种行为。该应用程序会重复发出警报,警报将在5秒内熄灭,然后每15分钟熄灭一次。如果您将日志添加到onReceive方法中,那么在调用该方法之前,您不会看到它,而在警报响起之前,您也不会看到它。至于第二部分,您没有得到任何日志,您可能没有让应用程序运行5秒,因此不会打印日志。需要注意的是,当你通过Android Studio运行应用程序时,它与你通过点击图标从手机运行应用程序并不完全相同。这也可以解释为什么在将日志添加到活动中后无法重新创建它。

奇怪的场景2:我重新启动了手机(或者它一直在启动我的应用程序,场景1一直在工作)。然后我只启动了示例链接应用程序,什么都没发生。我等了90秒,什么也没等。

示例应用程序应该大约每15分钟触发一次日志,而不是90秒(900000ms而不是90000ms)。然而,示例应用程序应该在启动应用程序后或重新启动后5秒(但由于Android的工作方式,不完全是5秒)触发日志。

我永远无法在启动时启动PollReceiver。ScheduledServiceDemoActivity似乎是真正的切入点,我从未在上面的代码中添加过服务,因为我不想要。。。只是想被通知启动以重新安排警报。这让我得出了一个可能的结论,ScheduledServiceDemoActivity在启动时会在某些设备上启动,而PollReceiver则用于启动时的其他设备?如果是这样,什么模拟器可以模拟其他启动场景?

您应该真正熟悉应用程序生命周期和活动生命周期。ScheduledServiceDemoActivity是在Android Studio中运行或按下启动器上的图标启动应用程序时打开的,但BroadcastReceiver也是应用程序的另一个入口点。在这种情况下,当Android发送带有action_BOOT_COMPLETED操作的Intent时,它会被触发。ScheduledServiceDemoActivity将永远不会在启动时启动。捆绑的AVD可以正确模拟启动场景,它将触发PollReceiver。

EDIT(我有另一个想法)在我的三星手机上,我检查了权限,只有三行,尽管我在清单中添加了这四行

<uses-permission android:name="android.permission.CALL_PHONE" />
<!-- so we can send a text -->
<uses-permission android:name="android.permission.SEND_SMS" />
<!-- So we can reschedule alarms that went off while powered off -->
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<!-- read contacts so they can easily choose their friends -->
<uses-permission android:name="android.permission.READ_CONTACTS" />

接收引导不在那里。这就是问题所在吗?或者手机没有向用户列出接收引导完成的情况,因为这可能会令人困惑?

设备上的大多数Android变体(如果不是全部的话)将不会显示被视为";正常的";谷歌。基本上,将在那里显示的唯一权限是在安装时没有自动授予的权限;危险的";因为它们可能会影响用户存储的数据或其他应用程序的行为。

好吧,我找到了答案

安卓8/9通知调度

我不知道你必须在谷歌上搜索版本。

最新更新