2011-07-11 16 views
23

Android Alarm Managerでは、繰り返しのない複数のアラームをスケジュールするにはどうすればよいでしょうか?私は 'setRepeating'関数を使用することはできません。アラームは繰り返しパターンを持たないからです。Alarm Manager - 複数の非繰り返しイベントをスケジュールする

私はアラーム時刻をSqliteデータベーステーブルに格納しており、このテーブルから日時を選択してアラームを設定する必要があります。

ループ内で異なるアラームを設定すると、最後のアラームだけが保持されます。 投稿から読む:How can create more than one alarm?

固有のIDをインテントに添付し、個々のアラームイベントを設定するように指示します。しかし、それは私にとってはうまくいかなかった。

この一意のIDを処理するためにマニフェストファイルに追加する必要があるものはありますか?

活動のコードは「RegularSchedule」であり、それが唯一のアラームイベントを作成します。

 while (notifCursor.moveToNext()) { 
      Intent intent = new Intent(RegularSchedule.this, 
        RepeatingAlarm.class); 

      // The cursor returns first column as unique ID    
      intent.setData(Uri.parse("timer:" + notifCursor.getInt(0))); 

      PendingIntent sender = PendingIntent.getBroadcast(
        RegularSchedule.this, 0, intent, 0); 

      // Setting time in milliseconds taken from database table 
      cal.setTimeInMillis(notifCursor.getLong(1)); 

      AlarmManager am = (AlarmManager) getSystemService(ALARM_SERVICE); 
      am.set(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), sender); 
     } 

詳細やコードスニペットが必要な場合は私に知らせてください。

マニフェストファイル(ここではRepeatingAlarm BroadcastReceiverを拡張):

<receiver android:name=".user_alerts.RepeatingAlarm" android:process=":remote" /> 

    <activity android:name=".user_alerts.RegularSchedule" 
     android:label="@string/reg_schedule_title" android:theme="@android:style/Theme.Light"> 
    </activity> 

RepeatingAlarm:

public class RepeatingAlarm extends BroadcastReceiver { 
@Override 
public void onReceive(Context context, Intent intent) { 
    NotificationManager mNotificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE); 
....... 
    // The PendingIntent to launch our activity if the user selects this notification 
    Intent notificationIntent = new Intent (context, DisplayReminder.class); 
    PendingIntent contentIntent = PendingIntent.getActivity(context, 0, notificationIntent, 0); 

    // Set the info for the views that show in the notification panel. 
    notification.setLatestEventInfo(context, contentTitle, contentText, contentIntent); 
    notification.defaults |= Notification.DEFAULT_SOUND; 
    notification.defaults |= Notification.DEFAULT_VIBRATE; 
    notification.defaults |= Notification.DEFAULT_LIGHTS; 

    mNotificationManager.notify(2425, notification); 

答えて

27

これは私のために働いたものです。他の人がこの問題に迅速に対応できるように、私はこのソリューションを共有しています。

私は(1)すべて、マニフェストファイルの第1の溶液の専門的でより多くの光をスローするように、他の入力を歓迎し、なぜ特定の物事が仕事や他の人が

:)をしていない: はあなたのことを確認してくださいあなたのクラスの受信機にBroadcastReceiverを持たせてください。

<receiver android:name=".RepeatingAlarm" android:process=":remote"> 
     <intent-filter> 
      <data android:scheme="timer:" /> 
     </intent-filter> 
    </receiver> 

このクラスはメインパッケージの一部です。一部のサブパッケージにある場合は、メインパッケージに移動してください。主なパッケージは、あなたが 'マニフェスト'タグで定義するものです。

「インテントフィルタ」は、「アクション」と「データ」を定義するために使用されます。保留中のインテントから呼び出されるActivityクラスをここに配置できます。しかし、マニフェストで「アクション」を定義すると、アクティビティに動的な値が表示されないことが分かりました。静的な値を表示するだけです。かなり奇妙。同じ問題に遭遇した場合は、マニフェストに 'action'を入れず、保留中のインテントの一部としてBroadcastReceiverクラスに入れてください。

「data」タグは、AlarmManagerを使用して異なるアラームをスケジュールしながら、ユニークなインテントの動的URIを配置するものです。詳細は次のステップを参照してください。

(2)AlarmManagerを使用してアラームをスケジュールするアクティビティクラス: データベースを使用してアラーム時間値を保存し、それらの値を使用してスケジューリングしています。私のカーソルはテーブルからの一意の_IDとアラーム時間(1970年1月1日からの秒数)を取得します。ここに入れたURIは、マニフェストファイルのURIと同じであることを確認してください。

