无法找到清单定义的接收器〜1%的时间

时间:2015-09-11 12:35:47

标签: android broadcastreceiver android-manifest

我有一个@AAR需要在使用应用程序的清单中输入一个条目。在我的库的引导期间,我检查AndroidManifest.xml所需的接收器,如果我找不到它,我抛出RuntimeException,因为我的库将无法正常工作。这适用于99%的安装,但是当接收器明确存在时,有少量安装会抛出此RuntimeException

Android v4.4 - v5.1.1都包含在崩溃报告中。三星,联想,Nexus 4,Nexus 5等都是受影响的设备。

最有趣的线索是~75%的崩溃都发生在root设备上。据推测,这是一些自定义ROM或其他一些干扰接收器检测的应用程序的结果。

我已经使用了扎根Nexus 5 w / 4.4.4进行了测试,它运行正常。我用Nexus 5 w / 5.1.1进行了测试,它运行正常。我已经使用运行CyanogenMod 12.1(最新版本)的Nexus 5进行了测试,它运行正常。我应用了所有可用的Privacy Guard选项,它仍然可以正常工作。

真的不知所措,不想放弃受影响的用户。

的AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">

    <permission
        android:name="${applicationId}.permission.C2D_MESSAGE"
        android:protectionLevel="signature" />

    <uses-permission android:name="${applicationId}.permission.C2D_MESSAGE" />
    <uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />

    <application>
        <receiver
            android:name="com.example.MyBroadcastReceiver"
            android:exported="true"
            android:permission="com.google.android.c2dm.permission.SEND">
            <intent-filter>
                <action android:name="com.google.android.c2dm.intent.RECEIVE" />
                <action android:name="com.google.android.c2dm.intent.REGISTRATION" />

                <category android:name="${applicationId}" />
            </intent-filter>
        </receiver>
        <!-- Activities, etc. removed for brevity -->
    </application>
</manifest>

public class CheckSetup {

        // Other methods removed for brevity

    public void checkManifest() {
        List<ResolveInfo> receiversInfo;

        Intent checkIntent = new Intent(applicationContext, MyBroadcastReceiver.class);
        receiversInfo = packageManager.queryBroadcastReceivers(checkIntent, 0);

        boolean receiverFound = false;

        if (receiversInfo != null) {
            for (ResolveInfo resolveInfo : receiversInfo) {
                if (resolveInfo.activityInfo != null && resolveInfo.activityInfo.name.equals(MyBroadcastReceiver.class.getName()) && resolveInfo.activityInfo.packageName.equals(packageName)) {
                    receiverFound = true;
                }
            }
        }

        if (!receiverFound) {
            throw new RuntimeException(String.format("%s definition not found in AndroidManifest.xml", MyBroadcastReceiver.class.getName()));
        }
    }
}

2 个答案:

答案 0 :(得分:0)

我能够重现此行为的唯一方法是安装第三方应用程序,允许我有选择地禁用ServicesReceivers。我不确定为什么有人会想要这样做,一旦禁用,就无法从我的AAR重新启用它们。

最好的情况是在开发过程中抛出异常,只需输出到LogCat以获取生产签名版本。

可以在此处找到此类应用的示例:

https://play.google.com/store/apps/details?id=cn.wq.myandroidtools

答案 1 :(得分:-1)

你可以删除android:exported =&#34; true&#34;并检查?理想情况下,android:exports应该是false。