回答:
投稿されたコメントronのフォローアップ、詳細な解決策を以下に示します。次のような保留中のインテントで繰り返しアラームを登録したとします。
Intent intent = new Intent("com.my.package.MY_UNIQUE_ACTION");
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0,
intent, PendingIntent.FLAG_UPDATE_CURRENT);
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
calendar.add(Calendar.MINUTE, 1);
AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), 1000 * 60, pendingIntent);
アクティブかどうかを確認する方法は、次のとおりです。
boolean alarmUp = (PendingIntent.getBroadcast(context, 0,
new Intent("com.my.package.MY_UNIQUE_ACTION"),
PendingIntent.FLAG_NO_CREATE) != null);
if (alarmUp)
{
Log.d("myTag", "Alarm is already active");
}
ここでの鍵は、FLAG_NO_CREATE
javadocで説明されているものですif the described PendingIntent **does not** already exists, then simply return null
(新しいものを作成する代わりに)。
alarmManager.cancel(pendingIntent)
してpendingIntent.cancel()
リターンfalseに、このソリューションのために。
これを必要とする他の人のために、ここに答えがあります。
使用する adb shell dumpsys alarm
アラームが設定されていることと、アラームが発生するタイミングと間隔を知ることができます。また、このアラームが呼び出された回数。
adb shell dumpsys alarm | grep <e.g. package name of your app>
新しいWindowsシステムでも動作します(Win10を使用しています)
レシーバーを使用した実例(トップの答えはアクションのみでした)。
//starting
AlarmManager alarmManager = (AlarmManager) getActivity().getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(getActivity(), MyReceiver.class);
intent.setAction(MyReceiver.ACTION_ALARM_RECEIVER);//my custom string action name
PendingIntent pendingIntent = PendingIntent.getBroadcast(getActivity(), 1001, intent, PendingIntent.FLAG_CANCEL_CURRENT);//used unique ID as 1001
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(), aroundInterval, pendingIntent);//first start will start asap
//and stopping
Intent intent = new Intent(getActivity(), MyReceiver.class);//the same as up
intent.setAction(MyReceiver.ACTION_ALARM_RECEIVER);//the same as up
PendingIntent pendingIntent = PendingIntent.getBroadcast(getActivity(), 1001, intent, PendingIntent.FLAG_CANCEL_CURRENT);//the same as up
alarmManager.cancel(pendingIntent);//important
pendingIntent.cancel();//important
//checking if alarm is working with pendingIntent
Intent intent = new Intent(getActivity(), MyReceiver.class);//the same as up
intent.setAction(MyReceiver.ACTION_ALARM_RECEIVER);//the same as up
boolean isWorking = (PendingIntent.getBroadcast(getActivity(), 1001, intent, PendingIntent.FLAG_NO_CREATE) != null);//just changed the flag
Log.d(TAG, "alarm is " + (isWorking ? "" : "not") + " working...");
言及する価値があります:
作成中のアプリケーションが後で同じ種類のPendingIntent(同じ操作、同じインテント-アクション、データ、カテゴリ、コンポーネント、フラグ)を再取得(処理)する場合、それがまだ有効であれば、同じトークンを表すPendingIntentを受け取ります。したがって、cancel()を呼び出して削除できます。
つまり、PendingIntentは、それを制御するために同じ機能(操作とインテントの構造)を持つ必要があります。
アラームマネージャーのsetメソッドのドキュメントからのこの引用に注意してください。
このインテントのアラームがすでにスケジュールされている場合(2つのインテントの同等性がIntent.filterEqualsによって定義されている場合)、アラームは削除され、このインテントに置き換えられます。
アラームを設定したい場合は、すでに存在しているかどうかを確認する必要はありません。アプリが起動するたびに作成してください。過去のアラームを同じものに置き換えますIntent
。
以前に作成したアラームの残り時間を計算する場合や、そのようなアラームが存在するかどうかを本当に知る必要がある場合は、別の方法が必要です。これらの質問に答えるには、アラームを作成するときに共有設定データを保存することを検討してください。アラームが設定された時刻のクロックタイムスタンプ、アラームが鳴ると予想される時間、および繰り返し周期(繰り返しアラームを設定した場合)を保存できます。
2つのアラームがあります。イベントを識別するために、アクションではなくエクストラを使用してインテントを使用しています。
Intent i = new Intent(context, AppReciever.class);
i.putExtra("timer", "timer1");
問題は、diffエクストラを使用すると、意図(およびアラーム)が一意にならないことです。どのアラームがアクティブであるかどうかを特定できるように、diff requestCode
-s を定義する必要がありました。
boolean alarmUp = (PendingIntent.getBroadcast(context, MyApp.TIMER_1, i,
PendingIntent.FLAG_NO_CREATE) != null);
アラームが作成された方法は次のとおりです。
public static final int TIMER_1 = 1;
public static final int TIMER_2 = 2;
PendingIntent pending = PendingIntent.getBroadcast(context, TIMER_1, i,
PendingIntent.FLAG_CANCEL_CURRENT);
setInexactRepeating(AlarmManager.RTC_WAKEUP,
cal.getTimeInMillis(), AlarmManager.INTERVAL_DAY, pending);
pending = PendingIntent.getBroadcast(context, TIMER_2, i,
PendingIntent.FLAG_CANCEL_CURRENT);
setInexactRepeating(AlarmManager.RTC_WAKEUP,
cal.getTimeInMillis(), AlarmManager.INTERVAL_DAY, pending);
PendingIntent.getService
ちょうど別の解決策を見つけた、それは私のために働くようです
Intent myIntent = new Intent(MainActivity.this, MyReceiver.class);
boolean isWorking = (PendingIntent.getBroadcast(MainActivity.this, 0, myIntent, PendingIntent.FLAG_NO_CREATE) != null);
if (isWorking) {Log.d("alarm", "is working");} else {Log.d("alarm", "is not working");}
if(!isWorking) {
pendingIntent = PendingIntent.getBroadcast(MainActivity.this, 0, myIntent, PendingIntent.FLAG_UPDATE_CURRENT);
alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
int timeNotif = 5 * 60 * 1000;//time in ms, 7*24*60*60*1000 for 1 week
Log.d("Notif", "Notification every (ms): " + timeNotif);
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), timeNotif, pendingIntent);
}
ここにいるほとんどの人が正しい答えを出していますが、アラームの仕組みがどのような根拠で説明されているのかはわかりません。
ここでAlarmManager
、実際にその動作についてさらに学ぶことができます。しかし、ここに簡単な答えがあります
あなたはAlarmManager
基本的にスケジュールPendingIntent
を将来的に見ていきます。したがって、スケジュールされたアラームをキャンセルするには、をキャンセルする必要がありますPendingIntent
。
作成中は常に2つのことに注意してください PendingIntent
PendingIntent.getBroadcast(context,REQUEST_CODE,intent, PendingIntent.FLAG_UPDATE_CURRENT);
PendingIntent
ここで、アラームがすでにスケジュールされているかどうかを確認したり、アラームをキャンセルしたりするには、アラームにアクセスする必要がありますPendingIntent
。これは、同じリクエストコードを使用しFLAG_NO_CREATE
、以下に示すように使用する場合に実行できます
PendingIntent pendingIntent=PendingIntent.getBroadcast(this,REQUEST_CODE,intent,PendingIntent.FLAG_NO_CREATE);
if (pendingIntent!=null)
alarmManager.cancel(pendingIntent);
ではFLAG_NO_CREATE
それが返されnull
た場合PendingIntent
、すでに存在していません。すでに存在する場合は、既存への参照を返しますPendingIntent
私はadbシェルからlongを抽出し、それらをタイムスタンプに変換して赤で表示する、単純な(愚かなかどうかにかかわらず)bashスクリプトを作成しました。
echo "Please set a search filter"
read search
adb shell dumpsys alarm | grep $search | (while read i; do echo $i; _DT=$(echo $i | grep -Eo 'when\s+([0-9]{10})' | tr -d '[[:alpha:][:space:]]'); if [ $_DT ]; then echo -e "\e[31m$(date -d @$_DT)\e[0m"; fi; done;)
それを試してみてください ;)
Intent intent = new Intent("com.my.package.MY_UNIQUE_ACTION");
PendingIntent pendingIntent = PendingIntent.getBroadcast(
sqlitewraper.context, 0, intent,
PendingIntent.FLAG_NO_CREATE);
FLAG_NO_CREATEは作成保留中のインテントではないため、ブール値falseを返します。
boolean alarmUp = (PendingIntent.getBroadcast(sqlitewraper.context, 0,
new Intent("com.my.package.MY_UNIQUE_ACTION"),
PendingIntent.FLAG_NO_CREATE) != null);
if (alarmUp) {
System.out.print("k");
}
AlarmManager alarmManager = (AlarmManager) sqlitewraper.context
.getSystemService(Context.ALARM_SERVICE);
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP,
System.currentTimeMillis(), 1000 * 60, pendingIntent);
AlarmManagerがPending Intentの値を確認した後、AlarmManagerがPending Intentのフラグを更新するため、Trueになります。
boolean alarmUp1 = (PendingIntent.getBroadcast(sqlitewraper.context, 0,
new Intent("com.my.package.MY_UNIQUE_ACTION"),
PendingIntent.FLAG_UPDATE_CURRENT) != null);
if (alarmUp1) {
System.out.print("k");
}