IT story

AlarmManager에 이미 알람이 설정되어 있는지 확인하는 방법은 무엇입니까?

hot-time 2020. 4. 25. 09:54
반응형

AlarmManager에 이미 알람이 설정되어 있는지 확인하는 방법은 무엇입니까?


내 앱이 시작되면 특정 알람 (AlarmManager를 통해 등록)이 이미 설정되어 실행 중인지 확인하고 싶습니다. 구글의 결과는 이것을 할 수있는 방법이 없다는 것을 나타냅니다. 여전히 맞습니까? 새 경보를 만들기 위해 조치를 취하기 전에 사용자에게 알리려면이 점검을 수행해야합니다.


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(새 것을 만드는 대신)


이것이 필요할 수도있는 다른 사람들을 위해 여기에 답이 있습니다.

사용하다 adb shell dumpsys alarm

알람이 설정되었고 알람이 울릴 시간과 간격을 알 수 있습니다. 또한이 알람이 몇 번이나 호출되었는지도 확인하십시오.


리시버를 사용한 작업 예 (가장 좋은 대답은 조치입니다).

//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);

다른 해결책을 찾았습니다.

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

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

시도 해봐 ;)


여기에있는 거의 모든 사람이 정답을 제시했지만, 경보가 작동하는 근거에 대해서는 아무도 설명하지 않았습니다.

실제로 여기에서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


    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");

            }

이 작업을 수행 할 수있는 방법이 없다는 인상을 받으면 좋을 것입니다.

Alarm_last_set_time을 어딘가에 기록하고 On_boot_starter BroadcastReciever : BOOT_COMPLETED를 사용하면 비슷한 결과를 얻을 수 있습니다.

참고 URL : https://stackoverflow.com/questions/4556670/how-to-check-if-alarmmanager-already-has-an-alarm-set

반응형