当我的应用程序启动时,我想让它检查一个特定的警报(通过AlarmManager注册)是否已经设置并运行。谷歌的结果似乎表明没有办法做到这一点。这仍然正确吗?我需要做这个检查,以便在采取任何行动创建一个新的警报之前建议用户。
当前回答
根据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");
}
关键是在javadoc中描述的FLAG_NO_CREATE:如果所描述的PendingIntent **不**已经存在,那么简单地返回null(而不是创建一个新的)
其他回答
虽然这里几乎每个人都给出了正确答案,但没有人解释警报的工作依据是什么
你可以在这里了解更多关于AlarmManager及其工作的信息。但这里有一个简单的答案
你可以看到AlarmManager基本上在未来的某个时间安排一个PendingIntent。所以为了取消预定的Alarm,你需要取消PendingIntent。
在创建PendingIntent时,总是要注意两件事
PendingIntent.getBroadcast(context,REQUEST_CODE,intent, PendingIntent.FLAG_UPDATE_CURRENT);
请求代码——作为唯一标识符 Flag -定义PendingIntent的行为
现在要检查警报是否已经被安排或取消警报,你只需要访问相同的PendingIntent。如果您使用相同的请求代码并使用如下所示的FLAG_NO_CREATE,就可以做到这一点
PendingIntent pendingIntent=PendingIntent.getBroadcast(this,REQUEST_CODE,intent,PendingIntent.FLAG_NO_CREATE);
if (pendingIntent!=null)
alarmManager.cancel(pendingIntent);
使用FLAG_NO_CREATE,如果PendingIntent不存在,它将返回null。如果它已经存在,则返回对现有的PendingIntent的引用
对于其他可能需要这个的人,这里有一个答案。
使用adb shell dumpsys警报
你可以知道闹铃已经设置好了,什么时候闹铃和间隔时间。还有这个警报被触发的次数。
刚找到另一个解决办法,似乎对我有用
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);
}
我用android jetpack workManager做了一个变通。
与其直接在alarmManager中设置警报,不如在workManager中设置work,在那里您可以设置触发时间(在workManager中设置触发时间),并为该work添加一个标签。当工作触发时,可设置并触发报警。
为了回答您的问题,您只需通过.addTag("something")向作品添加标签,然后在检查活动作品时使用.getWorkInfosByTag("something")
我有两个闹钟。我使用带有额外内容的意图而不是行动来识别事件:
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);
下面是如何创建警报的:
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);
推荐文章
- 碎片中的onCreateOptionsMenu
- TextView粗体通过XML文件?
- 如何使线性布局的孩子之间的空间?
- DSL元素android.dataBinding。enabled'已过时,已被'android.buildFeatures.dataBinding'取代
- ConstraintLayout:以编程方式更改约束
- PANIC: AVD系统路径损坏。检查ANDROID_SDK_ROOT值
- 如何生成字符串类型的buildConfigField
- Recyclerview不调用onCreateViewHolder
- Android API 21工具栏填充
- Android L中不支持操作栏导航模式
- 如何在TextView中添加一个子弹符号?
- PreferenceManager getDefaultSharedPreferences在Android Q中已弃用
- 在Android Studio中创建aar文件
- 修改抽射超时时间
- 如何通过数据从第二个活动到第一个活动时按回?——安卓