昨天寫的簡(jiǎn)易APP實(shí)現(xiàn)android定時(shí)關(guān)機(jī)辈赋,今天又倒騰了一天關(guān)于定時(shí)關(guān)機(jī)的,發(fā)現(xiàn)一些問(wèn)題
1.設(shè)置定時(shí)關(guān)機(jī)循環(huán)時(shí)(設(shè)定每天為一個(gè)周期)钥屈,當(dāng)手機(jī)關(guān)機(jī)后,再開機(jī)焕蹄,這個(gè)循環(huán)定時(shí)也就失效了,實(shí)際變成了單次定時(shí)關(guān)機(jī)
最后解決的方法是:再定義一個(gè)廣播接收器,用于接收系統(tǒng)開機(jī)時(shí)發(fā)出的廣播鸦泳,當(dāng)接收到廣播時(shí),創(chuàng)建一個(gè)activity做鹰,在activity中根據(jù)之前保存的數(shù)據(jù)重新設(shè)置定時(shí)击纬,這樣就可以實(shí)現(xiàn)循環(huán)更振,下面詳解
2.按照上面的想法,還是遇到了問(wèn)題饭尝,如果要使用循環(huán),就必須靜態(tài)注冊(cè)接收開機(jī)廣播的廣播接收器钥平。但是如果這樣的話,每次開機(jī)都會(huì)接收到廣播涉瘾,并啟動(dòng)新的activity,根據(jù)保存的數(shù)據(jù)設(shè)置定時(shí)立叛,即使點(diǎn)擊了關(guān)閉定時(shí)或者取消循環(huán),也消除不了秘蛇,就是說(shuō)這個(gè)廣播接收器總會(huì)運(yùn)行,然后進(jìn)行強(qiáng)制的定時(shí)彤叉。在網(wǎng)上搜索到一個(gè)方法庶柿,說(shuō)是使用PackageManager可以使在清單文件靜態(tài)注冊(cè)的廣播變回到默認(rèn)狀態(tài)(即未注冊(cè)狀態(tài))秽浇,但是好像不能再變?yōu)樽?cè)狀態(tài)了,關(guān)于這個(gè)類柬焕,作者講的比較詳細(xì)
3.針對(duì)2的問(wèn)題,開始想到的辦法是斑举,在主activity中設(shè)置接口和一個(gè)以該接口的引用為參數(shù)的方法,然后在第二個(gè)廣播接收器中實(shí)現(xiàn)接口富玷,再根據(jù)由接口中得到的數(shù)據(jù)判斷開機(jī)后是否需要設(shè)置定時(shí)璧坟,但是在該廣播接收器中實(shí)現(xiàn)activity中的方法實(shí)在麻煩。后來(lái)發(fā)現(xiàn)這方法顯得笨拙了啊
問(wèn)題解決方法
新的廣播接收器中(就叫做BootBroadcastReceiver)雀鹃,直接啟動(dòng)新activity(就叫做BootActivity),畢竟在循環(huán)時(shí)黎茎,BootActivity是需要讀取本地保存的數(shù)據(jù)的,所以傅瞻,直接根據(jù)讀取的數(shù)據(jù)進(jìn)行判斷就好(保存的數(shù)據(jù)中有一個(gè)boolean類型的表示是是否設(shè)置了循環(huán),如果讀取的為false嗅骄,那么直接結(jié)束掉這個(gè)activity胳挎,反之運(yùn)行)溺森,下面是這個(gè)activity中的代碼串远,方法沒(méi)貼出儿惫,在GitHub有完整注釋的代碼
try {
getData(); //獲取上一次程序退出時(shí)保存的數(shù)據(jù)
getTime(); //將設(shè)定的時(shí)間轉(zhuǎn)換為alarmManager.set()方法中所需參數(shù)
setAlarm(); //設(shè)置定時(shí)
} catch (Exception e) {
e.printStackTrace();
}
}
小細(xì)節(jié)
為了方便使用肾请,在新activity啟動(dòng)時(shí),不應(yīng)該有界面出現(xiàn)更胖,不然每次一開機(jī)就冒出來(lái)一個(gè)app界面豈不是很不爽,但是如果只是單純?nèi)サ鬭ctivity中的setContentView的話却妨,則會(huì)在開機(jī)時(shí)出現(xiàn)一個(gè)白屏,還好activity中有針對(duì)這個(gè)的解決辦法彪标。在清單文件中,activity標(biāo)簽下添加一個(gè)屬性即可在啟動(dòng)該activity時(shí)不產(chǎn)生界面
<activity android:name=".BootActivity" android:theme="@android:style/Theme.NoDisplay"></activity>
在將字符串解析為整型的時(shí)候捞烟,把解析用的方法弄錯(cuò)了(enter按的太快),結(jié)果總是問(wèn)題题画,經(jīng)過(guò)一番折騰才發(fā)現(xiàn)默辨,用成了 Integer.getInteger
,于是好奇這個(gè)看方法名像是轉(zhuǎn)換成整型的方法到底是干嘛的,網(wǎng)上說(shuō)的是
Integer.getInteger(String)的功能是根據(jù)指定的名稱得到系統(tǒng)屬性的整數(shù)值苍息。第一個(gè)參數(shù)將被認(rèn)為是系統(tǒng)屬性的名稱壹置。系統(tǒng)屬性可以通過(guò) System.getProperty(java.lang.String)方法訪問(wèn)得到。屬性值字符串將被解釋成一個(gè)整數(shù)钞护,并且以表示這個(gè)值的Integer對(duì)象形式返回
內(nèi)容就這些了,主要是對(duì)昨天的問(wèn)題進(jìn)行收尾患亿,把代碼都更新了一遍,如果需要的話押逼,可以去下載看看,看注釋很容易懂挑格,如果有錯(cuò)誤,希望留言指出來(lái)哈
(新問(wèn)題更新)
昨天小伙伴突然對(duì)我說(shuō)漂彤,我的自動(dòng)關(guān)機(jī)有重大bug,開機(jī)后馬上關(guān)機(jī)挫望,再開機(jī)還是馬上關(guān)機(jī)立润,最后還是趁著開機(jī)到關(guān)機(jī)的一小會(huì)過(guò)渡時(shí)間卸載了app才得以解決桑腮,此問(wèn)題一出,今天趕緊翻出來(lái)看看什么情況破讨。
出現(xiàn)的問(wèn)題:
1.如果設(shè)置的時(shí)間到了,自動(dòng)關(guān)機(jī)了奕纫,然后當(dāng)天再次開機(jī),于是就出現(xiàn)了這個(gè)情況匹层。
2.開機(jī)后,會(huì)提示xx已停止運(yùn)行(我記得當(dāng)時(shí)自己用的時(shí)候是沒(méi)出現(xiàn)這個(gè)問(wèn)題的又固,今天用模擬器發(fā)現(xiàn)有這個(gè)問(wèn)題)
3.改正1、2后仰冠,成功關(guān)機(jī)、開機(jī)洋只,但是出現(xiàn)了ANR
原因是這樣的:
1.AlarmManager在設(shè)置時(shí)間時(shí)辆沦,如果設(shè)置的時(shí)間小于當(dāng)前時(shí)間嗎,則會(huì)立馬執(zhí)行(當(dāng)時(shí)大意了肢扯,沒(méi)注意到這個(gè)問(wèn)題的影響),于是造就了開機(jī)后立馬關(guān)機(jī)的情況蔚晨。但是如果是第二天在設(shè)置的時(shí)間點(diǎn)之前開機(jī)則不會(huì)出現(xiàn)立馬關(guān)機(jī)的情況
2.使用Theme.NoDispaly時(shí),該Activity應(yīng)該繼承自Activity而不是AppCompatActivity
3.開機(jī)后铭腕,APP會(huì)自啟并設(shè)置提醒,然后一直在后臺(tái)什么都不做
解決:
1.在設(shè)置時(shí)間戳之前累舷,添加一個(gè)判斷,判斷當(dāng)前設(shè)置的時(shí)間是否小于當(dāng)前時(shí)間被盈,如果小于析孽,則,將day加1袜瞬,設(shè)置為第二天提醒
2.改繼承就OK
3.在自啟后執(zhí)行設(shè)置提醒后,finish()即可
(更改的代碼在GitHub中)