2015-09-11 12 views
12

Mam symbol @AAR, który wymaga wpisu w manifeście aplikacji konsumującej. Podczas ładowania mojej biblioteki sprawdzam AndroidManifest.xml dla wymaganego odbiornika i jeśli nie mogę go znaleźć, wyrzucam RuntimeException, ponieważ moja biblioteka nie będzie działać poprawnie. Działa to w 99% instalacji, ale istnieje niewielka liczba instalacji, które rzucają ten numer RuntimeException, gdy odbiornik wyraźnie istnieje.Nie można znaleźć odbiorcy o zdefiniowanym manifeście ~ 1% czasu

Android v4.4 - v5.1.1 są uwzględnione w raportach o awariach. Samsung, Lenovo, Nexus 4, Nexus 5 itd. To wszystkie urządzenia, których dotyczy problem.

Najciekawszą wskazówką jest to, że ~ 75% wypadków dotyczy urządzeń zrootowanych. Przypuszcza się, że jest to wynikiem zastosowania niestandardowej pamięci ROM lub innej aplikacji, która zakłóca wykrywanie odbiornika.

Testowałem z rooted Nexus 5 w/4.4.4 i działa dobrze. Przetestowałem na magazynie Nexus 5 w/5.1.1 i działa dobrze. Testowałem z Nexusem 5 z CyanogenMod 12.1 (najnowsza wersja) i działa dobrze. Zastosowałem wszystkie dostępne opcje Ochrony prywatności i nadal działa dobrze.

Naprawdę ponoszę straty i nie chcemy porzucać użytkowników, których dotyczy problem.

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> 

Klasa

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

Odpowiedz

0

Jedynym sposobem, w jaki udało mi się odtworzyć to zachowanie, jest zainstalowanie aplikacji innej firmy, która pozwala selektywnie wyłączyć Services i Receivers. Nie jestem pewien, dlaczego ktoś chciałby to zrobić i po wyłączeniu nie ma możliwości ponownego włączenia ich z mojego rocznego sprawozdania z działalności.

Najlepszym przypadkiem było zgłoszenie wyjątku podczas programowania i po prostu wyprowadzenie do LogCat w celu uzyskania podpisanych wersji produkcyjnych.

Przykładem takiej aplikacji można znaleźć tutaj:

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

-1

Czy można usunąć android: eksportowane = "true" i sprawdzić? Idealnie android: wyeksportowany powinien być fałszywy.

+0

Idealnie? Dokumentacja stwierdza inaczej http://developer.android.com/guide/topics/manifest/receiver-element.html i, jak zaznaczono powyżej, działa na 99,9% urządzeń, na których ten kod jest wykonywany. –

Powiązane problemy