답변:
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는 제어 할 수있는 동일한 기능 (작업 및 의도의 구조)을 가져야합니다.
경보 관리자의 설정 방법에 대한 문서 의이 인용문 을 참고 하십시오 .
예약 된이 의도에 대한 경보가 이미있는 경우 (Intent.filterEquals에 의해 정의 된 두 의도가 동일 함) 경보가 제거되고이 경보로 대체됩니다.
알람 설정이 필요하다는 것을 알고 있다면 이미 존재하는지 여부를 확인하지 않아도됩니다. 앱이 부팅 될 때마다 만들면됩니다. 과거의 알람을 모두 같은 것으로 교체합니다 Intent.
이전에 생성 된 알람에 남아있는 시간을 계산하거나 이러한 알람이 존재하는지 여부를 알아야하는 경우 다른 접근 방법이 필요합니다. 이러한 질문에 답하려면 알람을 만들 때 공유 준비 데이터를 저장하는 것이 좋습니다. 알람이 설정되는 순간, 알람이 울릴 것으로 예상되는 시간 및 반복 기간 (반복 알람을 설정 한 경우)에 시계 타임 스탬프를 저장할 수 있습니다.
알람이 2 개 있습니다. 이벤트를 식별하기 위해 조치 대신 추가 기능을 사용하려고합니다.
Intent i = new Intent(context, AppReciever.class);
i.putExtra("timer", "timer1");
문제는 diff extras를 사용하면 의도 (및 경보)가 고유하지 않을 것입니다. 따라서 어떤 알람이 활성화되어 있는지 확인하려면 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.
항상 두 가지를 기록해 두십시오. 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의 플래그를 업데이트하므로 참이됩니다.
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");
}