如何检查AlarmManager是否已经设置了闹钟?
当我的应用程序启动时,我想要检查一个特定的报警(通过AlarmManager注册)是否已经设置并正在运行。 谷歌的结果似乎表明,没有办法做到这一点。 这是否正确? 我需要做这个检查,以便在采取任何行动来创build一个新的警报之前build议用户。
关于ron的评论,这里是详细的解决scheme。 比方说,你已经注册了一个重复的警报,像这样一个挂起的意图:
Intent intent = new Intent("com.my.package.MY_UNIQUE_ACTION"); PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT); Calendar calendar = Calendar.getInstance(); calendar.setTimeInMillis(System.currentTimeMillis()); calendar.add(Calendar.MINUTE, 1); AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE); alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), 1000 * 60, pendingIntent);
你要检查它是否有效的方法是:
boolean alarmUp = (PendingIntent.getBroadcast(context, 0, new Intent("com.my.package.MY_UNIQUE_ACTION"), PendingIntent.FLAG_NO_CREATE) != null); if (alarmUp) { Log.d("myTag", "Alarm is already active"); }
这里的关键是在javadoc中描述的FLAG_NO_CREATE
: if the described PendingIntent **does not** already exists, then simply return null
(而不是创build一个新的)
对于其他可能需要的人来说,这是一个答案。
使用adb shell dumpsys alarm
你可以知道报警已经设定,什么时候报警和间隔。 还有多less次这个警报已被调用。
与接收者一起工作的例子(最好的答案只是采取行动)。
//starting AlarmManager alarmManager = (AlarmManager) getActivity().getSystemService(Context.ALARM_SERVICE); Intent intent = new Intent(getActivity(), MyReceiver.class); intent.setAction(MyReceiver.ACTION_ALARM_RECEIVER);//my custom string action name PendingIntent pendingIntent = PendingIntent.getBroadcast(getActivity(), 1001, intent, PendingIntent.FLAG_CANCEL_CURRENT);//used unique ID as 1001 alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(), aroundInterval, pendingIntent);//first start will start asap //and stopping Intent intent = new Intent(getActivity(), MyReceiver.class);//the same as up intent.setAction(MyReceiver.ACTION_ALARM_RECEIVER);//the same as up PendingIntent pendingIntent = PendingIntent.getBroadcast(getActivity(), 1001, intent, PendingIntent.FLAG_CANCEL_CURRENT);//the same as up alarmManager.cancel(pendingIntent);//important pendingIntent.cancel();//important //checking if alram is working with pendingIntent Intent intent = new Intent(getActivity(), MyReceiver.class);//the same as up intent.setAction(MyReceiver.ACTION_ALARM_RECEIVER);//the same as up boolean isWorking = (PendingIntent.getBroadcast(getActivity(), 1001, intent, PendingIntent.FLAG_NO_CREATE) != null);//just changed the flag Log.d(TAG, "alarm is " + (isWorking ? "" : "not") + " working...");
我也在我的博客上描述过
请注意报警pipe理器文档中的这个引用:
如果这个Intent已经有了一个警报(Intent.filterEquals定义了两个intent的等号),那么它将被移除,并被这个警报取代。
如果您试图决定是否创build闹钟,请不要打扰询问闹钟是否存在。 每次你的应用程序启动时创build它。 您将replace您configuration的任何过去的警报。
如果您正在计算之前创build的闹钟中剩余多less时间,或者您确实需要知道这种闹钟是否存在,则需要使用其他方法。 要回答这些问题,请考虑在创build警报时保存共享的前期数据。 您可以在闹钟设置的时刻,闹钟响起的时间以及重复周期(如果您设置重复闹钟)存储时钟时间戳。
我有2个闹钟。 我正在使用intent与extras而不是action来识别事件:
Intent i = new Intent(context, AppReciever.class); i.putExtra("timer", "timer1");
事情是与差额外的意图(和警报)不会是唯一的。 所以为了能够识别哪个报警是活动的,我不得不定义diff requestCode
-s:
boolean alarmUp = (PendingIntent.getBroadcast(context, MyApp.TIMER_1, i, PendingIntent.FLAG_NO_CREATE) != null);
这里是如何创build警报:
public static final int TIMER_1 = 1; public static final int TIMER_2 = 2; PendingIntent pending = PendingIntent.getBroadcast(context, TIMER_1, i, PendingIntent.FLAG_CANCEL_CURRENT); setInexactRepeating(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), AlarmManager.INTERVAL_DAY, pending); pending = PendingIntent.getBroadcast(context, TIMER_2, i, PendingIntent.FLAG_CANCEL_CURRENT); setInexactRepeating(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), AlarmManager.INTERVAL_DAY, pending);
刚发现另一个解决scheme,它似乎为我工作
Intent myIntent = new Intent(MainActivity.this, MyReceiver.class); boolean isWorking = (PendingIntent.getBroadcast(MainActivity.this, 0, myIntent, PendingIntent.FLAG_NO_CREATE) != null); if (isWorking) {Log.d("alarm", "is working");} else {Log.d("alarm", "is not working");} if(!isWorking) { pendingIntent = PendingIntent.getBroadcast(MainActivity.this, 0, myIntent, PendingIntent.FLAG_UPDATE_CURRENT); alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE); int timeNotif = 5 * 60 * 1000;//time in ms, 7*24*60*60*1000 for 1 week Log.d("Notif", "Notification every (ms): " + timeNotif); alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), timeNotif, pendingIntent); }
我做了一个简单的(笨或不)bash脚本,从adbshell中提取多个,将它们转换为时间戳并以红色显示。
echo "Please set a search filter" read search adb shell dumpsys alarm | grep $search | (while read i; do echo $i; _DT=$(echo $i | grep -Eo 'when\s+([0-9]{10})' | tr -d '[[:alpha:][:space:]]'); if [ $_DT ]; then echo -e "\e[31m$(date -d @$_DT)\e[0m"; fi; done;)
尝试一下 ;)
Intent intent = new Intent("com.my.package.MY_UNIQUE_ACTION"); PendingIntent pendingIntent = PendingIntent.getBroadcast( sqlitewraper.context, 0, intent, PendingIntent.FLAG_NO_CREATE);
FLAG_NO_CREATE不是创build挂起的意图,所以它给布尔值false。
boolean alarmUp = (PendingIntent.getBroadcast(sqlitewraper.context, 0, new Intent("com.my.package.MY_UNIQUE_ACTION"), PendingIntent.FLAG_NO_CREATE) != null); if (alarmUp) { System.out.print("k"); } AlarmManager alarmManager = (AlarmManager) sqlitewraper.context .getSystemService(Context.ALARM_SERVICE); alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(), 1000 * 60, pendingIntent);
在AlarmManager检查Pending Intent的值后,它会给出正确的结果,因为AlarmManager更新了待定意向标志。
boolean alarmUp1 = (PendingIntent.getBroadcast(sqlitewraper.context, 0, new Intent("com.my.package.MY_UNIQUE_ACTION"), PendingIntent.FLAG_UPDATE_CURRENT) != null); if (alarmUp1) { System.out.print("k"); }
我以为没有办法做到这一点的印象,这将是很好,但。
你可以通过在某处logging一个Alarm_last_set_time,并且有一个On_boot_starter BroadcastReciever:BOOT_COMPLETED有点类似的结果。
你是否正在说闹钟 – 你可以从这里下载哪个源代码 – https://android.googlesource.com/platform/packages/apps/AlarmClock
或者你说的时间给定的任务必须执行 – http://developer.android.com/reference/android/app/AlarmManager.html