2012-01-06 55 views
5

對於某些Android應用程序,我想集成以下功能: 用戶可以定義他想要提醒某事的時間。當時間到了,應用程序應該在通知欄中創建通知,即使此時用戶不使用該應用程序。在Android中創建定時通知(例如用於事件)

爲此,需要查看類AlarmManager,NotificationManager和Notification.Builder,對吧?

那麼如何提前創建定時通知?我的代碼(到目前爲止)是這樣的:在

添加這個到AndroidManifest註冊的廣播接收器:

<receiver android:name="AlarmNotificationReceiver"></receiver> 

創建一個新的類文件,它處理它接收到報警:

public class AlarmNotificationReceiver extends BroadcastReceiver { 

    public void onReceive(Context context, Intent intent) { 
     Bundle extras = intent.getExtras(); 
     if (extras != null) { 
      String additionalData = extras.getString("displayText"); 
      // show the notification now 
      NotificationManager mNotificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE); 
      Notification mNotification = new Notification(R.drawable.ic_launcher, context.getString(R.string.app_name), System.currentTimeMillis()); 
      PendingIntent pi = PendingIntent.getActivity(context, 0, new Intent(context, MainActivity.class), 0); // open MainActivity if the user selects this notification 
      mNotification.setLatestEventInfo(context, context.getString(R.string.app_name), additionalData, pi); 
      mNotification.flags |= Notification.FLAG_AUTO_CANCEL | Notification.DEFAULT_SOUND; 
      mNotificationManager.notify(1, mNotification); 
     } 
    } 

} 

使用此代碼(例如,在MainActivity)從現在設定報警時間爲3秒:

Intent i = new Intent(this, AlarmNotificationReceiver.class); 
    i.putExtra("displayText", "sample text"); 
    PendingIntent pi = PendingIntent.getBroadcast(this.getApplicationContext(), 234324246, i, 0); 
    AlarmManager mAlarm = (AlarmManager) getApplicationContext().getSystemService(Context.ALARM_SERVICE); 
    mAlarm.set(AlarmManager.RTC_WAKEUP, System.currentTimeMillis()+3*1000, pi); 

爲了完成這項工作,我需要改變什麼?謝謝!

的兩個問題是:當我在代碼更改

  1. 通知的文本不會更改。它只在我更改PendingIntent.getBroadcast(...)中的requestCode時發生更改。請求代碼的全部內容是什麼?它可以是一個隨機值還是0?
  2. 重新啓動手機後,「計劃」通知或鬧鐘消失。但現在我已經看到這是正常的行爲,對吧?我怎樣才能繞過這個?
+1

到目前爲止什麼都不工作? – 2012-01-06 01:31:17

回答

4

不確定第1部分,但對於第2部分,一般方法是攔截BOOT_COMPLETED意圖並使用該意圖重新註冊所有警報。這不幸的是,對於你已經在警報管理器註冊的每個警報,你都必須將它存儲在你的應用程序的數據庫中。

所以,你需要一個廣播接收器攔截BOOT_COMPLETED意圖:

public class BootReceiver extends BroadcastReceiver { 
    @Override 
    public void onReceive(Context context, Intent intent) { 
     // get your stored alarms from your database 
     // reregister them with the alarm manager 
    } 
} 

要獲得BOOT_COMPLETED意圖,你必須把以下權限在您的清單:

<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" /> 

而且BootReceiver還需要在清單中註冊以下意圖過濾器:

<receiver android:enabled="true" android:name=".receiver.BootReceiver" 
    android:permission="android.permission.RECEIVE_BOOT_COMPLETED"> 
     <intent-filter> 
       <action android:name="android.intent.action.BOOT_COMPLETED" /> 
       <category android:name="android.intent.category.DEFAULT" /> 
     </intent-filter> 
    </receiver> 

請注意,如果您的應用安裝到SD卡上,它永遠不會收到BOOT_COMPLETED意圖。另外,值得注意的是這個實現有點幼稚,因爲它在啓動時立即執行代碼,這可能會在啓動時降低用戶的電話速度。所以,我建議在攔截引導意圖後延遲執行幾分鐘。

+0

謝謝!真的沒有其他方法可以做到這一點?這聽起來有點(太)複雜。您需要額外的許可並執行這些註冊操作。那麼,不是每個應用程序的警報數量有限嗎?我認爲每個應用程序只允許註冊一個警報,之後的警報將被覆蓋。或者這是通知的規則? – caw 2012-01-09 16:00:06

+0

不幸的是沒有其他的方式來做到這一點。我不確定通知的侷限性,但我確信您可以註冊多個警報而沒有問題。 – danh32 2012-01-09 16:23:46

+0

所以我必須做你在這裏描述的,好吧:)我需要存儲這些警報的ID嗎?或者我可以在不存儲它們的情況下創建新的警報? – caw 2012-01-09 17:10:12

1

我個人會這樣做,沒有廣播接收器。我會讓AlarmManager發起啓動一個單獨的Activity而不是接收器的意圖。然後這個新的活動可以爲你通知。我不確定這是否是一種更好的方式,但對我而言似乎並不複雜。

編輯:服務可能會更好還是比活動

在您的MainActivity:

Intent i = new Intent(getBaseContext(), NotificationService.class); 
PendingIntent pi = PendingIntent.getService(getBaseContext(), 0, i, 0); 
AlarmManager mAlarm = (AlarmManager) Context.getSystemService(Context.ALARM_SERVICE); 
mAlarm.set(AlarmManager.RTC_WAKEUP, System.currentTimeMillis()+10*60*1000, pi); 

您服務:

public class NotificationService extends Service { 

public int onStartCommand(Intent intent, int flags, int startId) { 

//Create the notification here 

return START_NOT_STICKY; 
} 

您的清單:

<service android:name="com.android.yourpath.NotificationService"></service> 
+0

謝謝!你能解釋爲什麼使用服務比使用廣播更好嗎?我發現了幾個頁面上廣播的範例,涵蓋了警報。 – caw 2012-01-07 18:29:27

+0

真是個人喜好。對我來說,服務似乎更簡單一些,因爲您只需設置鬧鐘以在特定時間運行服務,而不是設置鬧鐘運行廣播,然後接收廣播以運行該操作。我認爲你需要寫一個自定義的意圖來使廣播方法起作用。 – 2012-01-08 12:27:24

+0

啊,好的。但是文檔說服務是用於長時間運行的後臺任務。所以我想我應該使用廣播。在這裏這個問題(http://stackoverflow.com/questions/1026973/android-whats-the-difference-between-the-various-methods-to-get-a-context),他們說不應該使用getBaseContext ();) – caw 2012-01-08 23:29:57