如何启动仅服务的Android应用程序

53
我正在创建一个应用程序,其唯一的组件是在后台持续运行(基本上是代理服务器)的服务,但我无法找到启动该服务的方法。应用程序不能有任何UI或用户交互,因此我没有使用Activity。
广播接收器可以监听BOOT广播,但我如何在第一次安装时启动服务并如何使其保持运行状态? 还是有一个广播可以在应用程序安装后侦听,例如TIME_TICK,但我认为必须从Activity注册。

1
我自己没有尝试过,但可以从Application对象启动一个服务吗? - phreed
我认为它可以工作 http://android-codes-examples.blogspot.com/2011/11/running-service-in-background-on.html - Android
3个回答

45

很遗憾,目前还没有可靠的方法可以在应用程序安装后接收广播事件,ACTION_PACKAGE_ADDED Intent 不会广播给新安装的包。

您需要一个广播接收器类和您的服务才能接收ACTION_BOOT_COMPLETED事件。 我还建议将ACTION_USER_PRESENT意图添加到该广播接收器中捕获,这需要Android 1.5(minSDK = 3),这将在用户解锁其手机时调用您的广播接收器。 最后一件事是尝试使您的服务保持运行状态而不易被自动关闭,可以在服务 onCreate 时调用Service.setForeground()来告诉Android不要停止您的服务,这主要是为了需要持续运行但可以被任何服务使用的mp3播放器类型服务而添加的。

确保在清单文件中添加适当的权限以获取boot_complete和user_present事件。

下面是一个简单的类,您可以将其用作事件的广播接收器。

package com.snctln.util.WeatherStatus;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;

public class WeatherStatusServiceReceiver extends BroadcastReceiver
{
    @Override
    public void onReceive(Context context, Intent intent)
    {
        if(intent.getAction() != null)
        {
            if(intent.getAction().equals(Intent.ACTION_BOOT_COMPLETED) ||
                intent.getAction().equals(Intent.ACTION_USER_PRESENT))
            {
                context.startService(new Intent(context, WeatherStatusService.class));
            }
        }
    }
};

祝你好运。


7
好的建议。关于Service.setForeground():它在Android 2.0及以上版本中已不再起作用。所有“长期运行”的服务现在需要在通知区域中具有持久通知,以便在运行时显示。示例在这里:http://developer.android.com/resources/samples/ApiDemos/src/com/example/android/apis/app/ForegroundService.html - Jarett Millard
2
ACTION_USER_PRESENT 是一个很棒的提示。我一直在苦苦挣扎,想让我的服务保持活跃状态,而这个提示解决了我的问题。 - defrex
5
发现从3.0版本开始,需要至少启动一次应用程序才能启用其意图-很奇怪,但对我有效。这意味着,必须创建一个小活动(例如带有介绍性内容),在安装后启动该活动。之后,您将正确接收到意图。 - ubuntudroid
这个有记录在UbuntuDroid上吗? - Archimedes Trajano
3
@ArchimedesTrajano 我知道这个问题很老,但它是谷歌上的第一个结果。这里有一些文档[http://developer.android.com/about/versions/android-3.1.html#launchcontrols]和一个很好的解释[http://commonsware.com/blog/2011/07/13/boot-completed-regression-confirmed.html]。 - jpalm

16

Service.onStartCommand 中返回 START_STICKY

Android 将会重新启动你的服务。


2
START_STICKY 仅适用于 Android 2.0 及以上版本。 - cow
但是服务至少要运行一次才能确保连续性,对吗? - diyoda_

1
我正在研究同样的问题。这是我找到的内容:
http://kfb-android.blogspot.de/2009/04/registering-for-timetick-after-reboot.html
这个简单的演示展示了一种解决方案,通过在广播接收器和服务之间来回传递信息。广播接收器在清单中注册以接收ACTION_BOOT_COMPLETED,从而在启动时启动服务。然后,服务为ACTION_TIME_TICK注册广播接收器。应用逻辑将在BroadcastReceiver中实现。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接