64

首先,我知道已经问了数百个这样的问题,但是我已经检查了一段时间,仍然找不到任何解决方案。

我已经看到这个答案说 BOOT_COMPLETED 不会发送到应用程序,除非用户在 Android 版本 3.1 之后首先启动您的应用程序,但我仍然看到一些应用程序正在这样做,必须有办法。我真的需要处理它,否则我也反对在没有用户交互的情况下做某事。

所以这是我的 AndroidManifest:

<manifest ... >

<!-- to be activated service on boot is completed -->
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<!-- Keeps the processor from sleeping when a message is received. -->
<uses-permission android:name="android.permission.WAKE_LOCK" />

<application ... >
    <!-- to receive data when boot completed -->
    <receiver
        android:name="myPackage.BootReceiver"
        android:enabled="true"
        android:exported="true"
        android:permission="android.permission.RECEIVE_BOOT_COMPLETED" >
        <intent-filter>
            <action android:name="android.intent.action.BOOT_COMPLETED" />
        </intent-filter>
    </receiver>
</application>

</manifest>

提前致谢。

编辑:在我的广播接收器中没有什么可看的,但这里需要的是:

package myPackage
public class BootReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
    Utils.LogI("BootReceiver", "BootReceiver received!");
    if (Intent.ACTION_BOOT_COMPLETED.equals(intent.getAction())) {
        // Do my stuff
    }
}
}
4

8 回答 8

84

下面这件事对我有用

AndroidManifest.xml

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

<application>    

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

    <service android:name="NotifyingDailyService" >
    </service>

BootCompletedReceiver.class

public class BootCompletedReceiver extends BroadcastReceiver {

@Override
public void onReceive(Context context, Intent arg1) {
    // TODO Auto-generated method stub
    Log.w("boot_broadcast_poc", "starting service...");
    context.startService(new Intent(context, NotifyingDailyService.class));
}

}

服务类

 public class NotifyingDailyService extends Service {

@Override
public IBinder onBind(Intent arg0) {
    // TODO Auto-generated method stub
    return null;
}

@Override
public int onStartCommand(Intent pIntent, int flags, int startId) {
    // TODO Auto-generated method stub
    Toast.makeText(this, "NotifyingDailyService", Toast.LENGTH_LONG).show();
    Log.i("com.example.bootbroadcastpoc","NotifyingDailyService");

    return super.onStartCommand(pIntent, flags, startId);
}
}
于 2013-12-07T12:36:47.580 回答
57

这是一个古老而基本的问题,但许多 Android 开发人员现在仍然对这个问题感到困惑,因为他们没有花时间仔细阅读文档

我看到有人分享了一些链接并说:“这已经不行了”,这是完全错误误解的。

