Подтвердить что ты не робот

Андроид отменяется после закрытия приложения

У меня проблема с 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);
}

Спасибо!

4b9b3361

Ответ 1

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

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

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

Ответ 2

Я считаю, что @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 вызывается, даже если я принудительно закрываю приложение из оболочки.

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

Ответ 3

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

Ответ 4

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

Этот question также может быть полезен.

Ответ 5

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

Ответ 6

Добавить

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

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

Ответ 7

Я смог сделать именно то, что вам нужно. Даже если вы остановите приложение на текущей вкладке в инструменте диспетчера приложений, служба перезагрузится. Единственный способ убить его - это нажать кнопку остановки, расположенную рядом с опцией 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>