web-dev-qa-db-fra.com

android - "Le récepteur exporté ne nécessite pas d'autorisation" sur les récepteurs destinés à recevoir des services système

J'ai certains récepteurs déclarés dans mon AndroidManifest:

<!-- no warning -->
<receiver
    Android:name=".receivers.TriggerMonitoringBootReceiver"
    Android:enabled="false">
    <intent-filter>
        <action Android:name="Android.intent.action.BOOT_COMPLETED" />
    </intent-filter>
</receiver>

<!-- no warning -->
<receiver
    Android:name=".receivers.ScanResultsReceiver"
    Android:enabled="false">
    <intent-filter>
        <action Android:name="Android.net.wifi.SCAN_RESULTS" />
    </intent-filter>
</receiver>

<!-- warning : Exported receiver does not require permission-->
<receiver
    Android:name=".receivers.BatteryMonitoringReceiver"
    Android:enabled="false">
    <intent-filter>
        <action Android:name="@string/intent_action_setup_alarm" />
        <action Android:name="@string/intent_action_cancel_alarm" />
        <action Android:name="@string/intent_action_monitor" />
    </intent-filter>
</receiver>

Le premier est destiné à recevoir un BOOT_COMPLETED action. Le second est destiné à recevoir Android.net.wifi.SCAN_RESULTS. Le troisième est destiné à recevoir certaines actions que je diffuse (intent_action_monitor) et certaines actions diffusées par le AlarmManager (intent_action_setup_alarm, etc.).

Deux questions:

  • Pourquoi ne reçois-je pas l'avertissement sur tous les récepteurs?
  • De quelles autorisations ai-je besoin pour définir pour les récepteurs destinés à recevoir des services système pour corriger l'avertissement (Je comprends de quoi il s'agit et je ne veux pas que quiconque utilise mes récepteurs de toute façon)? Volonté exported="false" faire pour les récepteurs d'amorçage, les récepteurs wifi, les récepteurs d'alarme etc?
    J'ai pensé à utiliser une autorisation personnalisée avec Android:protectionLevel="signatureOrSystem" mais la documentation déconseille ceci niveau de protection et autorisations personnalisées . Alors, comment dois-je gérer cet avertissement?

Les liens vers les documents et/ou du code seront très appréciés.

60
Mr_and_Mrs_D

Pourquoi ne reçois-je pas l'avertissement sur tous les récepteurs?

Parce que les deux premiers sont clairement conçus pour être diffusés par Android. La dernière est inconnue, en partie parce que vous n'avez pas fourni les valeurs de ressource de chaîne et peut-être parce que ce sont vos propres chaînes d'action uniques.

Quelles autorisations dois-je définir pour les récepteurs destinés à recevoir des services système pour corriger l'avertissement

La bonne solution consiste à supprimer le <intent-filter>. Si vous diffusez ces Intents, ou si vous encapsulez un Intent dans une getBroadcast()PendingIntent, vous n'avez pas besoin de chaînes d'action. Utilisez le constructeur Intent qui prend l'objet de classe Java comme deuxième paramètre) et utilisez-le:

new Intent(this, BatteryMonitoringReceiver.class)

Vous pouvez toujours attacher une chaîne d'action à ce Intent, si vous le souhaitez, mais vous pouvez vider le <intent-filter> (Le routage sera basé sur le composant fourni, dans ce cas le Java).

N'utilisez un <intent-filter> Que lorsque vous attendez que le système d'exploitation ou des applications tierces lancent le Intent eux-mêmes (l'exécution d'un PendingIntent que vous avez créé ne compte pas).

64
CommonsWare

L'avertissement "Le récepteur exporté ne nécessite pas d'autorisation" signifie que vous avez un intent-filter avec une action (ce qui signifie par défaut que vous avez Android:exported="true" set et il peut maintenant receive broadcasts de N'IMPORTE QUEL diffuseur en dehors de votre application) Puisqu'il peut receive broadcasts de TOUT broadcasters en dehors de votre application, il vous avertit en disant "Hé, êtes-vous sûr que TOUT diffuseur peut vous invoquer? À mon avis, il est préférable de n'autoriser que ces broadcasters pour vous appeler avec le permission que vous avez défini pour ce receiver à Android:permission"

Vous pouvez supprimer cet avertissement en ajoutant Android:exported="false" à la balise du récepteur

25
Xar E Ahmer

Si vous souhaitez exporter votre récepteur vers d'autres processus, vous pouvez ajouter votre propre définition d'autorisation dans votre fichier manifeste Android pour éviter cet avertissement, comme

<permission
    Android:name="com.yourpage.permission.YOUR_PERMISSION"
    Android:protectionLevel="normal" />

<uses-permission
    Android:name="com.yourpage.permission.YOUR_PERMISSION" />

<receiver <!-- warning : Exported receiver does not require permission-->
    Android:name=".receivers.BatteryMonitoringReceiver"
    Android:permission="com.yourpage.permission.YOUR_PERMISSION"
    Android:enabled="false" >
    <intent-filter>
        <action Android:name="@string/intent_action_setup_alarm" />
        <action Android:name="@string/intent_action_cancel_alarm" />
        <action Android:name="@string/intent_action_monitor" />
    </intent-filter>
</receiver> 

pour plus d'informations, vous pouvez vous référer à http://developer.Android.com/training/articles/security-tips.html

23
Lubo

Si, comme moi, vous êtes ici parce que votre application construite avec une version précédente du SDK a cessé de fonctionner avec des versions plus récentes et que vous souhaitez le corriger avec un minimum de modifications, ajoutez simplement

Android: exporté = faux

à la balise du récepteur dans le fichier manifeste. La solution de CommonsWare est évidemment la solution à long terme, mais cela résout temporairement le problème si vous utilisez des intentions personnalisées et ne souhaitez pas les exporter.

En suivant la voie de Lubo, vous devrez exporter cette autorisation personnalisée, qui inviterait l'utilisateur avant l'installation. Cela signifie que le texte descriptif de l'autorisation doit être bien écrit pour que vous ne finissiez pas par effrayer l'utilisateur à changer d'avis sur l'installation de l'application. De plus, il devrait être traduit dans toutes vos langues cibles.

4
navjotk