Android文字時鐘 — Part4

juxing發表於2014-02-19

前一篇文章中,我們已經可以在文字時鐘小部件上顯示時間,但是這個時間無法自動更新。在本文中我們將會使用AlarmManager定時更新小部件。

之前,我們討論過IntentService以及如何使用它去執行ActionAlarmManager為我們提供了一個定時啟動IntentService的完美機制。希望本文能幫你瞭解如何使用Intent啟動Android Service(之前介紹並使用過)。如何設定AlarmManager在某段時間間隔後執行這個Action,並且可以選擇時間間隔重複執行。不止侷限於啟動服務(Service),AlarmManager還可以執行許多其它Action。它可以傳送廣播並啟動活動(Activity)。PendingIntent用來表示將要被執行的Action,由AlarmManager安排這個Action將要執行的時間。

讓我們考慮一下我們的應用小部件應當如何更新。當使用者在主頁面建立一個小部件時會呼叫TextClockAppWidgetonUpdate()方法。到目前為止,我們只是在這個函式裡更新小部件的時間,沒有做任何其他事情。但其實我們還可以在這個方法裡安排即將要進行的更新。當然,我們仍然希望在這裡更新初始時間,所以我們保持startService()不變。我們希望做的是生成一個Alarm,這個Alarm會每分鐘觸發一個PendingIntent,呼叫一次startService()(當時間從59秒變到00秒的時候,分鐘數加一)確保小部件顯示精確的時間。

有一點要注意,使用者可能安裝多個小部件例項。但是我們只需要一個Alarm更新。我們的時鐘小部件本來就應該在同一時間更新,因此啟動多個服務就有些浪費了。壞訊息是,AlarmManager不允許我們查詢設定了哪些Alarm,這讓事情變得有些複雜。好訊息是,我們可以通過PendingIntent檢測是否有一個已經設定的Alarm。即使是建立在不同的執行緒、程式、甚至應用程式中,如果PendingIntent使用相同的操作(Operation)、Intent Action、資料、分類、元件和標記(Flag),那它就是唯一的PendingIntent。我們可以使用它管理Alarm。

為了便於說明,我們重點關注用PendingIntent來啟動服務。同樣的技術也可以應用在其他場合。我們無法直接建立PendingIntent,但是PendingIntent類為我們提供了一些靜態工廠方法。PendingIntent.getService()能夠接受四個引數:

  • Context contextPendingIntent啟動的服務上下文。
  • int requestCode:忽略。
  • Intent intent:用作startService()的引數,此函式會在剛才提供的context上呼叫。
  • int flags:用來控制是否需要以及如何建立或更新PendingIntent

如果我們使用FLAG_NO_CREATE標記,那麼PendingIntent.getService()會檢查是否有一個帶有同樣引數的PendingIntent已經存在於此裝置上。如果存在返回它的例項,否則返回null。因此我們可以使用這個方法確保只存在一個PendingIntent

如果建立PendingIntent時只建立了一個Alarm,那就可以保證只有一個Alarm

我們還可以應用於TextClockAppWidget

我們使用Calendar物件去尋找分鐘邊界。在每一個分鐘邊界處,我們設定一個每分鐘重複的Alarm。我們需要指定Alarm型別為RTC而不是RTC_WAKEUP,以此達到省電的目的。即使你的手機處於休眠狀態RTC_WAKEUP也會啟動服務,然而在使用者沒有看手機的情況下喚醒裝置並更新時間太費電。而使用RTC時,服務會在下一次裝置醒來時啟動(因此總是顯示準確時間),但不會喚醒裝置。

作為擁有良好習慣的Android程式設計師,需要在使用者移除我們的應用小部件例項時刪除Alarm

onDelete()在使用者每次移除小部件例項時觸發,所以我們需要檢查是否還有其他例項。如果已經沒有任何例項,那就移除Alarm。我們必須在這裡移除PendingIntent,如果不這樣做即使已經沒有與它關聯的Alarm,小部件還會一直在系統中處於活躍(Active)狀態。這樣會導致我們在scheduleTimer()中檢查PendingIntent失效。

如果我們執行程式,將會看到這個版本的文字時鐘顯示的是精確時間!

textclock_4_widget_update

現在我們有了一個實現基本功能的App:可以精確顯示時間。這就是Google Play上這個App的1.0.0版本。

我們將在下一章中繼續學習如何改進。

本文的原始碼可以在這裡找到,文字使用可以從Google Play下載。

相關文章