web-dev-qa-db-ja.com

アラームマネージャー-複数の非繰り返しイベントのスケジュール

Androidアラームマネージャーで、繰り返しがなく、繰り返しの間隔が決まっていない複数のアラームをスケジュールするにはどうすればよいですか?アラームに繰り返しがないため、「setRepeating」関数を使用できませんパターン。

Sqliteデータベーステーブルにアラーム時刻を保存しています。アクティビティはこのテーブルから日付と時刻を選択し、アラームを設定する必要があります。

ループ内に異なるアラームを設定すると、最後のアラームのみが保持されます。投稿から読みました: 複数のアラームを作成するにはどうすればよいですか?

一意のIDをインテントに添付してから、個々のアラームイベントを設定するように指示します。しかし、それは私にはうまくいきませんでした。

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

アクティビティ「RegularSchedule」のコードは次のとおりであり、1つのアラームイベントのみを作成します。

        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);
24
inder

これは私のために働いたものです。私は他の人がこの問題の恩恵を受けて迅速な解決策を見つけることができるように解決策を共有しています。

ソリューションの専門性と、特定のものが機能し、他のものが機能しない理由にさらに光を当てるために、他の入力を歓迎します:)

(1)まず、マニフェストファイル:BroadcastReceiverを備えたクラスのレシーバーがあることを確認します。

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

クラスはメインパッケージの一部であることに注意してください。サブパッケージに含まれている場合は、メインパッケージに移動してください。メインパッケージは、「マニフェスト」タグで定義するものです。

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

'data'タグは、AlarmManagerを使用してさまざまなアラームをスケジュールするときに、一意のインテントの動的URIを配置するものです。詳細については、次の手順を参照してください。

(2)AlarmManagerを使用してアラームをスケジュールするアクティビティクラス:データベースを使用してアラーム時間の値を保存し、それらの値を使用してスケジュールします。私のカーソルは、テーブルとアラーム時間(1970年1月1日からの秒数)から一意の_IDをフェッチします。ここに配置された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);
}

個別の通知を作成する場合は、notify()を呼び出すときにリクエストIDを一意として渡すことができることに注意してください。

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

28
inder

@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);
}

私にとってはうまくいきました。

1
issathink