有什么方法可以在android中连续运行服务吗?

时间:2019-01-28 10:01:26

标签: android android-service background-process periodic-task

在StackOverFlow上几乎没有与此类似的问题,但是没有一个解决方案对我有用

问题

问题是只有OnePlus和MI这样的设备很少,一旦用户从最近的应用程序中删除了应用程序,该服务就会被终止。

我读到这些OEM厂商采取了一些激进的策略来杀死服务。我只想知道有什么方法可以保持服务运行或在服务被杀死时立即启动它。

我想要的

我需要运行将在后台连续提供位置(24/7)的服务(此应用仅适用于特定人群,因此无需担心电池寿命)。

到目前为止我尝试过的事情:

1)尝试运行前台服务。

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        startForegroundService(intent)
     } else {
            startService(intent)
     }

也在服务中以通知开头的onCreate方法

@Override
public void onCreate() {
    Log.i("Service", "onCreate");
    startForeground(NOTIFICATION_ID, getnotification());
 }

2)尝试返回START_STICKY中的onStartCommand

 @Override
 public int onStartCommand(Intent intent, int flags, int startId) {

    initLocationClient();
    initLocationSyncThread();

    return START_STICKY;
}

3)试图在onDestroyonTaskRemoved中重新启动服务,但是没有被调用。

4)试图绑定服务

5)我可以安排警报管理器并经常启动服务,但play store会警告我们的应用程序使用警报管理器的频率过高,这是一种不良做法。现在,有一种方法可以使用Workmanager来计划少于15分钟的时间,并且仍然不能保证在15分钟之后开始。

除了上述选项之外,还有什么方法可以继续运行服务吗?

3 个答案:

答案 0 :(得分:2)

如果您通过THE LINK,则会发现:

  

不幸的是,某些设备实施了从“最近”菜单中杀死应用程序的强制停止操作。 Stock Android不会执行此操作。当应用程序被强制停止时,它无法执行作业,接收警报或广播等。因此,不幸的是,我们无法解决这个问题-问题出在操作系统上,没有解决方法。

这是一个已知问题。为了节省电池,许多制造商强行关闭了该应用程序,从而取消了所有定期任务,警报和广播接收等。主要制造商为OnePlus(您可以选择切换),Redmi,Vivo,Oppo,Huwaei。

这些设备中的每一个都具有优化管理器的AutoStartManagers / AutoLaunch / StartManager类型。这会阻止后台活动再次开始。您将必须手动要求用户将您的应用程序列入白名单,以便该应用程序可以自动启动其后台进程。点击THISTHIS链接,了解更多信息。

要添加到不同制造商白名单的方法,请参见this stackoverflow answer。即使添加到白名单之后,您的应用也可能由于“打ZE模式”而无法正常运行,因为您必须ignore battery otimizations

如果您可能想知道,这些自动启动管理器已经将Gmail / Hangout / WhatsApp / Slack / LinkedIn等应用列入了白名单。因此,对其背景过程没有影响。您总是会及时收到更新和通知。

答案 1 :(得分:1)

以下几件事没有多大帮助。

在AndroidManifest.xml中添加行android:enabled="true"

<service
      android:name=".service.TrackingService"
      android:exported="false"
      android:enabled="true"
    />

内部服务添加警报以在2秒后再次唤醒。

@Override
public void onTaskRemoved(Intent rootIntent) {
    initAlarm();
    super.onTaskRemoved(rootIntent);
}

   private void initAlarm() {
    AlarmManager alarmMgr = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
    Intent intent = new Intent(this, StartServiceReceiver.class);
    PendingIntent alarmIntent = PendingIntent.getBroadcast(this, 0, intent, 0);

    alarmMgr.set(AlarmManager.ELAPSED_REALTIME_WAKEUP,
            SystemClock.elapsedRealtime() +
                    2000, alarmIntent);

}

创建接收方StartServiceReceiver,然后在其中重新启动服务。

对于Mi设备,我们需要允许在内部设置权限,以允许服务在后台启动

答案 2 :(得分:0)

在播放服务中使用融合位置API的背景上侦听位置的正确方法。

在这里查看示例。 https://github.com/googlesamples/android-play-location?files=1

这些API具有较高的能效,我也推荐使用。