检测默认闹钟应用程序的闹钟

10

我想知道是否有一种方式(可能是系统广播),可以知道闹钟默认应用程序现在开始响铃。

如果没有的话 - 如果我能以编程方式获取用户设置的所有活动警报列表(我可以从每个警报中提取它将响铃的确切时间..),我也会感到满意。

到目前为止我尝试过的:

我知道有一种方法可以获取格式化的下一个闹钟字符串:

  String nextAlarm = Settings.System.getString(context.getContentResolver(), Settings.System.NEXT_ALARM_FORMATTED);

这种方法对某些设备(如所有三星Galaxy系列...)返回一个空字符串,即使闹钟已经被设置(通过三星原生的闹钟应用程序...)。我猜它只能在默认闹钟应用程序下的Nexus设备上工作。

我想得到一个通用的解决方案,无论哪种情况都能起作用。

TIA

更新

我将尝试让我的问题更清晰:

我不直接关心AlarmManager持有的所有PendingIntent

我只关心用户隐式设置的闹钟,特别是他为了唤醒而激活的闹钟。

我的最终目标是获取提示用户正在醒来。 就是这样。

5个回答

5

嗨,看起来我来晚了,但无论如何,这是我能够找到的内容。

1.) 一个系统广播,用于知道闹钟默认应用程序现在开始响铃。

我从我的Note3中检查了ADB日志,每当默认闹钟响铃时,我都可以看到这个日志:"I/SecExternalDisplayIntents_Java(2797): Intent Recieved .. - com.samsung.sec.android.clockpackage.alarm.ALARM_STARTED_IN_ALERT BroadCast Map value - 7"

我成功地使用动作名称“com.samsung.sec.android.clockpackage.alarm.ALARM_STARTED_IN_ALERT”捕获了意图。尽管我非常怀疑这个意图是否可用于所有Android设备。

意图操作的包名给了我进一步的提示,我找到了答案:

2.) 如果我能够以编程方式获取用户设置的所有活动警报列表,那么我也会满意。

看起来时钟包在 “com.samsung.sec.android.clockpackage/alarm” 的位置公开了Content provider,我可以从该DB中查询用户设置的所有警报(启用/禁用/名称/贪睡等)。通过切换启用/禁用按钮,我发现闹钟打开/关闭的值在第1列(列从0索引开始)。如果您需要更多数据,我建议拉取数据库并在SQLlite数据库浏览器中查看表结构(设备可能需要被root才能完整地拉取数据库)。

其他Android设备上也必须存在类似的数据库(我破坏了我的Nexus否则也可以在那上测试),祝愉快!


谢谢你的回答,我已经为你的努力点赞了。但是正如你自己所写的那样,这种策略需要针对每个手机厂商进行不同的处理(至少)。我正在寻找官方的 Android 解决方案,它应该是通用的。看起来并没有这样的解决方案。 - Tal Kanel
谢谢。我非常怀疑能够找到一种通用的解决方案。对于大多数三星设备(JBP),DB URI查询方法将起作用,因为应用程序公开了ACP,我相信这样做是为了让其他应用程序可以使用此信息。同样基于URI的DB查询也适用于S3和Note 3。只需检查Nexus / HTC设备的类似默认包名称,它可能会奏效 :) - amIT

2

1

我非常怀疑你能找到这个问题的解决方案。

闹钟由AlarmManagerService维护。由于它未包含在SDK中,反射可能是唯一的获取信息的方式。但从外观上看,即使反射也无法帮助你:

  • 需要访问AlarmManagerService $ Batch#alarms <--- ArrayList< Alarm >
  • 需要访问AlarmManagerService#mAlarmBatches#< ArrayList<Batch>
  • 使用反射:
    • Class<?> ams = Class.forName(“com.android.server.AlarmManagerService”)
    • Field mAlarmBatches = ams.getDeclaredField(“mAlarmBatches”)
    • mAlarmBatches.get(????)的对象listOfBatches
    • 卡住了

对我来说似乎是死路一条。您无法实例化AlarmManagerService - 即使通过访问和调用其构造函数(因为它调用本机方法)。

另一种推理方式:这是AlarmManagerService $ Alarm类的外观:

public static class Alarm {
    public int type;
    public int count;
    public long when;
    public long windowLength;
    public long whenElapsed;    // 'when' in the elapsed time base
    public long maxWhen;        // also in the elapsed time base
    public long repeatInterval;
    public PendingIntent operation;  <<<<<<============Problem==============
    public WorkSource workSource;

    ....
    ....
}

如果一个人可以访问PendingIntent,那么有什么阻止他们随意取消由其他应用程序设置的闹钟呢?
不过,我希望这里的某个人能够帮助你。
链接:AlarmManagerService

谢谢你的回答,你可能是对的。我已经给你点赞了,但我还没有接受它,因为也许还有人能告诉我们一些新的东西,我们之前没有想到过的。 - Tal Kanel
@TalKanel 感谢您的点赞。我同意我们应该等待更积极的答案。 - Vikram

1

你不能查询AlarmManager的命令列表,这是实现此目的所需的。

找到闹钟列表的最接近方法是使用dumpsys adb shell dumpsys alarm,但显然你无法在代码中执行该操作。


1
如果我理解正确,您想检查哪些应用程序使用Alarm Manager类。如果是这样,您可以通过允许您的应用程序监视日志记录来实现,一旦完成,您肯定会知道哪些应用程序正在使用闹钟。至少在启动时应该起作用。您可以创建一个新线程在后台运行logcat(不使用-d选项)。还要确保在清单中添加所需的权限才能使其正常工作。

启动时间的屏幕截图:

enter image description here

更新:在使用默认系统时钟设置9:56pm闹钟后的LogCat

在通过原始问题的更新了解OP的要求后,我尝试设置特定时间的闹钟,并检查LogCat是否有相同时间的日志记录。以下是按时间顺序记录的详细信息和事件:

enter image description here

这也可能是有趣的


谢谢你的回答。我已经为它点了赞,但是老实说,我不确定持续嗅探logcat消息是否是一个好主意。我的进程会一直保持运行状态,并消耗大量资源,这最终会导致电池快速耗尽..即使我忽略这个问题-仍然存在一些问题:com.android.desklock在非原生Android固件的手机上不存在,所以它不适用于这种情况。 - Tal Kanel
1
你的问题引起了好奇心,也许我们可以使用广播来替代处理程序进行嗅探,如果我找到任何相关或有价值的细节,我将在此发布。谢谢 :) - Skynet
2
你不能再嗅探其他应用程序的日志记录了。 - Simon

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接