Ho un @AAR che richiede una voce nel manifest dell'applicazione che consuma. Durante il bootstrap della mia libreria, ispeziono lo AndroidManifest.xml
per il ricevitore richiesto e, se non riesco a trovarlo, lancio un RuntimeException
poiché la mia libreria non funzionerà correttamente. Funziona sul 99% delle installazioni, ma ci sono un numero limitato di installazioni che generano questo RuntimeException
quando il ricevitore esiste chiaramente.Impossibile trovare il destinatario definito manifest ~ ~ 1% del tempo
Android v4.4 - v5.1.1 sono tutti inclusi nei rapporti di arresto anomalo. Samsung, Lenovo, Nexus 4, Nexus 5, ecc. Sono tutti dispositivi interessati.
L'indizio più interessante è che circa il 75% degli arresti anomali si verificano su dispositivi con root. La speculazione è stata che questo è il risultato di alcune ROM personalizzate o di qualche altra applicazione che interferisce con il rilevamento del ricevitore.
Ho provato con un Nexus 5 w/4.4.4 con le radici e funziona perfettamente. Ho provato con uno stock Nexus 5 con 5.1.1 e funziona perfettamente. Ho provato con un Nexus 5 con CyanogenMod 12.1 (ultima versione) e funziona perfettamente. Ho applicato tutte le opzioni di Privacy Guard disponibili e funziona ancora bene.
Davvero in perdita e non voglio abbandonare gli utenti interessati.
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>
Classe
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()));
}
}
}
Idealmente? La documentazione indica altrimenti http://developer.android.com/guide/topics/manifest/receiver-element.html e, come indicato sopra, funziona sul 99,9% dei dispositivi su cui viene eseguito questo codice. –