34

我知道这个问题在网站上被问了很多,但是,我似乎找不到解决方案。当应用程序未运行时,不会调用我的 BOOT_COMPLETED 接收器。

显现:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.startuptest"
    android:versionCode="1"
    android:versionName="1.0"
    android:installLocation="internalOnly">
    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
    <uses-sdk android:minSdkVersion="8" android:targetSdkVersion="17" />

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name="com.example.startuptest.MainActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

        <receiver android:name="com.example.startuptest.StartUpBootReceiver" >
            <intent-filter>
                <action android:name="android.intent.action.BOOT_COMPLETED" />
            </intent-filter>
        </receiver>
    </application>
</manifest>

启动引导接收器:

public class StartUpBootReceiver  extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {

        Log.d("startuptest", "StartUpBootReceiver " + intent.getAction());

        if ("android.intent.action.BOOT_COMPLETED".equals(intent.getAction())) {
            Log.d("startuptest", "StartUpBootReceiver BOOT_COMPLETED");
        }
    }
}

如果应用程序正在运行并且我用

adb shell
am broadcast -a android.intent.action.BOOT_COMPLETED

事件被正确接收,但是,如果应用程序关闭,则事件不会被接收,也不会在启动时被接收。

我已经安装了该应用程序,然后启动了几次以确保它已注册。我对这个很迷茫,所以任何建议都会受到高度赞赏。

编辑:我可以在日志中看到所有其他关闭的应用程序(Youtube、FileObserver 等)都收到了 boot_completed 事件,而不是我的。

4

9 回答 9

107

Android 3.1开始,所有应用程序在安装后都处于“停止”状态。(这与用户从“设置”应用程序强制停止应用程序后应用程序最终处于的状态相同。)

Android 停止状态

当处于“停止”状态时,应用程序不会因任何原因运行,除非手动启动活动。(意味着无论他们注册的事件如何,都不会调用BroadcastReceviersACTION_PACKAGE_INSTALLED等),直到用户手动运行应用程序。)BOOT_COMPLETED

这是谷歌的反恶意软件举措。谷歌提倡用户应该先从启动器启动一个活动,然后该应用程序才能做很多事情。在活动启动之前阻止BOOT_COMPLETED交付是该论点的逻辑结果。

有关此的更多详细信息:http:
//developer.android.com/about/versions/android-3.1.html#launchcontrols
http://commonsware.com/blog/2011/07/05/boot-completed-regression.html
http ://devmaze.wordpress.com/2011/12/05/activating-applications/

于 2013-11-08T10:08:40.403 回答
41

我在 BOOT_COMPLETED 时启动我的应用程序,所以我知道它正在工作。我添加Log.d它不会显示。我添加Toast它显示。Manifest.xml 中的小差异

<receiver android:name="com.example.startuptest.StartUpBootReceiver">
    <intent-filter>
         <action android:name="android.intent.action.BOOT_COMPLETED" />
    </intent-filter>            
</receiver>
于 2013-06-21T07:51:24.890 回答
29

这里的每个答案都会添加一小部分信息,因此这里是所有内容的摘要:

为确保您将收到 BOOT_COMPLETED,请确保您执行以下操作:

  1. 将您的接收器添加到清单(不要忘记标志):

    <receiver android:name="com.yourpacakge.BootReceiver" android:exported="true" android:enabled="true">
        <intent-filter>
            <action android:name="android.intent.action.BOOT_COMPLETED"/>
            <category android:name="android.intent.category.DEFAULT"/>
        </intent-filter>
    </receiver>
    
  2. 添加权限:

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

  3. 安装您的应用程序后,它需要至少一次午餐,由用户手动接收,以便接收启动完成事件。(更多详细信息

于 2015-08-16T06:30:53.843 回答
2

正在努力解决同样的问题,原因是您使用Log.d在 logcat 中跟踪您的应用程序,不幸的是,当您重新启动手机时,应用程序正在接收BOOT_Complete但您看不到它,因为它没有记录到 logcat。

尝试Toast使用一些文本而不是Log.d确保是否收到 BOOT_COMPLETED 。

希望这个帮助。

于 2013-06-21T05:41:31.130 回答
2

如果你们想要的话,这里有一个C#版本。我的测试表明它工作得非常完美,而且启动速度非常快。虽然请注意在C#AndroidManifest.xml中添加它会破坏它(至少对我而言)。

我还添加了一些不错且有用的示例,我希望我从某人那里找到,而不是在阅读纪录片等时自己学习。

[BroadcastReceiver(Enabled = true, Exported = true, DirectBootAware = true, Name = "com.nevaran.startup.StartUpBootReceiver")]
[IntentFilter(new string[] {
    Intent.ActionBootCompleted
    , Intent.ActionLockedBootCompleted
    , Intent.ActionMyPackageReplaced
    , Intent.ActionUserInitialize
    , "android.intent.action.QUICKBOOT_POWERON"
    , "com.htc.intent.action.QUICKBOOT_POWERON"
})]
public class BootReceiver : BroadcastReceiver
{
    public override void OnReceive(Context context, Intent intent)
    {
         if(    intent.Action.Equals(Intent.ActionBootCompleted)
             || intent.Action.Equals(Intent.ActionLockedBootCompleted)
             || intent.Action.Equals(Intent.ActionUserInitialize)
             || intent.Action.Equals("android.intent.action.QUICKBOOT_POWERON")
             || intent.Action.Equals("com.htc.intent.action.QUICKBOOT_POWERON")
           )
        {
            //run code here only if its started by the chosen actions
        }
        //some code that doesnt care about which action is triggered by
    }
}
于 2018-07-23T11:58:53.513 回答
0

添加以下内容似乎对我有用 BOOT_COMPLETED 意图操作

        <action android:name="android.intent.action.QUICKBOOT_POWERON" />
于 2021-01-28T08:50:49.880 回答
0

要解决此问题,您可以使用 firebaseJobDispatcher 自动调用,firebaseJobDispatcher 将有代码来响应您的服务,是的,在一定时间后服务可能会被操作系统停止,但您的 firebaseJobDispatcher 会再次重新激活您的服务。FirebaseJobDispatcher 有很多属性,您可以从中定义它的范围;

它是如何工作的,更多细节 https://github.com/firebase/firebase-jobdispatcher-android

于 2018-10-12T09:13:10.927 回答
-1

如果您想知道 BOOT_COMPLETE 无法正常工作或无法接收的实际原因。我会建议你去官方的 Android 开发网站。他们已经用确切的解决方案进行了解释。

Android 开发者 - BOOT_COMPLETE

于 2017-08-30T16:47:25.120 回答
-3

基本上你需要清单中的 android:enabled="true" android:exported="true" 标志来接收广播。

<receiver android:name=".bootReceiver" android:enabled="true" android:exported="true">
        <intent-filter>
            <action android:name="android.intent.action.BOOT_COMPLETED" />
            <category android:name="android.intent.category.DEFAULT"/>
        </intent-filter>
    </receiver>
于 2018-01-22T20:45:38.513 回答