Android定時關機問題解決

weixin_33890499發表於2016-08-13

昨天寫的簡易APP實現android定時關機,今天又倒騰了一天關於定時關機的,發現一些問題
1.設定定時關機迴圈時(設定每天為一個週期),當手機關機後,再開機,這個迴圈定時也就失效了,實際變成了單次定時關機
最後解決的方法是:再定義一個廣播接收器,用於接收系統開機時發出的廣播,當接收到廣播時,建立一個activity,在activity中根據之前儲存的資料重新設定定時,這樣就可以實現迴圈,下面詳解

2.按照上面的想法,還是遇到了問題,如果要使用迴圈,就必須靜態註冊接收開機廣播的廣播接收器。但是如果這樣的話,每次開機都會接收到廣播,並啟動新的activity,根據儲存的資料設定定時,即使點選了關閉定時或者取消迴圈,也消除不了,就是說這個廣播接收器總會執行,然後進行強制的定時。在網上搜尋到一個方法,說是使用PackageManager可以使在清單檔案靜態註冊的廣播變回到預設狀態(即未註冊狀態),但是好像不能再變為註冊狀態了,關於這個類,作者講的比較詳細

3.針對2的問題,開始想到的辦法是,在主activity中設定介面和一個以該介面的引用為引數的方法,然後在第二個廣播接收器中實現介面,再根據由介面中得到的資料判斷開機後是否需要設定定時,但是在該廣播接收器中實現activity中的方法實在麻煩。後來發現這方法顯得笨拙了啊

問題解決方法
新的廣播接收器中(就叫做BootBroadcastReceiver),直接啟動新activity(就叫做BootActivity),畢竟在迴圈時,BootActivity是需要讀取本地儲存的資料的,所以,直接根據讀取的資料進行判斷就好(儲存的資料中有一個boolean型別的表示是是否設定了迴圈,如果讀取的為false,那麼直接結束掉這個activity,反之執行),下面是這個activity中的程式碼,方法沒貼出,在GitHub有完整註釋的程式碼

try {            
getData(); //獲取上一次程式退出時儲存的資料            
getTime(); //將設定的時間轉換為alarmManager.set()方法中所需引數            
setAlarm(); //設定定時       
 } catch (Exception e) {           
 e.printStackTrace();        
}   
}    

小細節
為了方便使用,在新activity啟動時,不應該有介面出現,不然每次一開機就冒出來一個app介面豈不是很不爽,但是如果只是單純去掉activity中的setContentView的話,則會在開機時出現一個白屏,還好activity中有針對這個的解決辦法。在清單檔案中,activity標籤下新增一個屬性即可在啟動該activity時不產生介面
<activity android:name=".BootActivity" android:theme="@android:style/Theme.NoDisplay"></activity>

在將字串解析為整型的時候,把解析用的方法弄錯了(enter按的太快),結果總是問題,經過一番折騰才發現,用成了 Integer.getInteger,於是好奇這個看方法名像是轉換成整型的方法到底是幹嘛的,網上說的是

Integer.getInteger(String)的功能是根據指定的名稱得到系統屬性的整數值。第一個引數將被認為是系統屬性的名稱。系統屬性可以通過 System.getProperty(java.lang.String)方法訪問得到。屬性值字串將被解釋成一個整數,並且以表示這個值的Integer物件形式返回

內容就這些了,主要是對昨天的問題進行收尾,把程式碼都更新了一遍,如果需要的話,可以去下載看看,看註釋很容易懂,如果有錯誤,希望留言指出來哈

(新問題更新)

昨天小夥伴突然對我說,我的自動關機有重大bug,開機後馬上關機,再開機還是馬上關機,最後還是趁著開機到關機的一小會過渡時間解除安裝了app才得以解決,此問題一出,今天趕緊翻出來看看什麼情況。

出現的問題:
1.如果設定的時間到了,自動關機了,然後當天再次開機,於是就出現了這個情況。
2.開機後,會提示xx已停止執行(我記得當時自己用的時候是沒出現這個問題的,今天用模擬器發現有這個問題)
3.改正1、2後,成功關機、開機,但是出現了ANR

原因是這樣的:
1.AlarmManager在設定時間時,如果設定的時間小於當前時間嗎,則會立馬執行(當時大意了,沒注意到這個問題的影響),於是造就了開機後立馬關機的情況。但是如果是第二天在設定的時間點之前開機則不會出現立馬關機的情況
2.使用Theme.NoDispaly時,該Activity應該繼承自Activity而不是AppCompatActivity
3.開機後,APP會自啟並設定提醒,然後一直在後臺什麼都不做

解決:
1.在設定時間戳之前,新增一個判斷,判斷當前設定的時間是否小於當前時間,如果小於,則,將day加1,設定為第二天提醒
2.改繼承就OK
3.在自啟後執行設定提醒後,finish()即可
(更改的程式碼在GitHub中)

相關文章