Невозможно найти Manifest Defined Receiver ~ 1% от времени

У меня есть @AAR, который требует записи в манифесте приложения потребления. Во время начальной загрузки моей библиотеки я проверяю AndroidManifest.xml на нужный ресивер, и если я не могу его найти, я бросаю RuntimeException, так как моя библиотека не будет функционировать должным образом. Это работает на 99% установок, но есть небольшое количество установок, которые бросают этот RuntimeException, когда приемник явно существует.

Android v4.4 - v5.1.1 включены в отчеты о сбоях. Samsung, Lenovo, Nexus 4, Nexus 5 и т.д. - все это затронутые устройства.

Самая интересная подсказка заключается в том, что ~ 75% сбоев на корневых устройствах. Предположение заключается в том, что это результат некоторого пользовательского ПЗУ или другого приложения, которое мешает обнаружению приемника.

Я тестировал с укоренившимся Nexus 5 w/4.4.4, и он отлично работает. Я тестировал с запасом Nexus 5 w/5.1.1, и он отлично работает. Я тестировал Nexus 5 с CyanogenMod 12.1 (последняя версия), и он отлично работает. Я применил все доступные параметры защиты конфиденциальности и все еще работает нормально.

Действительно в убытке и не хотите оставлять затронутых пользователей.

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()));
        }
    }
}

Ответ 1

Единственным способом, которым я смог воспроизвести это поведение, является установка стороннего приложения, которое позволяет мне выборочно отключать Services и Receivers. Я не уверен, почему кто-то захочет это сделать, и после того, как отключено, нет возможности повторно включить их из моего AAR.

Лучшим случаем было исключение во время разработки и просто вывод в LogCat для выпуска подписанных выпусков.

Пример такого приложения можно найти здесь:

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

Ответ 2

Можете ли вы удалить android: exported = "true" и проверить? В идеале андроид: экспортируемый должен быть ложным.