如何在后台始终运行服务?

Tho*_*s H 73 android android-service background-thread

我正在创建一个类似于内置SMS应用程序的应用程序.

我需要的:

  • 始终在后台运行的服务
  • 每5分钟一次.该服务检查设备的当前位置并调用Web服务
  • 如果满足某些条件,服务应生成通知(就像SMS应用程序一样)
  • 单击通知时,用户将被带到应用程序(就像SMS应用程序一样)
  • 安装应用程序时,应启动该服务
  • 重启设备时,应启动该服务

我尝试过:
- 运行常规服务,直到Android杀死服务一直工作
- 使用AlarmManager进行5分钟.间隔呼叫服务.但我无法做到这一点.

Com*_*are 33

始终在后台运行的服务

正如您所发现的那样,这在任何真正意义上都是不可能的.这也是糟糕的设计.

每5分钟一次.该服务检查设备的当前位置并调用Web服务

使用AlarmManager.

使用AlarmManager进行5分钟.间隔呼叫服务.但我无法做到这一点.

这是一个示例项目,展示如何使用它,以及使用,WakefulIntentService以便您在尝试执行整个Web服务时保持清醒.

如果你继续遇到问题,请打开一个关于你遇到的具体事情的新问题,AlarmManager这会给你带来悲伤.

  • @SamirMangroliya:如果你看一下答案的日期,你会发现它已经超过3年了.此示例是为Android 2.x编写的,您需要重新启动设备/模拟器才能启动警报.现在,对于Android 3.1+,即使这还不够 - 你需要在on-boot接收器生效之前运行一个活动.我建议您切换到https://github.com/commonsguy/cw-omnibus/tree/master/AlarmManager/Wakeful这是一个相同的基本项目,但更新.运行它,确保活动运行(显示"Toast"),警报将开始. (2认同)

Jim*_*ler 26

我的一个应用程序做了非常相似的事情.我建议在一段时间后唤醒服务postDelayed()

有一个处理程序字段:

private final Handler handler = new Handler();
Run Code Online (Sandbox Code Playgroud)

和复习 Runnable

private final Runnable refresher = new Runnable() {
  public void run() {
    // some action
  }
};
Run Code Online (Sandbox Code Playgroud)

您可以在runnable中触发通知.

在服务构建上,每次执行后都会这样开始:

handler.postDelayed(refresher, /* some delay in ms*/);
Run Code Online (Sandbox Code Playgroud)

onDestroy()删除帖子

handler.removeCallbacks(refresher);
Run Code Online (Sandbox Code Playgroud)

要在启动时启动服务,您需要一个自动启动器.这就在你的清单中

<receiver android:name="com.example.ServiceAutoStarter">
        <intent-filter>
            <action android:name="android.intent.action.BOOT_COMPLETED" />
        </intent-filter>
  </receiver>
Run Code Online (Sandbox Code Playgroud)

ServiceAutoStarter看起来像这样:

public class ServiceAutoStarter extends BroadcastReceiver {
  @Override
  public void onReceive(Context context, Intent intent) {
    context.startService(new Intent(context, UpdateService.class));
  }
}
Run Code Online (Sandbox Code Playgroud)

停止操作系统杀死服务非常棘手.你的应用程序也可以RuntimeException崩溃,或者你的逻辑可以停止.

在我的情况下,似乎总是有助于在屏幕上刷新服务BroadcastReceiver.因此,如果更新链停滞不前,它将在用户使用手机时重新启动.

在服务中:

private BroadcastReceiver screenOnReceiver; 
Run Code Online (Sandbox Code Playgroud)

在您的服务中 onCreate()

screenOnReceiver = new BroadcastReceiver() {

  @Override
  public void onReceive(Context context, Intent intent) {
    // Some action
  }
};

registerReceiver(screenOnReceiver, new IntentFilter(Intent.ACTION_SCREEN_ON));
Run Code Online (Sandbox Code Playgroud)

然后在注销你的服务onDestroy()

unregisterReceiver(screenOnReceiver);
Run Code Online (Sandbox Code Playgroud)

  • 感谢CWare,我应该更清楚地了解复活器是为了防止逻辑故障以及可以阻止唤醒服务的事件链的许多事情,因为系统关闭服务的原因往往是其他东西.我将研究一下警报管理器的方法,我模糊地回忆起前一段时间尝试这种方法而无法让它工作. (4认同)
  • 我通常喜欢您的答案,但是这个答案...不是很多。:-(例如,您建议该服务注册一个接收方,使其在被杀死后可以自行恢复。该接收方将与该服务一起被杀死;因此,这应该没有效果。而且,永久性服务的整个概念太糟糕了在Android上,这是用户在设置应用程序中使用任务杀手或“运行服务”屏幕进行反击的原因。在极少数情况下,需要真正持久的服务-在大多数情况下,“ AlarmManager”就足够了。 (2认同)