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

Java 当用户关闭应用程序时,服务不会停止,java,android,android-service,alarmmanager,Java,Android,Android Service,Alarmmanager,因此,我试图让alarmManager每60秒运行一次,这将运行对服务器的http请求。我希望该服务在应用程序打开时运行,并且在屏幕关闭睡眠时仍然运行 如果用户在“最近使用的应用”菜单下刷走应用,我希望服务停止/取消 Service.onDestroy方法的运行时间只有它看起来的一半,Alarm.onReceive方法将永远每60秒运行一次,即使应用程序已关闭 调用Alarm.cancelAlarm不会进行任何更改 我错过了什么 AndroidManifest: <receiver and

因此,我试图让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>
服务:

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);
    }
}
广播接收机:

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

使用START\u STICKY而不是START\u NOT\u STICKY

您正在创建一个在单独线程上运行的接收方服务。删除android:process=XX并使用START\u STICKY

如果使用JobService而不是Service/Receiver的组合,那么就更简单了

试着这样做:

-


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

当应用程序在启动时关闭时,命令再次运行并重新启动服务,但intent为null,因此如果intent为null,我将取消警报

在我的服务课上:

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

我不认为FirebaseJobDispatcher对我有任何好处,因为在Android上,24+ScheduledJobs在设备处于睡眠模式时无法执行,这可能会延迟15分钟,我最多需要2分钟。删除android:process=XX也没有停止这个过程,但我想我已经找到了一个答案,现在我将发布这个答案。
<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;
  }
}
   @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        if (intent == null) {
            alarm.cancelAlarm(this);
        } else {
            alarm.setAlarm(this);
        }
        return START_STICKY;
    }