关于这个问题:“我已经看到这个答案说 BOOT_COMPLETED 不会发送到应用程序,除非用户在 Android 版本 3.1 之后首先启动您的应用程序”,请阅读这些行(来自官方文档:https://developer.android. com/about/versions/android-3.1.html#launchcontrols)正确理解:

  • 请注意,应用程序的停止状态Activity 的停止状态不同。系统分别管理这两个停止状态。

  • 应用程序在首次安装但尚未启动以及由用户手动停止时(在Manage Applications中)处于停止状态。(他们的意思是强制停止应用程序)

在此处输入图像描述

  1. 这意味着用户应该在安装后至少启动一次应用程序以激活应用程序,然后应用程序可以正常接收来自操作系统的隐式广播。(只有一次发射!

  2. “是否有任何应用程序被安装并且从未打开过一次?” ,是的,它是垃圾邮件和诈骗应用程序,这种技术可以帮助用户防止这种情况!

此外,直到现在(Android Oreo 8.0),当 Android 限制在 Manifest(https://developer.android.com/about/versions/oreo/background.html#broadcasts)上注册隐式广播时,目前仍有几个广播不受这些广播的约束限制。 BOOT_COMPLETED是他们提到的一个https://developer.android.com/guide/components/broadcast-exceptions.html

顺便说一句,这是我为这个问题找到的最佳解决方案:

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

<receiver android:name=".BootReceiver" android:enabled="true" android:exported="true">
            <intent-filter>
                <category android:name="android.intent.category.DEFAULT"/>
                <action android:name="android.intent.action.BOOT_COMPLETED"/>
                <action android:name="android.intent.action.QUICKBOOT_POWERON"/>
                <!--For HTC devices-->
                <action android:name="com.htc.intent.action.QUICKBOOT_POWERON"/>
            </intent-filter>
        </receiver>

最后,请仔细阅读文档并三思而后行代码一次:3!

于 2017-09-19T07:41:30.670 回答
9

并为 Htc 设备添加com.htc.intent.action.QUICKBOOT_POWERON

    <receiver android:enabled="true" android:name=".receivers.BootUpReceiver">
        <intent-filter>
            <category android:name="android.intent.category.DEFAULT" />
            <action android:name="android.intent.action.BOOT_COMPLETED"/>
            <action android:name="android.intent.action.QUICKBOOT_POWERON"/>
            <action android:name="com.htc.intent.action.QUICKBOOT_POWERON"/>
         </intent-filter>
    </receiver>
于 2017-03-06T09:52:02.900 回答
7

一些新的平板电脑和安卓设备默认具有安全应用程序。有时这些应用程序会锁定您的自动启动模式。这个安全应用程序的一个例子是 MyAsus 管理器。因此您可以将“允许自动启动”添加到您的应用程序

于 2016-12-23T20:31:00.837 回答
7

对于其他仍然像我一样遇到此问题的人,如果您在具有引导锁定(引脚、模式或其他)的设备上进行调试,则操作系统版本 >= 7.0 需要订阅android.intent.action.LOCKED_BOOT_COMPLETED如下图所示:

<receiver
    android:directBootAware="true"
    android:name=".BootCompletedReceiver">
    <intent-filter>
        <action android:name="android.intent.action.BOOT" />
        <action android:name="android.intent.action.LOCKED_BOOT_COMPLETED" />
        <action android:name="android.intent.action.QUICKBOOT_POWERON" />
    </intent-filter>
</receiver>

您可以在以下链接中找到文档:https ://developer.android.com/training/articles/direct-boot

于 2020-02-25T21:23:58.167 回答
6

问题出在设备上。某些设备只允许内部应用程序接收此操作(例如:Android 5.1)。

您可以将其添加到您的意图过滤器中作为解决方法

行动android:name="android.intent.action.USER_PRESENT"

这是在用户解锁设备后触发的。

于 2017-05-25T09:39:14.453 回答
1

我遇到的问题是,当我从 Android 6.0.1 面板关闭电源时BOOT_COMPLETEDQUICKBOOT_POWERON并不总是触发我的意图。我在网上搜索了很长时间,通过添加QUICKBOOT_POWEROFF到清单文件中找到了解决方案。

也可以看看:

HTC 的“快速启动”没有广播 BOOT_COMPLETED 意图,也没有从警报管理器中擦除意图

于 2019-02-22T10:08:23.103 回答
-3

对于解决方法,您需要创建 NotificationListener 服务

如果设备 >= Build.VERSION_CODES.JELLY_BEAN_MR2 并且具有华为设备中的电池优化选项,那么您必须请求 NotificationListener 权限并按照以下代码创建 NotificationListener 服务,然后您将在接收器中获得 BOOT_COMPLETED

清单接收者:

    <receiver
                android:name=".TestRes"
                android:enabled="true"
                android:exported="true">
                <intent-filter android:priority="1">
                    <category android:name="android.intent.category.DEFAULT"/>
                    <action android:name="android.intent.action.BOOT_COMPLETED"/>
                    <action android:name="android.intent.action.QUICKBOOT_POWERON"/>
                    <action android:name="android.intent.action.USER_PRESENT"/>
                    <action android:name="android.intent.action.REBOOT"/>
                </intent-filter>
 </receiver>

1 创建一个 NotificationListener 服务:

@RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR2)
public class DevAppNotificationListener extends NotificationListenerService {

    @Override
    public void onNotificationPosted(StatusBarNotification sbn) {
//        super.onNotificationPosted(sbn);
    }

    @Override
    public void onNotificationRemoved(StatusBarNotification sbn) {
   //     super.onNotificationRemoved(sbn);
    }


}

2 检查 NotificationListener 是否被授予:

static boolean CheckNotificationLisPermission(Context context)
    {

        return NotificationManagerCompat.getEnabledListenerPackages (context).contains(context.getApplicationContext().getPackageName());

    }

3 如果没有,则请求 NotificationListener 权限:

 Intent intent = new Intent("android.settings.ACTION_NOTIFICATION_LISTENER_SETTINGS");
            context.startActivityForResult(intent, callBackResultIntent);
于 2019-06-07T17:49:18.633 回答