Не удается остановить службу, запущенную с помощью AlarmManager

#android #service #location #alarmmanager

#Android #Обслуживание #Расположение #alarmmanager

Вопрос:

У меня возникли проблемы с отменой сигнала тревоги, и служба запустилась с ним.

Я установил будильник в activity:

 public class AlarmStarter extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);

      Intent locationPollerIntent = new Intent(this, LocationPoller.class);     
      PendingIntent pendingIntent = PendingIntent.getBroadcast
                (getApplicationContext(), REQUEST_CODE, locationPollerIntent, 0);

      alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
      alarmManager.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP,
                             SystemClock.elapsedRealtime(), 6000, pendingIntent);
    }
}
  

Намерение LocationPoller запустит службу для получения местоположения устройства.
Поэтому я использую AlarmManager для повторения этого поиска с определенной частотой.

После этого, когда я получаю свое местоположение в BroadcastReceiver, я вызываю другое действие, чтобы показать местоположение и отправить уведомление.

На данный момент я хотел бы прекратить поиск местоположения. Поэтому я пытаюсь отменить AlarmManager.

 public class Notifier extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.alarm_notifier);

        findViewById(R.id.btTurnOffAlarm).
                               setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) {
                Intent intentToStop = new Intent(this, LocationPoller.class);
                PendingIntent pendingIntentToStop = PendingIntent.getBroadcast 
                       (getApplicationContext(), REQUEST_CODE, intentToStop, 0);

                AlarmManager alarmManager = (AlarmManager)
                                getSystemService(ALARM_SERVICE);
                alarmManager.cancel(pendingIntentToStop);
            }
        });
    }
}
  

Но это не работает, он продолжает поиск местоположения.

Какие-либо подсказки?

Спасибо.

Ответ №1:

Вы должны сделать намерение уникальным.

что-то похожее на:

 locationPollerIntent.setData((Uri.parse("YOUR UNIQUE ID FOR THIS INTENT")));
  

AlarmManager проверит поле данных намерения при получении правильного сигнала тревоги для вас.
просто установите уникальный Uri для данных намерения.

итак, когда вы вернете свой будильник, сделайте что-нибудь вроде:

 intentToStop.setData((Uri.parse("YOUR SAME UNIQUE ID FOR THIS INTENT")));
  

после этого сигнал тревоги должен быть отменен.

Комментарии:

1. Вы стирали эмулятор перед каждым тестированием? Возможно, ваши предыдущие сигналы тревоги все еще извлекают местоположения. И убедитесь, что каждый сигнал тревоги использует уникальный идентификатор. Поэтому, если вы запускаете сигнал тревоги 5 раз, вам нужно 5 разных идентификаторов…. просто предположение…

Ответ №2:

REQUEST_CODE должно быть одинаковым в обоих местах; вы не показываете, где это определено в ваших списках кода.

Кроме того, вам здесь не нужно getApplicationContext() this будет работать просто отлично.

Комментарии:

1. Да, REQUEST_CODE тот же. Я хотел бы знать, если отменить сигнал тревоги, он должен остановить службу. Потому что после вызова AlarmManager.cancel() он продолжает поиск местоположения. Спасибо.

2. @blui: » Я хотел бы знать, если отменить сигнал тревоги, это должно остановить службу «. — нет. Все, что сделает отмена сигнала тревоги, это остановит ваш PendingIntent вызов.

Ответ №3:

Вы должны передать тот же экземпляр.

 public static final Uri MYURI = Uri.parse("Some_Uri");
[...]
locationPollerIntent.setData(MyClass.MYURI);
[...]
intentToStop.setData(MyClass.MYURI);
  

Если у вас есть две разные ссылки каждый раз, когда вы создаете намерение, это не сработает.

Более подробный пример здесь:

http://malubu.wordpress.com/2012/06/05/take-your-time-widgets-and-alarmmanager/

Комментарии:

1. У меня та же проблема, я создаю синглтон для намерения, но все равно не работает…

Ответ №4:

У меня была такая же проблема, речь идет не о том, чтобы иметь один и тот же экземпляр намерения «locationPollerIntent» и «intentToStop», но у вас должен быть один и тот же экземпляр для PendingIntent.

После остановки AlarmManager служба тоже останавливается.

     static PendingIntent instance;

public static PendingIntent getInstance(Context context) {

    if (instance == null)
    {
        Intent intent = new Intent(context, LocationPoller.class); 
        instance = PendingIntent.getService(context, REQUEST_CODE, intent, 0);
    }

    return instance;
}