如何检查AlarmManager是否已设置警报?


182

当我的应用程序启动时,我希望它检查是否已经设置并运行了特定的警报(通过AlarmManager注册)。谷歌的结果似乎表明,没有办法做到这一点。这是否正确?我需要做这个检查,以便在采取任何行动来创建新的警报之前通知用户。

  0

请验证解决您的问题的答案或张贴自己的解决方案。 16 1月. 172017-01-16 22:13:53

-3

你说的闹钟 - 这源,你可以从这里下载 - https://android.googlesource.com/platform/packages/apps/AlarmClock

或者你说话的设置时,必须执行特定任务的时间 - 的印象http://developer.android.com/reference/android/app/AlarmManager.html

  0

他们将其重命名为DeskClock:http://android.git.kernel.org/?p=platform/packages/apps/DeskClock.git;a=summary 29 12月. 102010-12-29 18:41:20

  0

我指的是使用AlarmManager在我的代码中设置的警报。我无法找到任何方法来检查是否已经为特定意图设置了警报。由于该程序允许用户设置闹钟,然后关闭应用程序,我想知道应用程序何时打开是否闹钟已设置并正在运行“视线之外”。 29 12月. 102010-12-29 19:41:19

  0

似乎AlarmManager类不提供这样的功能。这里可以看看AlarmManager的来源 - http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/2.1_r2/android/app/AlarmManager.java 如果你真的很绝望,你可以扩展它(或者重新实现IAlarmManager)并创建你自己的报警管理器。矫枉过正。 29 12月. 102010-12-29 20:18:28

  0

更新:我从另一个线程发现,以下似乎做的工作: - 30 12月. 102010-12-30 13:27:22

+6

alarm =(AlarmManager)getSystemService(Context.ALARM_SERVICE); \t String ALARM_ACTION; ALARM_ACTION = AAAlarmReceiver.ACTION_LOAD_LISTVIEW; Intent intentToFire = new Intent(ALARM_ACTION); boolean alarmUp =(PendingIntent.getBroadcast(cText,0,intentToFire,PendingIntent.FLAG_NO_CREATE)!= null); 30 12月. 102010-12-30 13:27:40

  0

请只回答你答案中的具体内容。如果你想问一个问题或其他任何问题,请将它保留在评论中。 01 12月. 172017-12-01 10:39:08

  0

@RahatZaman你在说什么?主要堆栈溢出理论之一是'给一个人一条鱼,你喂他一天。教一个人钓鱼,你一辈子喂他。所以,指出lib的来源在这里很常见。 05 12月. 172017-12-05 10:06:25


1

林说那里有没有办法做到这一点,但它会很好。

您可以通过在某处记录Alarm_last_set_time,并且有一个On_boot_starter BroadcastReciever:BOOT_COMPLETED有点类似的结果。


277

关注ron的评论,这里是详细的解决方案。比方说,你已经注册了一个悬而未决的意图这样的重复报警:

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"); 
} 

这里的关键是FLAG_NO_CREATE这如javadoc中所述:if the described PendingIntent **does not** already exists, then simply return null(而不是创建一个新的)

+8

是否必须仅使用Action字符串的Intent?我试着指定一个类,新的Intent(context,MyClass.class),但它似乎不工作。即使报警正在运行,它总是返回空值。 04 4月. 122012-04-04 08:39:49

+5

toc777,不需要它是一个字符串,它与您的清单中的意图过滤器中声明的操作相匹配。xml 11 4月. 122012-04-11 08:27:24

+4

克里斯,这是导致我的问题的另一个问题。我上面提到的意图确实有效:) 12 4月. 122012-04-12 12:25:50

  0

我遇到的一个问题是没有调用alarmManager和pendingIntent的cancel。 I.E〜alarmMgr.cancel(alarmIntent); alarmIntent.cancel(); 29 5月. 142014-05-29 12:01:21

  0

@ChrisKnight:如果我从应用程序中检查app1是否设置了闹钟并在app2中运行,这仍然有效吗?而且,在应用更新期间,报警会死机,那么我们需要重新设置一次(对于应用更新情况)? 08 7月. 142014-07-08 03:25:46

+1

总是返回TRUE,说明挂起的意图已经存在。即使在应用程序卸载并重新安装之后。挂起的意图活多久? 13 8月. 142014-08-13 20:33:24

+30

请注意,您需要同时调用''alarmManager.cancel(pendingIntent)''和'''pendingIntent.cancel()'''以便此解决方案返回false。 29 9月. 142014-09-29 20:00:44

+1

对于使用新Intent(context,YourService.class)的用户,您可以使用.setAction(“ACTIONNAME”)来定义一个动作,意图为 28 11月. 142014-11-28 20:11:13

+1

Lifesaver。请注意,除了标志之外,您需要完全按照您之前创建的方式创建意图。 26 2月. 152015-02-26 10:07:31

+22

这种情况并不明显,此答案中的代码未验证挂起的意图是否已在警报管理器中注册。代码只是验证PendingIntent是通过getBroadcast创建的,具有等效的目标意图。您可以在getBroadcast之后运行alarmUp代码,但在所有日历和闹钟管理器之前运行。它会返回true。这个事实解释了为什么你必须PendingIntent.cancel才能让值回到false。严格地说,这并不回答这个问题。 21 4月. 152015-04-21 21:09:49