Calendar cal = Calendar.getInstance(); 
    int notifIterator = 0; 

    if (notifCursor.getCount() > 0) { 
     while (notifCursor.moveToNext()) { 
      Intent intent = new Intent(MySchedule.this, 
        RepeatingAlarm.class); 

      // As the same intent cancels the previously set alarm having 
      // same intent 
      // changing the intent for every alarm event so that every alarm 
      // gets 
      // scheduled properly. 
      intent.setData(Uri.parse("timer:" + notifCursor.getInt(0))); 

      PendingIntent sender = PendingIntent.getBroadcast(
        MySchedule.this, 0, intent, 
        Intent.FLAG_GRANT_READ_URI_PERMISSION); 

      cal.setTimeInMillis(notifCursor.getLong(1) * 1000); 

      AlarmManager am = (AlarmManager) getSystemService(ALARM_SERVICE); 
      am.set(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), sender); 

      notifIterator++; 

      Toast mToast = Toast.makeText(
        RegularSchedule.this, 
        "Reminders added to the calendar successfully for " 
          + android.text.format.DateFormat.format(
            "MM/dd/yy h:mmaa", 
            cal.getTimeInMillis()), 
        Toast.LENGTH_LONG); 
      mToast.show(); 
     } 
    } 

あなたも、これを実行した後にアラームが表示されない場合は、はエミュレータがかかる時間帯をご確認ください。時には、ローカルタイムゾーンをスケジュールすることもありますが、GMTタイムゾーンのエミュレータスケジュールを設定することもあります。トーストメッセージを見ると、この問題を理解するのに役立ちます。

(3)最後はBroadcastReceiverクラスです。

public void onReceive(Context context, Intent intent) { 

    // Update the status in the notification database table 
    int notificationId = Integer.parseInt(intent.getData().getSchemeSpecificPart()); 

    db = context.openOrCreateDatabase(DATABASE_NAME, 
      SQLiteDatabase.CREATE_IF_NECESSARY, null); 

    <<<< Do DB stuff like fetching or updating something>>>> 

    // Raise the notification so that user can check the details 
    NotificationManager mNotificationManager = (NotificationManager) context 
      .getSystemService(Context.NOTIFICATION_SERVICE); 

    int icon = R.drawable.icon; 
    CharSequence tickerText = "your text"; 
    long when = System.currentTimeMillis(); 

    Notification notification = new Notification(icon, tickerText, when); 

    // Count of number of notifications 
    notification.number = notifCount; 

    CharSequence contentTitle = "your title "; 
    CharSequence contentText = "your notification text"; 

    // The PendingIntent to launch our activity if the user selects this 
    // notification 
    Intent notificationIntent = new Intent(context, DisplayReminder.class); 
    PendingIntent contentIntent = PendingIntent.getActivity(context, 0, 
      notificationIntent, 0); 


    // Set the info for the views that show in the notification panel. 
    notification.setLatestEventInfo(context, contentTitle, contentText, 
      contentIntent); 
    notification.defaults |= Notification.DEFAULT_SOUND; 
    notification.defaults |= Notification.DEFAULT_VIBRATE; 
    notification.defaults |= Notification.DEFAULT_LIGHTS; 

    // Instead of 1234 or any other number, use below expression to have unique notifications 
    // Integer.parseInt(intent.getData().getSchemeSpecificPart()) 
    mNotificationManager.notify(1234, notification); 
} 

(注)個別の通知を作成する場合は()に通知呼び出すときに、要求IDが一意として渡すことができること:あなたが「コンテキスト」を使用する必要があります、データベースをオープンすることに注意してください。

最後に、ユーザーが通知をクリックしたときに呼び出すDisplayReminderクラスを作成できます。

+13

私のための鍵は、この行です:int.setData(Uri.parse( "timer:" + notifCursor.getInt(0)));インテントが一意であることを保証し、その後のAlarmManager.setの呼び出しは、前のアラームをキャンセルしません。 –

+0

ありがとうございました@JonathonHorsman私は独自の新しい値を手渡し、スレッドを保存して共有設定に保存するためにこの[小さなクラス](https://gist.github.com/deadfalkon/5a579aca2179cab10e7b)を作成しました。あなたのアプリが殺された場合)。 – volkersfreunde

+0

@inder:素晴らしい仕事の男! – mudit

1

@Jonathon Horsmanが示唆しているように、作成するインテントが一意であることを確認してください。

あなたが例えば10のアラームを設定する場合:

for(int i=; i<10; i++) { 
    Intent intent = new Intent(YourActivity.this, 
       YourAlarm.class); 
    intent.setData(Uri.parse("timer:" + i); 
    PendingIntent sender = PendingIntent.getBroadcast(
       YourActivity.this, 0, intent, 
       Intent.FLAG_GRANT_READ_URI_PERMISSION); 
    AlarmManager am = (AlarmManager) getSystemService(ALARM_SERVICE); 
    am.set(AlarmManager.RTC_WAKEUP, yourTimeInMillis, sender); 
} 

は私のためにうまく働きました。

+0

Intent.FLAG_GRANT_READ_URI_PERMISSION - タイプが正しくありません。私は、私がintent.getData()を使うことができるようにそのフラグを設定する必要があることを理解しています。onReceiveでgetSchemeSpecificPart() – marienke

関連する問題