我想在单元测试中测试是否触发使用AlarmManager编程的报警,如果是,则在正确的时间内触发.
@H_403_2@以下是要测试的接收器类.
我在我的测试项目中创建了它.
(注意:它没有在清单中注册)
我可以确认AlarmManager不是问题.报警根据adb dumpsys报警正确注册. @H_403_2@我现在试图通过调用sendBroadcast来让接收方运行,但是我处于死胡同.接收器不会被调用.我尝试了主应用程序上下文,测试用例上下文,甚至是ActivityInstrumentationTestCase2.试过还添加了WakeLocks和没有.没有办法得到它.我认为这可能是由于意图或意图过滤器中的一些标志引起的(android似乎真的很挑剔标志).
我在我的测试项目中创建了它.
(注意:它没有在清单中注册)
public class MockBroadcastReceiver extends BroadcastReceiver { private static int numTimesCalled = 0; MockBroadcastReceiver(){ numTimesCalled = 0; } @Override public void onReceive(Context context,Intent intent) { numTimesCalled++; } public static int getNumTimesCalled() { return numTimesCalled; } public static void setNumTimesCalled(int numTimesCalled) { MockBroadcastReceiver.numTimesCalled = numTimesCalled; } }@H_403_2@这是单元测试. programReceiver方法实际上属于主项目中的一个类,但是我已经将它包含在测试中,所以你不需要读这么多代码.
public class ATest extends AndroidTestCase { MockBroadcastReceiver mockReceiver; @Override protected void setUp() throws Exception { mockReceiver = new MockBroadcastReceiver(); getContext().registerReceiver(mockReceiver,new IntentFilter()); } @Override protected void tearDown() { getContext().unregisterReceiver(mockReceiver); mockReceiver = null; } public void test(){ //We're going to program twice and check that only the last //programmed alarm should remain active. final Object flag = new Object(); MockBroadcastReceiver.setNumTimesCalled(0); new Thread (){ @Override public void run(){ programReceiver(getContext(),MockBroadcastReceiver.class,60000,60000); SystemClock.sleep(20000); programReceiver(getContext(),60000); SystemClock.sleep(90000); synchronized(flag){ flag.notifyAll(); } } }.start(); synchronized(flag){ try { flag.wait(); } catch (InterruptedException e) { } } assertEquals(1,MockBroadcastReceiver.getNumTimesCalled()); //should have been called at least once,but its 0. } private static void programReceiver(Context context,Class<? extends BroadcastReceiver> receiverClass,long initialDelay,long period){ Intent intent = new Intent(context,receiverClass); PendingIntent pendingIntent = PendingIntent.getBroadcast(context,intent,PendingIntent.FLAG_UPDATE_CURRENT); AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE); alarmManager.cancel(pendingIntent); //Cancel any prevIoUs alarm alarmManager.setInexactRepeating ( AlarmManager.RTC_WAKEUP,System.currentTimeMillis() + initialDelay,period,pendingIntent ); } }@H_403_2@当我执行测试方法时,接收器应该已经在setUp中动态注册.然后我编程相同的闹钟两次.我的意图是测试,只有最后一个警报仍然活跃,但我无法使接收器被呼叫.测试失败,因为它预计会被调用一次(或至少多次> = 1),但是模拟接收器中的计数器为0.我已经在onReceive方法中设置了一个断点,它永远不会击中.我还添加了日志记录,没有显示在logcat中.所以我100%肯定接收机没有被叫.我也尝试增加线程中的睡眠时间,因为setInexactRepeating非常不正确地触发,但是我可以等待年龄,但仍然没有被调用. @H_403_2@我也尝试在测试项目的清单中注册它,而不是以编程方式注册,结果是一样的. @H_403_2@为什么收件人不被叫? @H_403_2@UPDATE
我可以确认AlarmManager不是问题.报警根据adb dumpsys报警正确注册. @H_403_2@我现在试图通过调用sendBroadcast来让接收方运行,但是我处于死胡同.接收器不会被调用.我尝试了主应用程序上下文,测试用例上下文,甚至是ActivityInstrumentationTestCase2.试过还添加了WakeLocks和没有.没有办法得到它.我认为这可能是由于意图或意图过滤器中的一些标志引起的(android似乎真的很挑剔标志).
解决方法
在android源代码中有一个
alarmManagerTest,它使用broadcastreceiver执行alarmManager.setInexactRepeating.
@H_403_2@主要区别是工作的android测试延迟了15分钟,而您的测试使用了1分钟的延迟.
@H_403_2@AlarmManager的Android文档说:
interval之间的间隔间隔(以毫秒为单位).在API 19之前,如果这是INTERVAL_FIFTEEN_MINUTES之一,INTERVAL_HALF_HOUR,INTERVAL_HOUR,INTERVAL_HALF_DAY或INTERVAL_DAY,则报警将与其他报警相对齐,以减少唤醒次数.否则,报警将被设置为应用程序调用setRepeating(int,long,PendingIntent).从API 19开始,所有重复的报警将不准确,并与其他报警进行批处理,而不管其所述的重复间隔. @H_403_2@如果这意味着只允许15分钟的多边形,我并不舒服. @H_403_2@在我的Android 2.2手机上,不精确的定时器只有在15分钟内才能工作.
public void setInexactRepeating (int type,long triggerAtMillis,long intervalMillis,PendingIntent operation)@H_403_2@…
interval之间的间隔间隔(以毫秒为单位).在API 19之前,如果这是INTERVAL_FIFTEEN_MINUTES之一,INTERVAL_HALF_HOUR,INTERVAL_HOUR,INTERVAL_HALF_DAY或INTERVAL_DAY,则报警将与其他报警相对齐,以减少唤醒次数.否则,报警将被设置为应用程序调用setRepeating(int,long,PendingIntent).从API 19开始,所有重复的报警将不准确,并与其他报警进行批处理,而不管其所述的重复间隔. @H_403_2@如果这意味着只允许15分钟的多边形,我并不舒服. @H_403_2@在我的Android 2.2手机上,不精确的定时器只有在15分钟内才能工作.