昨天寫的簡易APP實現(xiàn)android定時關(guān)機,今天又倒騰了一天關(guān)于定時關(guān)機的,發(fā)現(xiàn)一些問題
1.設(shè)置定時關(guān)機循環(huán)時(設(shè)定每天為一個周期),當(dāng)手機關(guān)機后,再開機,這個循環(huán)定時也就失效了,實際變成了單次定時關(guān)機
最后解決的方法是:再定義一個廣播接收器,用于接收系統(tǒng)開機時發(fā)出的廣播,當(dāng)接收到廣播時,創(chuàng)建一個activity,在activity中根據(jù)之前保存的數(shù)據(jù)重新設(shè)置定時,這樣就可以實現(xiàn)循環(huán),下面詳解
2.按照上面的想法,還是遇到了問題,如果要使用循環(huán),就必須靜態(tài)注冊接收開機廣播的廣播接收器。但是如果這樣的話,每次開機都會接收到廣播,并啟動新的activity,根據(jù)保存的數(shù)據(jù)設(shè)置定時,即使點擊了關(guān)閉定時或者取消循環(huán),也消除不了,就是說這個廣播接收器總會運行,然后進行強制的定時。在網(wǎng)上搜索到一個方法,說是使用PackageManager可以使在清單文件靜態(tài)注冊的廣播變回到默認(rèn)狀態(tài)(即未注冊狀態(tài)),但是好像不能再變?yōu)樽誀顟B(tài)了,關(guān)于這個類,作者講的比較詳細(xì)
3.針對2的問題,開始想到的辦法是,在主activity中設(shè)置接口和一個以該接口的引用為參數(shù)的方法,然后在第二個廣播接收器中實現(xiàn)接口,再根據(jù)由接口中得到的數(shù)據(jù)判斷開機后是否需要設(shè)置定時,但是在該廣播接收器中實現(xiàn)activity中的方法實在麻煩。后來發(fā)現(xiàn)這方法顯得笨拙了啊
問題解決方法
新的廣播接收器中(就叫做BootBroadcastReceiver),直接啟動新activity(就叫做BootActivity),畢竟在循環(huán)時,BootActivity是需要讀取本地保存的數(shù)據(jù)的,所以,直接根據(jù)讀取的數(shù)據(jù)進行判斷就好(保存的數(shù)據(jù)中有一個boolean類型的表示是是否設(shè)置了循環(huán),如果讀取的為false,那么直接結(jié)束掉這個activity,反之運行),下面是這個activity中的代碼,方法沒貼出,在GitHub有完整注釋的代碼
try {
getData(); //獲取上一次程序退出時保存的數(shù)據(jù)
getTime(); //將設(shè)定的時間轉(zhuǎn)換為alarmManager.set()方法中所需參數(shù)
setAlarm(); //設(shè)置定時
} catch (Exception e) {
e.printStackTrace();
}
}
小細(xì)節(jié)
為了方便使用,在新activity啟動時,不應(yīng)該有界面出現(xiàn),不然每次一開機就冒出來一個app界面豈不是很不爽,但是如果只是單純?nèi)サ鬭ctivity中的setContentView的話,則會在開機時出現(xiàn)一個白屏,還好activity中有針對這個的解決辦法。在清單文件中,activity標(biāo)簽下添加一個屬性即可在啟動該activity時不產(chǎn)生界面
<activity android:name=".BootActivity" android:theme="@android:style/Theme.NoDisplay"></activity>
在將字符串解析為整型的時候,把解析用的方法弄錯了(enter按的太快),結(jié)果總是問題,經(jīng)過一番折騰才發(fā)現(xiàn),用成了 Integer.getInteger,于是好奇這個看方法名像是轉(zhuǎn)換成整型的方法到底是干嘛的,網(wǎng)上說的是
Integer.getInteger(String)的功能是根據(jù)指定的名稱得到系統(tǒng)屬性的整數(shù)值。第一個參數(shù)將被認(rèn)為是系統(tǒng)屬性的名稱。系統(tǒng)屬性可以通過 System.getProperty(java.lang.String)方法訪問得到。屬性值字符串將被解釋成一個整數(shù),并且以表示這個值的Integer對象形式返回
內(nèi)容就這些了,主要是對昨天的問題進行收尾,把代碼都更新了一遍,如果需要的話,可以去下載看看,看注釋很容易懂,如果有錯誤,希望留言指出來哈
(新問題更新)
昨天小伙伴突然對我說,我的自動關(guān)機有重大bug,開機后馬上關(guān)機,再開機還是馬上關(guān)機,最后還是趁著開機到關(guān)機的一小會過渡時間卸載了app才得以解決,此問題一出,今天趕緊翻出來看看什么情況。
出現(xiàn)的問題:
1.如果設(shè)置的時間到了,自動關(guān)機了,然后當(dāng)天再次開機,于是就出現(xiàn)了這個情況。
2.開機后,會提示xx已停止運行(我記得當(dāng)時自己用的時候是沒出現(xiàn)這個問題的,今天用模擬器發(fā)現(xiàn)有這個問題)
3.改正1、2后,成功關(guān)機、開機,但是出現(xiàn)了ANR
原因是這樣的:
1.AlarmManager在設(shè)置時間時,如果設(shè)置的時間小于當(dāng)前時間嗎,則會立馬執(zhí)行(當(dāng)時大意了,沒注意到這個問題的影響),于是造就了開機后立馬關(guān)機的情況。但是如果是第二天在設(shè)置的時間點之前開機則不會出現(xiàn)立馬關(guān)機的情況
2.使用Theme.NoDispaly時,該Activity應(yīng)該繼承自Activity而不是AppCompatActivity
3.開機后,APP會自啟并設(shè)置提醒,然后一直在后臺什么都不做
解決:
1.在設(shè)置時間戳之前,添加一個判斷,判斷當(dāng)前設(shè)置的時間是否小于當(dāng)前時間,如果小于,則,將day加1,設(shè)置為第二天提醒
2.改繼承就OK
3.在自啟后執(zhí)行設(shè)置提醒后,finish()即可
(更改的代碼在GitHub中)