应用程序关闭时未收到Android BOOT_COMPLETED

时间:2013-06-21 01:33:34

标签: android bootcompleted

我知道这个问题已经在网站上被问了很多,但是,我似乎无法找到解决方案。当应用程序未运行时,不会调用我的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>

StartUpBootReceiver:

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事件,而不是我的。

8 个答案:

答案 0 :(得分:93)

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

Android stopped state

当处于“已停止”状态时,应用程序将无法以任何理由运行,除非手动启动活动。 (含义BroadcastReceviersACTION_PACKAGE_INSTALLEDBOOT_COMPLETED等)将被调用,无论他们注册的事件是什么,直到用户手动运行应用程序。)

这是Google的反恶意软件举措。谷歌一直主张用户应该首先从启动器启动一个活动,然后该应用程序可以做很多事情。在活动发起之前阻止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/

答案 1 :(得分:38)

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

<receiver android:name="com.example.startuptest.StartUpBootReceiver" 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>

答案 2 :(得分:1)

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

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

希望得到这个帮助。

答案 3 :(得分:1)

如果需要的话,这里提供 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
    }
}

答案 4 :(得分:0)

  

如果您想知道为什么BOOT_COMPLETE无效或无法接收的实际原因。我建议你去官方的Android开发网站。他们用精确的解决方案进行了解释。

Android developer - BOOT_COMPLETE

答案 5 :(得分:0)

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

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

答案 6 :(得分:0)

添加以下内容与 BOOT_COMPLETED 意图操作一起对我有用

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

答案 7 :(得分:-3)

基本上你需要android:enabled =&#34; true&#34;机器人:导出=&#34;真&#34;清单中的标志用于接收广播。

<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>