RECEIVE_BOOT_COMPLETED和"导出的接收器不需要许可"

时间:2015-03-31 13:50:05

标签: android android-intent android-manifest intentfilter android-broadcast

我的问题不是重复:我搜索了SO和网络,但还没有找到明确的答案。

在与蓝牙相关的应用中,我希望在设备启动时启动后台Service,然后连接到蓝牙信标(如果可用),并在特定事件时向用户发布Android通知。

所以我在AndroidManifest.xml添加了以下行:

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

    <service 
        android:name="ScanService"
        android:icon="@drawable/ic_launcher">
        <intent-filter>
            <category android:name="android.intent.action.BOOT_COMPLETED" />
        </intent-filter>
    </service>

然而,Eclipse显示警告导出的接收者不需要许可,这可能意味着任何应用都可以运行我的服务。当然,我不希望这样。

我只想要Android OS(在启动时)和我的MainActivity(充当后台服务的设置GUI前端)能够(重新)启动ScanService。

这个问题有两个常见的建议:

  1. 首先是将android:exported="false"添加到意图过滤器。
  2. 其次是将android:permission添加到intent过滤器。
  3. 但我仍然有后续问题:

    1. BOOT_COMPLETED广播是否仍会传送到“非导出”服务?
    2. 此处指定的权限是,真的是RECEIVE_BOOT_COMPLETE还是其他什么(Android系统是否需要此权限?)

2 个答案:

答案 0 :(得分:6)

1。 BOOT_COMPLETED是操作系统发送的跨应用程序系统范围的广播,所有过滤的应用组件都会听到这个广播。 未导出仅表示其他应用无法使用该组件;接收方肯定会听到广播行动。

2。 BOOT_COMPLETED是您需要在此处使用的广播。设置android:exported="false"并在清单中添加该权限。

修改

BOOT_COMPLETED广播操作。要在启动时拦截它,您需要使用BroadcastReceiver,然后您可以启动Service。在您的清单中,添加

<receiver 

    android:name=".BootCompletedReceiver" 
    android:enabled="true" 
    android:exported="false">

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

</receiver>

创建课程

public class BootCompletedReceiver extends BroadcastReceiver {   

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

        Intent i = new Intent(context, ScanService.class);
        context.startService(i);

    }
}

试试这个。这将有效。

答案 1 :(得分:1)

如果出现以下情况,请记住以下事项: Android接收器&amp; RECEIVE_BOOT_COMPLETED&amp; BOOT_COMPLETED无法启动您的服务

显而易见的事情之后:

<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"
and:
            <receiver 
                   android:name="com.twiggwidgets.service.MyScheduleReceiver"
                   android:enabled="true"
                   android:exported="true"
            >
                <intent-filter>
                     <action android:name="android.intent.action.BOOT_COMPLETED" />
 <action android:name="android.intent.action.QUICKBOOT_POWERON" />
                     <category android:name="android.intent.category.DEFAULT" />
                </intent-filter>
            </receiver>

还在拔头发吗?

Android 3.1之后 &#34;系统将 FLAG_EXCLUDE_STOPPED_PACKAGES 添加到所有广播意图。&#34; 这意味着在3.1之后,所有应用程序都会在启动时停止。 为什么?出于安全考虑。

RULES 关闭标志&#34; FLAG_EXCLUDE_STOPPED_PACKAGES&#34;

(1)您的应用需要手机存储,而不是SD卡,否则标志设置。  在挂载外部存储之前发送BOOT_COMPLETE。如果应用程序安装到外部存储器,它将无法收到BOOT_COMPLETE广播消息。

(2)如果用户按下&#34;强制关闭&#34;来自设置或&#34;无响应的应用程序&#34;按钮,标志已设置。

(3)如果应用程序从未运行过,则设置标志(永远不会相对于当前引导状态; O)从不意味着在此引导中或者在上次引导状态中使标志无效)

如果您遵守规则,您的Reciver将在启动时运行(标记未设置)。

<强>信息

您可以注册接收您的代码(它不会帮助启动)。

    IntentFilter filter = new IntentFilter("com.twiggwidgets.service.MyScheduleReceiver");

    MyScheduleReceiver myReceiver = new MyScheduleReceiver();
    registerReceiver(myReceiver, filter);

//receiver's (are supposed to) run momentarily, but you knew that.

测试提示

Open console/terminal and navigating to /platform-tools (it should be in your path ;O)).
Type adb shell or on linux/mac ./adb shell
In the shell type "am broadcast -a android.intent.action.BOOT_COMPLETED"

看到android链接: http://developer.android.com/about/versions/android-3.1.html#launchcontrols