+1

不好意思。我想问什么是MY_UNIQUE_ACTION?它来自哪里? 23 7月. 152015-07-23 01:14:26

+1

@LeonardFebrianto我认为这是一个早该回答的问题,但我确信你有理由。这只是行动的名称,它可以是任何行动常数,你有与清单 15 12月. 152015-12-15 05:49:51

  0

接收器相关联的行为不起作用,如果报警被'强行停止'等死亡。它必须被取消之前使用此代码 17 12月. 152015-12-17 13:55:17

+1

我试过意图意图=新意图(ctx,MyReceiver.class);而不是通过unique_action,它的工作:) 22 12月. 152015-12-22 11:24:16

  0

哦,其工作的感谢! 23 12月. 152015-12-23 03:46:33

+1

针对未来读者的提示 - 确保您不会错误地将PendingIntent.getBroadcast(...)与PendingIntent.getService(...)混为一谈 - 省去一些麻烦! :) 18 4月. 162016-04-18 04:33:00

+2

这是我第一次看到如此高评价错误的答案。请参阅bigh_29的评论。 03 1月. 172017-01-03 20:29:37


7

我有2个闹钟。我使用的意图与群众演员,而不是动作识别的事件:

Intent i = new Intent(context, AppReciever.class); 
i.putExtra("timer", "timer1"); 

的事情是,与DIFF额外的意图(和报警)不会是唯一的。因此,要能够识别哪些报警被激活与否,我必须定义DIFF requestCode -s:

boolean alarmUp = (PendingIntent.getBroadcast(context, MyApp.TIMER_1, i, 
        PendingIntent.FLAG_NO_CREATE) != null); 

,这里是报警是如何被创造:

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); 
  0

使用意图额外和这个解决方案为我工作。只有一个变化是我正在使用服务,所以我已经将其更改为'PendingIntent.getService' 27 8月. 162016-08-27 10:07:25


92

对于其他人谁可能需要这个,这是一个答案。

使用adb shell dumpsys alarm

可以知道报警已定,是时,他们会感到震惊和间隔。此警报已被调用多少次。

+4

这应该是正确的答案 04 10月. 142014-10-04 22:07:13

+1

这正是 09 12月. 142014-12-09 12:43:14

+24

不是OP的程序化答案,而是一个很酷的提示。非常好知道。 06 5月. 152015-05-06 17:38:12

+1

附加一个grep来过滤通常很长的警报列表:'adb shell dumpsys alarm | grep <例如。 '也适用于新的Windows系统(我使用Win10) 08 8月. 162016-08-08 10:51:30

+2

grep在移动设备上执行,而不是在PC上执行。所以如果grep的工作取决于Android操作系统。旧的手机不带有grep。 07 3月. 172017-03-07 13:15:26


36

接收器的工作示例(最佳答案只是采取行动)。

//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..."); 

我还介绍了我的​​

+1

我不确定这是否足够。在向AlarmManager注册PendingIntent然后由两种取消方法停止的情况下,上面的“isWorking”仍然是真实的。 PendingIntent似乎还没有从AlarmManager中删除,并且将继续返回一个实例。那么我们如何有效地知道何时打开/关闭警报? 10 6月. 162016-06-10 07:36:29

  0

这实际上工作完美。需要注意的是:setAction()和requestCode()在所有getBroadcast()中都必须相同,并且它的价值在于从设备上卸载应用程序。这让我失望了。谢谢 11 6月. 162016-06-11 10:12:42

  0

很好。谢谢! 01 9月. 162016-09-01 12:59:48

  0

不错的例子,但我不会在那里使用1001作为私人请求代码。只是为了让这个例子更加明显。 09 7月. 172017-07-09 08:12:57


29

注意这句话从文档的告警管理:

如果已经有这个意向预定的报警(与 两个意图的相等由Intent.filterEquals定义),那么它将被删除并被这个替换掉。

如果您试图决定是否创建闹钟,请不要打扰询问闹钟是否存在。每次启动应用程序时都要创建它。您将替换您配置的任何过去的警报。

如果您试图计算在先前创建的闹钟上剩余多少时间,或者您确实需要知道这种闹钟是否存在,则您需要采用不同的方法。要回答这些问题,请考虑在创建警报时保存共享的pref数据。您可以在设置闹钟,预计闹钟关闭的时间以及重复周期(如果您设置重复闹钟)时存储时钟时间戳。

  0

在我看来这应该是被接受的答案。除非OP有特殊情况证明不需要重新报警 19 5月. 162016-05-19 16:11:12

  0

在我的情况下,我想知道是否已经设置了报警,如果是这样,我不想创建新报警或重置现有报警。 21 7月. 172017-07-21 14:00:12


3

我做了一个简单的(笨或不)bash脚本,它从adb外壳中提取多条线,将它们转换为时间戳并以红色显示。

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;) 

试试吧;)


2
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不创建挂起的意图,这样它给布尔值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的值后,它给出true,因为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"); 

      } 

5

刚刚找到另一种解决方案,它似乎为我工作

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); 
    } 
  0

有时,在棉花糖上强制停止应用程序后,getBroadcast()将返回非null值,但未设置警报。 15 2月. 182018-02-15 20:14:10