用户关闭应用程序时服务不会停止

时间:2018-07-31 16:10:19

标签: java android android-service alarmmanager

因此,我试图使alarmManager每60秒运行一次,这将对服务器运行http请求。我希望服务在应用程序打开时运行,并且在屏幕关闭(休眠)时仍可以运行。

如果用户在最近的应用程序菜单下将应用程序滑开,我希望该服务停止/取消。

Service.onDestroy方法只运行一半的时间,而Alarm.onReceive方法将永远运行(每60秒),即使应用已关闭。

呼叫Alarm.cancelAlarm不会进行任何更改。

我想念什么?

AndroidManifest:

<receiver android:process=":remote" android:name=".objects.Alarm"></receiver>
    <service
        android:name=".objects.Service"
        android:enabled="true"
        android:process=":your_service"
        android:stopWithTask="true">
    </service>

主要活动:

@Override
protected void onCreate(Bundle savedInstanceState) {
    startService(new Intent(LaunchActivity.this, Service.class));
}

服务:

public class Service extends android.app.Service {
    @Override
    public int onStartCommand(Intent intent, int flags, int startId)
    {
        alarm.setAlarm(this);
        return START_NOT_STICKY;
    }

    @Override
    public void onDestroy(){
        alarm.cancelAlarm(this);
    }
}

BroadcastReceiver:

public class Alarm extends BroadcastReceiver {

    public void onReceive(Context context, Intent intent) {
        Log.d("mytag","trigger update");
    }

    public void setAlarm(Context context)
    {
        AlarmManager am =( AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
        Intent i = new Intent(context, Alarm.class);
        PendingIntent pi = PendingIntent.getBroadcast(context, 0, i, PendingIntent.FLAG_UPDATE_CURRENT);
        am.setRepeating(AlarmManager.RTC, System.currentTimeMillis(), 60000, pi);
    }

    public void cancelAlarm(Context context)
    {
        AlarmManager am = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
        Intent myIntent = new Intent(context, Alarm.class);
        PendingIntent pendingIntent = PendingIntent.getBroadcast(
                context, 0, myIntent,
                PendingIntent.FLAG_UPDATE_CURRENT);

        am.cancel(pendingIntent);
    }
}

3 个答案:

答案 0 :(得分:1)

您正在创建在单独的线程上运行的接收器服务。删除android:process =“ XX”并使用START_STICKY。

如果您使用JobService而不是Service / Receiver组合会更简单。

尝试类似的操作:

<service android:name=".services.AlarmService">
      <intent-filter>
        <action android:name="com.firebase.jobdispatcher.ACTION_EXECUTE"/>
      </intent-filter>
    </service>

-

AlarmService.schedule(this,XXXX);

-

public class AlarmService extends JobService {

  private static String TAG = "AlarmService";

  public static void schedule(Context context, int minutes) {
    FirebaseJobDispatcher dispatcher = new FirebaseJobDispatcher(new GooglePlayDriver(context));
    Job myJob = dispatcher.newJobBuilder()
        .setService(SubscriptionAlarmService.class) // the JobService that will be called
        .setTag(TAG)        // uniquely identifies the job
        .setRecurring(true)
        .setReplaceCurrent(true)
        .setTrigger(Trigger.executionWindow(minutes * 60,(minutes * 60) + 10))
        .setLifetime(Lifetime.UNTIL_NEXT_BOOT)
        .setRetryStrategy(RetryStrategy.DEFAULT_EXPONENTIAL)
        .setConstraints(Constraint.ON_ANY_NETWORK)
        .build();
    dispatcher.mustSchedule(myJob);
  }

  public static void CancelAlarm(Context context) {
    FirebaseJobDispatcher dispatcher = new FirebaseJobDispatcher(new GooglePlayDriver(context));
    dispatcher.cancel(TAG);
  }

  public void run() {
    //DO STUFF HERE
  }

  @Override
  public boolean onStartJob(JobParameters job) {
    run();
    return false;
  }

  @Override
  public boolean onStopJob(JobParameters job) {
    return false;
  }
}

答案 1 :(得分:0)

使用START_STICKY代替START_NOT_STICKY

答案 2 :(得分:0)

也许不是最好的方法,但是经过测试,它似乎对我有用。

当应用关闭时,onStartCommand再次运行并重新启动服务,但是意图是null,所以如果意图是null,我只是取消警报。

在我的服务班级:

   @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        if (intent == null) {
            alarm.cancelAlarm(this);
        } else {
            alarm.setAlarm(this);
        }
        return START_STICKY;
    }