實(shí)現(xiàn)定時(shí)關(guān)機(jī)的方法之一(網(wǎng)上還有多種方法魄健,目前用的這個(gè)是自己實(shí)踐的)
主要是使用AlarmManager泉蝌,思路就是:利用AlarmManager在特定的時(shí)刻發(fā)送一個(gè)廣播,在程序中寫一個(gè)廣播接收器用于接收這個(gè)廣播打洼,一旦接收到該廣播蠢古,則執(zhí)行關(guān)機(jī)的命令。一句話就介紹完了欲主,但是個(gè)人覺(jué)得這個(gè)知識(shí)點(diǎn)還是蠻有用的邓厕,下面詳解這次用到的知識(shí)點(diǎn)及遇到的問(wèn)題
關(guān)于AlarmManager的官網(wǎng)文檔介紹
Note: The Alarm Manager is intended for cases where you want to have your application code run at a specific time, even if your application is not currently running. For normal timing operations (ticks, timeouts, etc) it is easier and much more efficient to use Handler.
上面說(shuō)的是:當(dāng)你想要在某個(gè)特定的時(shí)刻運(yùn)行你的程序代碼,可以使用AlarmManager扁瓢,即使當(dāng)前該程序并沒(méi)有運(yùn)行亦可详恼。對(duì)于平時(shí)那些用到定時(shí)的操作(如ticks, timeouts),AlarmManager比Handler使用起來(lái)各更簡(jiǎn)單引几、有效
該APP的截圖
關(guān)于界面就不介紹了昧互。
主要實(shí)現(xiàn)大體是按照上面的思路來(lái)的
1.設(shè)置AlarmManager所需的參數(shù)
Intent intent = new Intent(getApplicationContext(), AlarmBroadcastReciver.class); pendingIntent = PendingIntent.getBroadcast(getApplicationContext(), 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
}```
這里要說(shuō)一下關(guān)于AlarmManager的幾個(gè)重要方法!
[這篇文章介紹的比較詳細(xì)她紫,感謝作者](http://www.runoob.com/w3cnote/android-tutorial-alarmmanager.html)
`set(int type, long triggerAtMillis, PendingIntent operation)`
這個(gè)方法是本次使用到的方法之一硅堆,用于在特定時(shí)間傳遞一個(gè)廣播,但是只能單次提醒贿讹,它的參數(shù)說(shuō)明:
**第一個(gè)參數(shù)是指AlarmManager的類型**渐逃,有5個(gè)值可以選擇:`AlarmManager.ELAPSED_REALTIME` 鬧鐘在手機(jī)睡眠狀態(tài)下不可用,該狀態(tài)下鬧鐘使用相對(duì)時(shí)間(相對(duì)于系統(tǒng)啟動(dòng)開(kāi)始); `AlarmManager.ELAPSED_REALTIME_WAKEUP `鬧鐘在睡眠狀態(tài)下會(huì)喚醒系統(tǒng)并執(zhí)行提示功能民褂,該狀態(tài)下鬧鐘也使用相對(duì)時(shí)間茄菊; `AlarmManager.RTC `鬧鐘在睡眠狀態(tài)下不可用,該狀態(tài)下鬧鐘使用絕對(duì)時(shí)間(即當(dāng)前系統(tǒng)時(shí)間)赊堪;` AlarmManager.RTC_WAKEUP` 表示鬧鐘在睡眠狀態(tài)下會(huì)喚醒系統(tǒng)并執(zhí)行提示功能面殖,該狀態(tài)下鬧鐘使用絕對(duì)時(shí)間; `AlarmManager.POWER_OFF_WAKEUP `表示鬧鐘在手機(jī)關(guān)機(jī)狀態(tài)下也能正常進(jìn)行提示
**第二個(gè)參數(shù)是指開(kāi)啟提示的時(shí)間**
**第三個(gè)參數(shù)是綁定了需要執(zhí)行的操作**,比如這次采用的發(fā)送廣播哭廉,也可以彈出提示框等等
`setRepeating(int type, long triggerAtMillis, long intervalMillis, PendingIntent operation)`
這個(gè)方法和上一個(gè)類似脊僚,就是多了一個(gè)參數(shù)`long intervalMillis`,這個(gè)方法是可以重復(fù)執(zhí)行提醒功能,而多出的這個(gè)參數(shù)就是重復(fù)提醒之間的時(shí)間間隔
`cancel(PendingIntent operation)`
這個(gè)方法從名字就可以看出來(lái)遵绰,是用來(lái)取消提醒的
2.設(shè)置廣播接收器
注意1中的這一行代碼 `Intent intent = new Intent(getApplicationContext(), AlarmBroadcastReciver.class); ` 這行代碼就是利用Intent直接指定廣播接收器辽幌,這樣就不需要在清單文件中注冊(cè)具體的廣播標(biāo)簽,該廣播接收器接受到廣播時(shí)椿访,會(huì)直接執(zhí)行關(guān)機(jī)操作
```@Override
public void onReceive(Context context, Intent intent) { Toast.makeText(context,"關(guān)機(jī)啦", Toast.LENGTH_SHORT).show(); try { Process process = Runtime.getRuntime().exec("su"); DataOutputStream out = new DataOutputStream( process.getOutputStream()); out.writeBytes("reboot -p\n"); out.writeBytes("exit\n"); out.flush(); } catch (IOException e) { e.printStackTrace(); }```
3.設(shè)置按鈕監(jiān)聽(tīng)器乌企,根據(jù)點(diǎn)擊的按鈕開(kāi)啟循環(huán)提醒還是單次提醒,同時(shí)顯示出當(dāng)前設(shè)定的數(shù)據(jù)
4.重寫onStop()方法成玫,在方法中使用ShardPreference用于保存設(shè)定的數(shù)據(jù)加酵,在進(jìn)入程序時(shí)讀取保存的數(shù)據(jù)拳喻,并顯示出來(lái),以方便知道之前設(shè)定的數(shù)據(jù)
遇到的問(wèn)題:本來(lái)是覆寫的onDestroy()方法猪腕,想的是在程序銷毀時(shí)保存數(shù)據(jù)冗澈,結(jié)果總是沒(méi)保存下來(lái),之前也用過(guò)ShardPreference在onDestroy()方法中保存數(shù)據(jù)码撰,是可以的渗柿。最后經(jīng)過(guò)多次測(cè)試,又看了一下Activity的生命周期圖才發(fā)現(xiàn)問(wèn)題所在脖岛,下面結(jié)合官網(wǎng)給出的生命圖來(lái)說(shuō)明

當(dāng)程序進(jìn)入到后臺(tái)時(shí)就由運(yùn)行態(tài)轉(zhuǎn)換到onPause()態(tài)朵栖,當(dāng)不再對(duì)用戶可見(jiàn)時(shí),就會(huì)進(jìn)入到onStop()態(tài)柴梆,當(dāng)程序被finifsh掉后陨溅,會(huì)進(jìn)入onDestroy()進(jìn)而被消滅,這種正常退出的情況下在onDestroy()中保存數(shù)據(jù)當(dāng)然是可以的绍在。但是考慮到圖中的另一條路線门扇,由onStop()直接轉(zhuǎn)到死亡狀態(tài),這種情況就屬于非正常情況退出了偿渡,比如正在運(yùn)行時(shí)突然被什么清理軟件給徹底殺掉了臼寄,那么這個(gè)時(shí)候是不會(huì)到onDestroy()這一步,所以此時(shí)在這個(gè)方法中保存數(shù)據(jù)就會(huì)失敗溜宽,因此面對(duì)這種情況可以考慮覆寫onStop()方法進(jìn)行保存數(shù)據(jù)吉拳,然后在onCreate()中即活動(dòng)剛創(chuàng)建時(shí)獲取即可
按照習(xí)慣,總是以一個(gè)小APP的形式熟悉這些知識(shí)點(diǎn)适揉,全代碼還有之前的涉及到其他知識(shí)點(diǎn)的小APP的代碼留攒,都放在[GitHub](https://github.com/huangkunkun/),有些地方可能說(shuō)的不是很到位,希望各位大神留言指正
一些bug的更改及遺漏問(wèn)題放在[Android定時(shí)關(guān)機(jī)問(wèn)題解決](http://www.reibang.com/p/da37562f1111)