如何测试 Android 上的每日警报?

How to test daily alarms on Android?

我的一个宠物项目显示了用户定义的特定日期的通知。我用

AlarmManger.setRepeating(AlarmManager.RTC_WAKEUP, millis, AlarmManager.INTERVAL_DAY, pendingIntent)

安排每天启动应用程序的警报,以决定它今天是否应该显示通知。

问题是有时日常闹钟会停止工作。我知道有很多原因(设备重启、date/time 更改、应用程序重新安装、打瞌睡模式),我确信还有一些我还没有找到的原因(欢迎提出想法!)。

我的问题是如何针对所有可能的风险正确测试警报? 仪器测试适合这里吗?

设备重启时重新注册您的警报管理器,date/time更改正常工作。

My question is how to test alarms properly against all possible risks? Do instrumentation tests fit here?

由于 AlarmManager 是 Android OS 的一部分,因此经过了很好的测试,您无需进行任何检测或单元测试即可对其进行测试。您可以测试您的闹钟调用的服务,但无需测试您的闹钟设置是否正确。

只有少数情况下您的警报会掉线、无效或被忽略。你已经给他们打电话了:

  • 重新启动时
  • 准时变更
  • 打瞌睡模式

现在您可以使用系统通知(OS 广播)重新配置您的闹钟。

On reboot
警报在设备关闭时消失,因此在重新启动时重新设置

public class BootReceiver extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {
        if (Intent.ACTION_BOOT_COMPLETED.equals(intent.getAction())) {
            // set repeating alarm 
            MyAlarmMangerSupport.set(context);
        }
    }
}

On time change
时间变化相同的程序:

public class TimeChangeReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        final String action = intent.getAction();

        if (Intent.ACTION_TIME_CHANGED.equals(action ) || Intent.ACTION_TIMEZONE_CHANGED.equals(action )) {
            // cancel previous alarm and set a new one
            MyAlarmMangerSupport.cancelAndSet(context);
        }
    }
}

On doze mode
如果设备进入 the doze mode,我相信没有必要显示任何 不相关的 通知 无论如何,即使设备处于打瞌睡状态,也有一种方法可以触发警报。

重要的是要知道,瞌睡模式是从 API 23 级开始的新功能

  1. 用户必须 whitelist your app and disable Battery Optimization 为您的应用程序。

  2. 使用setExactAndAllowWhileIdle方法为android级别23+的设备设置闹钟:

    alarmManager.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, period, pendingIntent);
    

    重要提示:这是一个单发警报,您必须在警报接收器中再次设置它:

    public class AlarmReceiver extends BroadcastReceiver {
        @Override
        public void onReceive(Context context, Intent intent) {
            final String action = intent.getAction();
    
            if ("my-Pet-Notification".equals(action )) {
                 if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M){
                     // set repeating alarm, calls setExactAndAllowWhileIdle
                     MyAlarmMangerSupport.set(context);
                 }
    
                 //execute service to show notification
                 [..]
            }
        }
    }