Сигнализация Android отменяется после закрытия приложения - PullRequest
22 голосов
/ 10 января 2011

У меня проблема с AlarmManager, я установил код для планирования повторяющегося сигнала и после запуска приложения сигнал работает нормально.Даже если я нажму кнопку «Домой» (и приложение будет приостановлено), сигнал тревоги все равно будет работать с интервалом.

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

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

Код ниже - метод вызывается классом ApplicationContext,onCreate ().

 private void scheduleAlarm() {
  if (alarmScheduled == true) { return; } // we only need to schedule once.

  int alarmInterval = Def.pref(getApplicationContext()).getInt("alarmInterval", 30);

  final Intent intent = new Intent(getApplicationContext(), CollectorAlarmReceiver.class);
  final PendingIntent pending = PendingIntent.getBroadcast(getApplicationContext(), 0, intent, 0);

  AlarmManager alarmMgr = (AlarmManager) getApplicationContext().getSystemService(Context.ALARM_SERVICE);

  alarmMgr.cancel(pending); // cancel others.

  alarmMgr.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis()+1000,
    alarmInterval*1000, pending);

  Def.log(TAG,"scheduleAlarm(): alarm scheduled, interval: "+alarmInterval+" seconds");
  alarmScheduled = true;
 }

Код получателя:

public void onReceive(Context context, Intent intent) {
    Log.i(TAG, "CollectorAlarmReceiver invoked, starting CollectorService in background");

    context.startService(new Intent(context, CollectorService.class));

    Intent collectorService = new Intent(context,CollectorService.class);
    collectorService.putExtra("action", CollectorService.ACTION_BACKGROUND_REQUEST_MESSAGES);

    context.sendBroadcast(collectorService);
}

Спасибо!

Ответы [ 7 ]

9 голосов
/ 10 января 2011

Это нормальное поведение. Если пользователь добровольно принудительно остановит приложение, то оно должно быть остановлено. Иначе, вы создаете вирусоподобное приложение.

Если вы действительно хотите, вы можете написать другую службу, которая отслеживает, работает ли другая ваша служба, и запускает службу, если она не запущена. Но это будет другое приложение, и (вы надеетесь) пользователь не убьет это приложение с помощью диспетчера задач.

Лично я бы не волновался. Если пользователь остановил это, они хотели остановить это. Не раздражайте пользователя.

8 голосов
/ 04 января 2014

Я думаю, @GSree не так. Есть простой способ добиться этого. Просто используйте настраиваемое действие. Вот как это сделать:

Сначала определите имя настраиваемого действия, например:

public static final String MY_ACTION = "com.sample.myaction"

Затем создайте BroadcastReceiver:

public class MyAlarmReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        if (intent.getAction().equals(MY_ACTION)) {
            // Do something here
        }
    }    
}

Зарегистрируйте получателя на вашем AndroidManifest.xml:

<receiver android:name="com.sample.MyAlarmReceiver">
    <intent-filter>
        <action android:name="com.sample.myaction"/>
    </intent-filter>
</receiver>

Затем для настройки будильника используйте следующее PendingIntent:

Intent i = new Intent(MY_ACTION);
PendingIntent pi = PendingIntent.getBroadcast(getApplicationContext(), 0, i, 0);

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

Обратите внимание, что это решение не требует от вас создания службы.

2 голосов
/ 29 августа 2016

Это нормальное поведение! Будильник перестанет работать, когда ваше приложение перейдет в onDestroy ().

1 голос
/ 08 марта 2014

Я делал это несколько раз, но удивляюсь, почему вы назначаете requestCode 0; Я бы подумал, что присвоение вашей тревоги уникального номера очень помогло бы.

0 голосов
/ 01 января 2016

Добавить

<receiver android:name=".AlarmReceiver" android:process=":remote" />

в файл манифеста.Будильник сработает, даже если приложение убито.

0 голосов
/ 22 августа 2013

Я смог сделать именно то, что вам нужно.Даже если вы остановите приложение через вкладку «Выполнение» в диспетчере приложений, служба перезапустится сама.Единственный способ убить его - воспользоваться кнопкой принудительной остановки рядом с опцией unistall в диспетчере приложений.В основном вы звоните в Службу напрямую.Вот мой код:

public class TestService extends Service {

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
        Toast.makeText(this, "Ejecutando Servicio ...", Toast.LENGTH_SHORT).show();
    return Service.START_NOT_STICKY;    
    }

@Override
    public void onCreate() {
      super.onCreate();
      Toast.makeText(this, "Iniciando Servicio ...", Toast.LENGTH_SHORT).show();
}

    @Override
    public void onDestroy() {
      super.onDestroy();
      Toast.makeText(this, "Deteniendo Servicio ...", Toast.LENGTH_SHORT).show();
}   

На клиентской активности напишите следующий код:

            Calendar cal = Calendar.getInstance();
        Intent intent = new Intent(this,TestService.class);
        PendingIntent pIntent = PendingIntent.getService(this.getApplicationContext(), 0, intent, 0);
        alarm=  (AlarmManager) getSystemService(Context.ALARM_SERVICE);
        alarm.setRepeating(AlarmManager.RTC_WAKEUP,cal.getTimeInMillis(), 3*1000, pIntent);

и объявите службу в манифесте:

        <service
      android:name="TestService"
      android:icon="@drawable/ic_launcher"
      android:label="TestService"
      >
    </service>         
0 голосов
/ 10 января 2011

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

Этот вопрос также может помочь.

...