Android平台预置GMS包后关机闹钟失效问题及解决方法

作者:是何先森啊 时间:2022-12-31 05:52:33 

1.介绍

关机闹钟为Android中默认支持的功能,实现起来则需要满足一定的条件:自动开机、开机后响铃。对于自动开机来说,自动关机可以在应用层通过设置alarm来实现,而自动开机需要底层rtc时钟的支持;开机后检查时间,到点响铃。

2.原理

一般智能手机的硬件架构都是分为RF,BB,AP这三个部分, RF射频部分的功能主要是接收和发射射频,大家不用关注这个。而AP部分就是应用程序处理器,其实也就是CPU模块;BB部分则是基带模块。通常手机关机都是AP模块完全断电,而BB虽然处在关机状态,但实际上闹钟和时间部分并没有断电。而当所设置闹钟到点时BB模块会自动给AP模块上电,这样系统也就能开机并激活闹钟功能了。

3.流程

在闹钟设置一个时间合适且有效响铃的闹钟后,向PowerOffAlarm发送设定关机闹钟广播并传入闹钟时间参数,PowerOffAlarm接收到广播后,根据预设提前开机时间和闹钟时间往rtc中写入时间,并将该时间写入文件中暂存。
设置好闹钟后关机,机器会根据rtc中的alrm_time时间参数来开机,开机后AlarmManagerService会检查闹钟,并在闹钟时间发送广播后弹出响铃界面。
点击关闭闹钟后,会发送取消关机闹钟广播,PowerOffAlarm会对传入时间与暂存的时间对比,如果相同则会取消该关机闹钟。

4.遇到问题及解决方法

4.1预置GMS包后,关机闹钟失效

在对比平台闹钟分析后,发现谷歌闹钟在设置闹钟后并没有向PowerOffAlarm发送广播,但是由于谷歌闹钟无法进行修改。
在分析了平台的闹钟设置闹钟步骤后,发现在设置闹钟后都会调用AlarmManager.setAlarmClock()这个方法,然后再AlarmStateManager的updateNextAlarm方法中发送设置关机闹钟的广播。
谷歌闹钟在设置闹钟也会调用AlarmManager.setAlarmClock()这个方法,所以在该方法中直接发送广播到PowerOffAlarm中。


@@ -615,8 +633,34 @@ public class AlarmManager {
 public void setAlarmClock(AlarmClockInfo info, PendingIntent operation) {
  setImpl(RTC_WAKEUP, info.getTriggerTime(), WINDOW_EXACT, 0, 0, operation,
    null, null, null, null, info);
+  setPowerOffAlarm(mContext,info.getTriggerTime());
 }

+
+ /*add by hxj at Aug.6,for PowerOffAlarm*/
+ private void setPowerOffAlarm(Context context, long time) {
+  Log.d(TAG, "setPowerOffAlarm: saveAlarmToPreference and sendBroadcast to setPowerOffAlarm,the time is "+time);
+  DEFAULT_ALARM_TIME = time;
+  Intent intent = new Intent(ACTION_SET_POWEROFF_ALARM);
+  intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
+  intent.setPackage(POWER_OFF_ALARM_PACKAGE);
+  intent.putExtra(TIME, time);
+  context.sendBroadcast(intent);
+ }
+
+ private void cancelPowerOffAlarm(Context context) {
+  //long time = getAlarmFromPreference(context);
+  Log.d(TAG, "cancelPowerOffAlarm: cancel alarm and cancelPowerOffAlarm(mContext),time is "+DEFAULT_ALARM_TIME );
+  Intent intent = new Intent(ACTION_CANCEL_POWEROFF_ALARM);
+  intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
+  intent.putExtra(TIME, DEFAULT_ALARM_TIME);
+  intent.setPackage(POWER_OFF_ALARM_PACKAGE);
+  context.sendBroadcast(intent);
+  DEFAULT_ALARM_TIME = 0L;
+ }
+
+
 /** @hide */
 @SystemApi
 @RequiresPermission(android.Manifest.permission.UPDATE_DEVICE_STATS)
@@ -930,6 +974,7 @@ public class AlarmManager {

try {
   mService.remove(operation, null);
+   cancelPowerOffAlarm(mContext);
  } catch (RemoteException ex) {
   throw ex.rethrowFromSystemServer();
  }

4.2 PowerOffAlarm无法接收广播

在分析log后,发现接受该广播需要在应用中添加特定的权限,即"org.codeaurora.permission.POWER_OFF_ALARM"权限,但是由于谷歌闹钟中未添加并且无法修改,所以在PowerOffAlarm中接收管广播处移除该权限。


@@ -29,7 +29,7 @@
  android:defaultToDeviceProtectedStorage="true">

<receiver android:name=".PowerOffAlarmBroadcastReceiver"
-   android:permission="org.codeaurora.permission.POWER_OFF_ALARM"
+
   android:exported="true"
   android:directBootAware="true"
   android:label="PowerOffAlarmBroadcastReceiver">

4.3 开机时间过长导致开机后闹钟过期

提前开机时间平台预设默认为90000毫秒,项目中开机时间较长,所以增长开机时间,改为150000毫秒。


@@ -42,7 +42,7 @@ public class PowerOffAlarmUtils {

private static final int FAILURE = -1;

- public static final long MS_IN_ONE_MIN = 90000L;
+ public static final long MS_IN_ONE_MIN = 150000L;

private static final long SEC_TO_MS = 1000L;

此外还有其他的问题也会导致关机闹钟的失效,有时间再来记录一下。

来源:https://blog.csdn.net/weixin_42731568/article/details/108452801

标签:android,GMS包,闹钟
0
投稿

猜你喜欢

  • Android桌面插件App Widget用法分析

    2022-02-05 02:26:39
  • native.js获取手机硬件基本信息实例代码android版

    2023-10-19 13:33:09
  • SpringBoot整合EasyExcel实现文件导入导出

    2021-11-07 17:14:51
  • SpringBoot中如何对actuator进行关闭

    2022-11-30 01:56:37
  • SpringBoot整合logback的示例代码

    2023-08-13 02:32:08
  • Android Studio中使用jni进行opencv开发的环境配置方法

    2021-07-26 00:02:06
  • 安卓(Android)实现选择时间功能

    2023-11-05 08:20:58
  • C# 7.2中结构体性能问题的解决方案

    2022-08-12 23:04:26
  • 详解java注解相关知识

    2022-09-22 12:32:52
  • Android4.4开发之电池低电量告警提示原理与实现方法分析

    2022-06-17 19:52:39
  • Android使用SharedPreferences存储数据的实现方法

    2021-08-22 02:05:49
  • java 文件流的处理方式 文件打包成zip

    2022-07-08 12:43:03
  • Android通用LoadingView加载框架详解

    2021-12-01 10:43:24
  • Java中try catch处理异常示例

    2023-11-07 00:43:17
  • Java静态代理与动态代理案例详解

    2021-12-09 19:55:44
  • Java中两个字符串进行大小比较的方法

    2023-10-12 13:39:26
  • WinForm绘制圆角的方法

    2023-06-21 14:23:51
  • android 添加随意拖动的桌面悬浮窗口

    2023-12-27 15:57:17
  • RecyclerView实现拖拽排序效果

    2022-09-14 01:23:40
  • Android仿iOS侧滑退出当前界面功能

    2022-07-01 10:08:37
  • asp之家 软件编程 m.aspxhome.com