溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶(hù)服務(wù)條款》

Android平臺(tái)預(yù)置GMS包后關(guān)機(jī)鬧鐘失效問(wèn)題及解決方法

發(fā)布時(shí)間:2020-10-06 07:52:51 來(lái)源:腳本之家 閱讀:263 作者:是何先森啊 欄目:開(kāi)發(fā)技術(shù)

1.介紹

關(guān)機(jī)鬧鐘為Android中默認(rèn)支持的功能,實(shí)現(xiàn)起來(lái)則需要滿(mǎn)足一定的條件:自動(dòng)開(kāi)機(jī)、開(kāi)機(jī)后響鈴。對(duì)于自動(dòng)開(kāi)機(jī)來(lái)說(shuō),自動(dòng)關(guān)機(jī)可以在應(yīng)用層通過(guò)設(shè)置alarm來(lái)實(shí)現(xiàn),而自動(dòng)開(kāi)機(jī)需要底層rtc時(shí)鐘的支持;開(kāi)機(jī)后檢查時(shí)間,到點(diǎn)響鈴。

2.原理

一般智能手機(jī)的硬件架構(gòu)都是分為RF,BB,AP這三個(gè)部分, RF射頻部分的功能主要是接收和發(fā)射射頻,大家不用關(guān)注這個(gè)。而AP部分就是應(yīng)用程序處理器,其實(shí)也就是CPU模塊;BB部分則是基帶模塊。通常手機(jī)關(guān)機(jī)都是AP模塊完全斷電,而B(niǎo)B雖然處在關(guān)機(jī)狀態(tài),但實(shí)際上鬧鐘和時(shí)間部分并沒(méi)有斷電。而當(dāng)所設(shè)置鬧鐘到點(diǎn)時(shí)BB模塊會(huì)自動(dòng)給AP模塊上電,這樣系統(tǒng)也就能開(kāi)機(jī)并激活鬧鐘功能了。

3.流程

在鬧鐘設(shè)置一個(gè)時(shí)間合適且有效響鈴的鬧鐘后,向PowerOffAlarm發(fā)送設(shè)定關(guān)機(jī)鬧鐘廣播并傳入鬧鐘時(shí)間參數(shù),PowerOffAlarm接收到廣播后,根據(jù)預(yù)設(shè)提前開(kāi)機(jī)時(shí)間和鬧鐘時(shí)間往rtc中寫(xiě)入時(shí)間,并將該時(shí)間寫(xiě)入文件中暫存。
設(shè)置好鬧鐘后關(guān)機(jī),機(jī)器會(huì)根據(jù)rtc中的alrm_time時(shí)間參數(shù)來(lái)開(kāi)機(jī),開(kāi)機(jī)后AlarmManagerService會(huì)檢查鬧鐘,并在鬧鐘時(shí)間發(fā)送廣播后彈出響鈴界面。
點(diǎn)擊關(guān)閉鬧鐘后,會(huì)發(fā)送取消關(guān)機(jī)鬧鐘廣播,PowerOffAlarm會(huì)對(duì)傳入時(shí)間與暫存的時(shí)間對(duì)比,如果相同則會(huì)取消該關(guān)機(jī)鬧鐘。

4.遇到問(wèn)題及解決方法

4.1預(yù)置GMS包后,關(guān)機(jī)鬧鐘失效

在對(duì)比平臺(tái)鬧鐘分析后,發(fā)現(xiàn)谷歌鬧鐘在設(shè)置鬧鐘后并沒(méi)有向PowerOffAlarm發(fā)送廣播,但是由于谷歌鬧鐘無(wú)法進(jìn)行修改。
在分析了平臺(tái)的鬧鐘設(shè)置鬧鐘步驟后,發(fā)現(xiàn)在設(shè)置鬧鐘后都會(huì)調(diào)用AlarmManager.setAlarmClock()這個(gè)方法,然后再AlarmStateManager的updateNextAlarm方法中發(fā)送設(shè)置關(guān)機(jī)鬧鐘的廣播。
谷歌鬧鐘在設(shè)置鬧鐘也會(huì)調(diào)用AlarmManager.setAlarmClock()這個(gè)方法,所以在該方法中直接發(fā)送廣播到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無(wú)法接收廣播

在分析log后,發(fā)現(xiàn)接受該廣播需要在應(yīng)用中添加特定的權(quán)限,即"org.codeaurora.permission.POWER_OFF_ALARM"權(quán)限,但是由于谷歌鬧鐘中未添加并且無(wú)法修改,所以在PowerOffAlarm中接收管廣播處移除該權(quán)限。

@@ -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 開(kāi)機(jī)時(shí)間過(guò)長(zhǎng)導(dǎo)致開(kāi)機(jī)后鬧鐘過(guò)期

提前開(kāi)機(jī)時(shí)間平臺(tái)預(yù)設(shè)默認(rèn)為90000毫秒,項(xiàng)目中開(kāi)機(jī)時(shí)間較長(zhǎng),所以增長(zhǎng)開(kāi)機(jī)時(shí)間,改為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;

此外還有其他的問(wèn)題也會(huì)導(dǎo)致關(guān)機(jī)鬧鐘的失效,有時(shí)間再來(lái)記錄一下。

總結(jié)

到此這篇關(guān)于Android平臺(tái)預(yù)置GMS包后,關(guān)機(jī)鬧鐘失效的文章就介紹到這了,更多相關(guān)android 預(yù)置GMS包關(guān)機(jī)鬧鐘失效內(nèi)容請(qǐng)搜索億速云以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持億速云!

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI