340

当设备在 android 上启动时,我一直在尝试启动服务,但我无法让它工作。我在网上查看了许多链接,但没有一个代码有效。我是不是忘记了什么?

AndroidManifest.xml

<receiver
    android:name=".StartServiceAtBootReceiver"
    android:enabled="true"
    android:exported="false"
    android:label="StartServiceAtBootReceiver" >
    <intent-filter>
        <action android:name="android.intent.action._BOOT_COMPLETED" />
    </intent-filter>
</receiver>

<service
    android:name="com.test.RunService"
    android:enabled="true" />

广播接收器

public void onReceive(Context context, Intent intent) {
    if ("android.intent.action.BOOT_COMPLETED".equals(intent.getAction())) {
        Intent serviceLauncher = new Intent(context, RunService.class);
        context.startService(serviceLauncher);
        Log.v("TEST", "Service loaded at start");
    }
}
4

16 回答 16

608

其他答案看起来不错,但我想我会将所有内容都打包成一个完整的答案。

您的AndroidManifest.xml文件中需要以下内容:

  1. 在你的<manifest>元素中:

    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
    
  2. 在您的<application>元素中(请务必为您的 使用完全限定的[或相对]类名BroadcastReceiver):

    <receiver android:name="com.example.MyBroadcastReceiver">  
        <intent-filter>  
            <action android:name="android.intent.action.BOOT_COMPLETED" />  
        </intent-filter>  
    </receiver>
    

    (您不需要android:enabled,exported等属性:Android 默认值是正确的)

    MyBroadcastReceiver.java

    package com.example;
    
    public class MyBroadcastReceiver extends BroadcastReceiver {
        @Override
        public void onReceive(Context context, Intent intent) {
            Intent startServiceIntent = new Intent(context, MyService.class);
            context.startService(startServiceIntent);
        }
    }
    

从原来的问题:

  • 不清楚<receiver>元素是否在<application>元素中
  • 不清楚是否指定了正确的完全限定(或相对)类BroadcastReceiver
  • 有一个错字<intent-filter>
于 2011-03-25T23:55:48.213 回答
85

作为附加信息:在挂载外部存储之前将 BOOT_COMPLETE 发送到应用程序。因此,如果应用程序安装到外部存储,它将不会收到 BOOT_COMPLETE 广播消息。

更多细节广播接收器部分监听“启动完成”

于 2010-11-22T13:59:39.760 回答
70

如何在设备启动时启动服务(自动运行应用程序等)

首先:从 Android 3.1+ 版本开始,如果用户从未启动过您的应用程序至少一次或用户“强制关闭”应用程序,您不会收到 BOOT_COMPLETE。这样做是为了防止恶意软件自动注册服务。此安全漏洞已在较新版本的 Android 中关闭。

解决方案:

使用活动创建应用程序。当用户运行它一次应用程序可以接收 BOOT_COMPLETE 广播消息。

第二:在挂载外部存储之前发送 BOOT_COMPLETE。如果应用程序安装到外部存储,它将不会收到 BOOT_COMPLETE 广播消息。

在这种情况下,有两种解决方案:

  1. 将您的应用安装到内部存储
  2. 在内部存储中安装另一个小应用程序。此应用程序接收 BOOT_COMPLETE 并在外部存储上运行第二个应用程序。

如果您的应用程序已经安装在内部存储中,那么下面的代码可以帮助您了解如何在设备启动时启动服务。


在 Manifest.xml 中

允许:

<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />

注册您的 BOOT_COMPLETED 接收器:

<receiver android:name="org.yourapp.OnBoot">
    <intent-filter>
        <action android:name="android.intent.action.BOOT_COMPLETED"/>
    </intent-filter>
</receiver>

注册您的服务:

<service android:name="org.yourapp.YourCoolService" />

在接收器 OnBoot.java 中:

public class OnBoot extends BroadcastReceiver
{

    @Override
    public void onReceive(Context context, Intent intent) 
    {
        // Create Intent
        Intent serviceIntent = new Intent(context, YourCoolService.class);
        // Start service
        context.startService(serviceIntent);

    }

 }

对于 HTC,如果设备未捕获 RECEIVE_BOOT_COMPLETED,您可能还需要在清单中添加此代码:

<action android:name="android.intent.action.QUICKBOOT_POWERON" />

接收器现在看起来像这样:

<receiver android:name="org.yourapp.OnBoot">
    <intent-filter>
        <action android:name="android.intent.action.BOOT_COMPLETED"/>
        <action android:name="android.intent.action.QUICKBOOT_POWERON" />
    </intent-filter>
</receiver>

如何在不重启模拟器或真实设备的情况下测试 BOOT_COMPLETED?这很简单。尝试这个:

adb -s device-or-emulator-id shell am broadcast -a android.intent.action.BOOT_COMPLETED

如何获取设备ID?获取具有 id 的已连接设备列表:

adb devices

默认情况下,ADT 中的 adb 可以在以下位置找到:

adt-installation-dir/sdk/platform-tools

享受!)

于 2014-09-24T21:04:50.707 回答
34

随着

<action android:name="android.intent.action.BOOT_COMPLETED" />  

也使用,

<action android:name="android.intent.action.QUICKBOOT_POWERON" />

HTC 设备似乎没有捕捉到 BOOT_COMPLETED

于 2013-05-14T11:52:10.877 回答
20

请注意,在问题的开头,有一个拼写错误:

<action android:name="android.intent.action._BOOT_COMPLETED"/>

代替 :

<action android:name="android.intent.action.BOOT_COMPLETED"/>

一个小“_”和所有这些麻烦:)

于 2011-02-05T09:19:05.857 回答
13

我刚刚发现这可能是Fast Boot因为Settings>Power

当我关闭此选项时,我的应用程序会收到此广播,但不会收到其他广播。

顺便说一句,我有Android 2.3.3HTC Incredible S

希望能帮助到你。

于 2012-01-11T20:21:57.213 回答
13

我认为您的清单需要添加:

<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
于 2010-05-06T21:14:42.977 回答
7

在尝试了所有提到的答案和技巧之后,我终于找到了为什么代码在我的手机中不起作用。部分安卓手机如“华为荣耀3C安卓4.2.2 ”在设置中有Statup Manager菜单,您的应用必须在列表中勾选。:)

于 2015-09-06T19:20:27.463 回答
5

我有一个额外的<category>-tag,不知道这是否有什么不同。

<receiver android:name="BootIntentReceiver">  
        <intent-filter>  
            <action android:name="android.intent.action.BOOT_COMPLETED" />  
            <category android:name="android.intent.category.HOME" />  
        </intent-filter>  
</receiver>

您是否尝试过省略 if-clause "android.intent.action.BOOT_COMPLETED".equals(intent.getAction(),因为接收者可能只会收到该意图?

于 2010-05-06T21:12:18.113 回答
5

这就是我所做的

1.我做了Receiver类

public class BootReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        //whatever you want to do on boot
       Intent serviceIntent = new Intent(context, YourService.class);
       context.startService(serviceIntent);
    }
}

2.在清单中

<manifest...>
    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
    <application...>
        <receiver android:name=".BootReceiver" android:enabled="true" android:exported="false">
            <intent-filter>
                <action android:name="android.intent.action.BOOT_COMPLETED" />
            </intent-filter>
        </receiver>
    ...

3.毕竟你需要在你的MainActivity中“设置”接收器,它可能在onCreate里面

...
 final ComponentName onBootReceiver = new ComponentName(getApplication().getPackageName(), BootReceiver.class.getName());
        if(getPackageManager().getComponentEnabledSetting(onBootReceiver) != PackageManager.COMPONENT_ENABLED_STATE_ENABLED)
        getPackageManager().setComponentEnabledSetting(onBootReceiver,PackageManager.COMPONENT_ENABLED_STATE_ENABLED,PackageManager.DONT_KILL_APP);
...

我从 ApiDemos 学到的最后一步

于 2017-10-24T21:14:57.360 回答
4

请参阅此链接http://khurramitdeveloper.blogspot.in/2013/06/start-activity-or-service-on-boot.html 逐步过程以在服务上使用引导

于 2014-02-17T04:24:14.900 回答
3

在安装外部存储之前发送 BOOT_COMPLETE 执行。如果您的应用程序安装到外部存储,它将不会收到 BOOT_COMPLETE 广播消息。为了防止这种情况,您可以将应用程序安装在内部存储中。您只需在 menifest.xml 中添加此行即可

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
android:installLocation="internalOnly"
... >

一些 HTC 设备可以启用“快速启动”功能,该功能更像是深度休眠而不是真正的重启,因此不应给出 BOOT_COMPLETE 意图。要恢复它,您可以在接收器中添加此意图过滤器:

            <intent-filter>
                <action android:name="android.intent.action.BOOT_COMPLETED" />
                <action android:name="android.intent.action.QUICKBOOT_POWERON" />
            </intent-filter>
于 2015-10-04T20:31:26.743 回答
2

如果您使用的是 Android Studio 并且非常喜欢自动完成,那么我必须通知您,我使用的是 Android Studio v 1.1.0,并且我使用自动完成来获得以下权限

<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />

RECEIVE_BOOT_COMPLETEDAndroid Studio以小写形式自动完成receive_boot_completed,我一直在拔头发,因为我已经勾选了我的清单,以便在启动时启动服务。我刚刚再次确认

Android Studio 会以小写形式自动完成此权限。

于 2015-03-19T12:21:43.127 回答
2

正如@Damian 评论的那样,这个线程中的所有答案都做错了。像这样手动执行此操作可能会导致您的服务因设备进入睡眠状态而在中间停止。您需要先获得唤醒锁。幸运的是,Support 库为我们提供了一个类来执行此操作:

public class SimpleWakefulReceiver extends WakefulBroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        // This is the Intent to deliver to our service.
        Intent service = new Intent(context, SimpleWakefulService.class);

        // Start the service, keeping the device awake while it is launching.
        Log.i("SimpleWakefulReceiver", "Starting service @ " + SystemClock.elapsedRealtime());
        startWakefulService(context, service);
    }
}

然后,在您的服务中,确保释放唤醒锁:

    @Override
    protected void onHandleIntent(Intent intent) {
        // At this point SimpleWakefulReceiver is still holding a wake lock
        // for us.  We can do whatever we need to here and then tell it that
        // it can release the wakelock.

...
        Log.i("SimpleWakefulReceiver", "Completed service @ " + SystemClock.elapsedRealtime());
        SimpleWakefulReceiver.completeWakefulIntent(intent);
    }

不要忘记将 WAKE_LOCK 权限添加到您的 mainfest:

<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
于 2015-06-21T22:50:20.837 回答
1

事实上,我不久前就遇到了这个问题,而且它真的很容易解决,如果你设置了"android.intent.action.BOOT_COMPLETED"权限和意图过滤器,你实际上并没有做错任何事情。

请注意,如果您在 Android 4.X 上,您必须在启动服务之前运行广播侦听器,这意味着,您必须先添加一个活动,一旦您的广播接收器运行,您的应用程序应该按预期运行,但是,在 Android 4.X 上,我还没有找到一种在没有任何活动的情况下启动服务的方法,我认为谷歌是出于安全原因这样做的。

于 2013-08-20T14:35:18.660 回答
0

如果我将空构造函数留在接收器类中,我会遇到这个问题。删除空的构造函数后,onRreceive 方法开始正常工作。

于 2014-12-29T14:34:59.863 回答