【问题标题】:BroadcastReceiver not receiving BOOT_COMPLETEDBroadcastReceiver 没有收到 BOOT_COMPLETED
【发布时间】:2011-06-30 10:00:12
【问题描述】:

我在这里寻找类似的问题,但由于某种原因,我的 BroadcastReceiver 永远不会收到 android.intent.action.BOOT_COMPLETED Intent。

这是我的(相对)Android.Manifest 文件:

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

        </intent-filter>
    </receiver>

这是真正的接收者。

public class BootReceiver extends BroadcastReceiver {
private static final String TAG="BootReceiver";

@Override public void onReceive(Context context,Intent intent){
    try{
        context.startService(new Intent(context,ConnectivityListener.class));
        Log.i(TAG,"Starting Service ConnectivityListener");
    }catch(Exception e){
        Log.e(TAG,e.toString());
    }
}
}

谢谢!非常感谢任何帮助

【问题讨论】:

  • 盲猜——你的receiver不在主包中,也没有package/mainpackage/BootReceiver.java,而是package/mainpackage/receivers/BootReceiver.java,即receiver的路径不对.
  • 谢谢,我没想过要检查,但运气不好,它肯定在默认包中。
  • 当接收者声明包含 android:exported="true" 会为接收者创建新进程时,可能会发生同样的问题。您的记录器 (Log.i) 将在新控制台中打印结果,您甚至不会在 android 监视器 (Android Studio) 下注意到这些结果。除非您知道它的含义,否则我建议您删除此声明。

标签: android broadcastreceiver boot


【解决方案1】:

您可以通过 adb 连接到设备并打开设备外壳来模拟所有广播操作。

我们开始吧:

  • 打开控制台/终端并导航到 /platform-tools
  • 键入adb shell 或在linux/mac 上./adb shell
  • 在 shell 中输入 am broadcast -a android.intent.action.BOOT_COMPLETED 或任何你想触发的动作

adb 或 adb shell 附带了许多不错的命令。试试看吧

问候 弗洛尔

编辑:哦,该死的,我想要这个答案作为“每次都必须打开/关闭手机”的答案。对不起各位

【讨论】:

  • 根本不是最初的问题所要问的(所以不赞成),不过,我觉得这很有帮助,谢谢。
  • 作为参考,在 4.2.2 的 adb 中运行它实际上会重启你的设备
  • 有史以来最有用的随机答案
  • 在较新的 Android 版本上,您需要运行 adb shell am broadcast -a android.intent.action.BOOT_COMPLETED -p com.mypackage.name。在不限制广播到您的应用的情况下,您的设备实际上会重新启动。
  • 发出此命令时出现以下错误Broadcasting: Intent { act=android.intent.action.BOOT_COMPLETED } java.lang.SecurityException: Permission Denial: not allowed to send broadcast android.intent.action.BOOT_COMPLETED from pid=3566, uid=2000
【解决方案2】:

我发布此内容是希望它对尝试了所有方法但在安装后仍无法使其在启动时运行或者它以前可以工作但现在不再工作的人有所帮助。

所以假设你已经添加了权限:

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

并注册您的接收器:

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

并为您的BroadcastReceiver 编码:

public class StartUpBootReceiver extends BroadcastReceiver {

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

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

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

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

这是 Google 为防止恶意软件应用而做出的设计决定。谷歌提倡用户应该先从启动器启动一个活动,然后该应用程序才能做很多事情。在活动启动之前阻止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/

【讨论】:

  • +1 这是一个很好的答案,我没有意识到这一点。一个相关的信息是,从 3.1 “...系统将 FLAG_EXCLUDE_STOPPED_PACKAGES 添加到 all 广播意图。” 这导致您的答案中描述的情况 - 但是- “后台服务或应用程序可以通过将FLAG_INCLUDE_STOPPED_PACKAGES flag 添加到应该允许激活停止的应用程序的广播意图来覆盖此行为。”我尚未对此进行测试但是:p(取自您发布的链接developer.android.com/about/versions/…
  • 应该澄清的是,一旦用户在您的应用程序中运行任何活动一次,您将在以后的所有启动后收到 BOOT_COMPLETED 广播。对此的一个警告是,如果用户对您的应用执行强制关闭,他们将不得不再次手动启动它,然后您才能再次收到 BOOT_COMPLETED 广播。
  • @Dori 你能验证 FLAG_INCLUDE_STOPPED_PACKAGES 标志的行为吗?
  • 你不能addFlags,除非你第一次开始你的活动,因此这并没有绕过第一次启动应用程序的需要。
  • 激活的应用程序更新到新版本后是否保持激活状态?通过应用商店或adb install -r ?
【解决方案3】:

如果您的应用安装在外部存储(SD 卡) 上,您将永远不会收到启动完成操作。所以你必须在manifest tag中指定android:installLocation="internalOnly"

【讨论】:

  • 终于我明白了为什么我的应用程序在某些手机上没有启动,而在其他手机上却可以正常工作——问题是默认选择了哪个存储来安装应用程序。
  • 它也不能在我的棒棒糖 5.1.1 设备上运行。它认为在不启动 Activity 的情况下使用 BOOT_COMPLETED 是不可能的。
【解决方案4】:

您的 &lt;uses-permission&gt; 元素必须是 &lt;manifest&gt; 元素的直接子元素,而您上面的代码清单表明它不是。

Here is a sample project 演示BOOT_COMPLETED 的使用。

【讨论】:

  • 对不起,上面有点误导,因为我只取了 Manifest 的 sn-ps,因为它很长,但是 uses-permission 是 的直接子级
  • +1 用于提及 元素的正确位置。我把它作为 的子代弄错了,它编译时没有警告或错误,但当然没有用。
【解决方案5】:

原来接收器不在清单的标签中。哎呀!谢谢你们的帮助!测试这个最糟糕的部分是必须不断关闭和打开电话。 :P

【讨论】:

  • 正如我在其他地方看到的那样,您不需要重新启动,只需一个 shell:adb shell am broadcast -a android.intent.action.BOOT_COMPLETED
【解决方案6】:

这似乎是这个问题的最前沿线程,所以我想为我的 C# 同事添加一个解决方案。在尝试了这里的一切之后,我绞尽脑汁想弄清楚我做错了什么,但无济于事。我终于弄清楚出了什么问题,这与此处针对 C# Mono 开发的建议有所不同。基本上,它归结为我刚刚学到的东西。使用 C# 不要手动修改 AndroidManifest.xml!

请参阅本指南以供参考: Xamarin: Working with AndroidManifest.xml

更直接地解决这个问题,这里是你如何完成的。

首先,在您的项目属性中,在 Manifest 选项卡下,有一个复选框列表用于选择您要提供的权限,其中一个是 RECEIVE_BOOT_COMPLETED。检查以提供这些权限。

其次,您需要在您的 BroacastReceiver 类上放置适当的标签。

[BroadcastReceiver]
[IntentFilter(new String[]{ Intent.ActionBootCompleted }, Priority = (int)IntentFilterPriority.LowPriority)]
public class MyBootReceiver : BroadcastReceiver
{
   public override void OnReceive(Context context, Intent intent)
   {
      // Do your boot work here, set alarms, show toasts, whatever
   }
}

处理优先级的 [IntentFilter()] 的最后部分不是必需的,它只是让其他更高优先级的事情在启动时首先完成,如果您的应用程序不是高优先级的事情,这是一个很好的做法。

正如您将在链接文章中看到的那样,在您的代码中使用这些标签将导致在构建时创建 AndroidManifest.xml 文件,并保持其应有的状态。我发现,当手动修改清单以包含接收者标签时,系统导致它查找类的深度太深,从而引发 ClassNotFound 异常。它试图实例化 [Namespace].[Namespace].[BroadcastReceiver] 这是错误的。这样做是因为手动清单编辑。

无论如何,希望这会有所帮助。

另外,关于 adb 工具的另一个快速提示。如果您想获得更易于阅读的日志版本,请尝试以下操作:

C:\Android\platform-tools\adb logcat >> C:\log.txt

这会将 logcat 转储到一个文本文件中,您可以比在命令提示符窗口中更容易地打开和阅读。也让剪切和粘贴变得更加容易。

【讨论】:

  • 你在小米的MIUI下试过了吗?
【解决方案7】:

适用于部分运行 Android Kitkat 4.4.4_r2/r1 的设备。

Android 中似乎存在一个错误,导致 android.intent.action.BOOT_COMPLETED 没有被广播。

见:
BOOT FAILURE making Package Manager Service ready

在大多数情况下,这不是您问题的答案(更可能是因为权限等),但如果您正在运行 Kitkat,那么您可能会看看这是否适合您。

我遇到了这个问题,并且 android.intent.action.BOOT_COMPLETED 在它启动的某些时候根本不会被广播!

【讨论】:

  • 在 Android 5.1 版本中也存在同样的问题??
  • 那么我们应该怎么做呢?
【解决方案8】:

在我的清单文件中添加&lt;category android:name="android.intent.category.HOME" /&gt; 可以解决我的问题并且有效。

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

【讨论】:

    【解决方案9】:

    此处的其他答案已经涵盖了如何完美实现广播接收器以使其正常工作,但是我仍然在接收 BOOT_COMPLETED Intent 时遇到问题,直到我通过按应用程序图标。 每当我使用 Android Studio 中的调试/运行命令启动我的应用程序时,BOOT_COMPLETED Intent 将不会被传递,除非应用程序已打开并正在运行。

    我希望这可以帮助像我一样在这个问题上挣扎了几个小时的人。 此外,如果有人对这种行为有解释,我会很高兴了解更多。

    【讨论】:

      猜你喜欢
      • 2011-04-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-05-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多