Android8.0 implizite Broadcast- und benutzerdefinierte Signaturberechtigung

Cogito ergo sum

Vorwort

Nehmen Sie den interessanteren Fehler auf, den mein Kollege heute mit mir teilte: Die bestehenden Sendungen, die in China registriert wurden, können AndroidManifest.xmlauf einigen Mobiltelefonen nicht Actionimplizit gestartet werden . Ich habe im Internet nach Informationen gesucht und eine Demo geschrieben, Mark it ! !

Offizielle Android-Website: Oreo-Hintergrundausführungslimit

Hier betrachten wir hauptsächlich die Auswirkungen auf den Rundfunk, auszugsweise aus einer Einführung auf der offiziellen Website:

Sendebeschränkung

Wenn sich eine App für den Empfang von Broadcasts registriert, verbrauchen die Empfänger der App jedes Mal Ressourcen, wenn ein Broadcast gesendet wird. Dies kann zu Problemen führen, wenn sich mehrere Apps für den Empfang systemereignisbasierter Broadcasts registrieren: Ein Systemereignis, das einen Broadcast auslöst, kann dazu führen, dass alle Apps in schneller Folge Ressourcen verbrauchen, wodurch die Benutzererfahrung beeinträchtigt wird. Um dies abzumildern Android 7.0(API-Level 24) wurden dem Broadcasting einige Beschränkungen auferlegt, wie in Background Optimization beschrieben . Android 8.0(API-Level 26), um diese Beschränkungen strenger zu machen.

  • Apps , die sich anpassen Android 8.0oder höher sind, können Broadcast-Empfänger nicht mehr für implizite Broadcasts in ihrem Manifest registrieren. Ein impliziter Broadcast ist nicht anwendungsspezifisch. Beispielsweise ACTION_PACKAGE_REPLACEDist ein impliziter Broadcast, da er an alle registrierten Listener gesendet wird, um sie darüber zu informieren, dass einige Pakete auf dem Gerät ersetzt wurden. Es handelt sich jedoch ACTION_MY_PACKAGE_REPLACEDnicht um eine implizite Übertragung, da sie nur an die App gesendet wird, deren Paket ersetzt wurde, unabhängig davon, wie viele andere Apps Listener für die Übertragung registriert haben.
  • Apps können sich weiterhin für explizite Übertragungen in ihrem Manifest registrieren.
  • Anwendungen können zur Laufzeit Empfänger Context.registerReceiver()für (entweder implizit oder explizit).
  • Broadcasts, die Signaturberechtigungen erfordern , sind von dieser Einschränkung ausgenommen, da sie nur an Apps gesendet werden, die mit demselben Zertifikat signiert sind, nicht an alle Apps auf dem Gerät.

In vielen Fällen können Apps, die sich zuvor für implizite Broadcasts registriert haben, ähnliche Funktionen mithilfe von JobSchedulerjobs . Beispielsweise muss eine soziale Foto-App möglicherweise von Zeit zu Zeit eine Datenbereinigung durchführen, und dies in der Regel, während das Gerät an ein Ladegerät angeschlossen ist. Zuvor hatte die App einen Empfänger für im Manifest ACTION_POWER_CONNECTEDregistriert ; wenn die App die Sendung empfängt, prüft sie, ob eine Bereinigung erforderlich ist. Zur Migration zu Android 8.0oder später entfernt die App diesen Empfänger aus ihrem Manifest. Die App plant Reinigungsaufträge so, dass sie ausgeführt werden, wenn das Gerät im Leerlauf ist und aufgeladen wird.

**Hinweis:** Viele implizite Übertragungen sind derzeit von dieser Einschränkung ausgenommen. Apps können weiterhin Empfänger für diese Sendungen in ihrem Manifest registrieren, unabhängig davon, mit welcher API-Ebene die App kompatibel ist. Eine Liste der ausgenommenen Broadcasts finden Sie unter Implizite Broadcast-Ausnahmen .

Basierend auf der obigen Beschreibung können wir die folgenden Punkte erhalten:

  1. Angepasste Android 8.0oder neuere Apps können Broadcast-Empfänger für implizite Broadcasts nicht mehr in ihrem Manifest registrieren;
  2. Apps können weiterhin explizite Broadcasts in ihren Manifesten registrieren;
  3. Context.registerReceiver()Es wird empfohlen, die Registrierung zur Laufzeit zu senden;
  4. Sendungen, die einer Unterschriftenberechtigung bedürfen, fallen nicht darunter;

benutzerdefinierte Berechtigungen

Offizielle Android-Website: Erlaubnis

<permission android:description="string resource"
    android:icon="drawable resource"
    android:label="string resource"
    android:name="string"
    android:permissionGroup="string"
    android:protectionLevel=["normal" | "dangerous" |"signature" | ...] />

android: Schutzstufe

Beschreiben Sie die potenziellen Risiken, die mit der Genehmigung verbunden sind, und geben Sie den Prozess an, dem das System folgen sollte, um zu bestimmen, ob der anfordernden App die Genehmigung erteilt werden soll.

Jede Schutzebene besteht aus einem Basisberechtigungstyp und null oder mehr Flags. Beispielsweise dangeroussind Schutzstufen nicht gekennzeichnet. Stattdessen signature|privilegedsind Kombinationen aus signatureBasisberechtigungstypen und Flags.privileged

Die folgende Tabelle listet alle grundlegenden Berechtigungstypen auf. Eine Liste der Flags finden Sie unter protectionLevel .

Wert Bedeutung
normal Standardwerte. Berechtigungen mit geringerem Risiko, die es der anfordernden App ermöglichen, mit minimalem Risiko für andere Apps, das System oder den Benutzer auf Funktionen auf isolierter App-Ebene zuzugreifen. Das System gewährt diese Berechtigungen automatisch Apps, die zum Zeitpunkt der Installation eine Autorisierung anfordern, ohne die ausdrückliche Erlaubnis des Benutzers (obwohl der Benutzer immer die Möglichkeit hat, diese Berechtigungen vor der Installation zu überprüfen).
dangerous Berechtigungen mit höherem Risiko, die es einer App, die eine Autorisierung anfordert, ermöglichen, auf die privaten Daten eines Benutzers zuzugreifen oder die Kontrolle über ein Gerät zu erlangen, was sich nachteilig auf den Benutzer auswirken könnte. Aufgrund des potenziellen Risikos solcher Berechtigungen werden sie Apps, die eine Autorisierung anfordern, möglicherweise nicht automatisch gewährt. Zum Beispiel können alle von der App angeforderten gefährlichen Berechtigungen dem Benutzer angezeigt werden und erfordern eine Bestätigung, bevor fortgefahren wird, oder es kann eine andere Methode verwendet werden, um den Benutzer daran zu hindern, eine solche Funktionalität automatisch zuzulassen.
signature Berechtigungen werden nur erteilt, wenn die App, die die Autorisierung anfordert, mit demselben Zertifikat signiert ist wie die App, die die Berechtigung erklärt. Wenn die Zertifikate übereinstimmen, werden Berechtigungen automatisch erteilt, ohne den Benutzer zu benachrichtigen oder um seine ausdrückliche Erlaubnis zu bitten.
signatureOrSystem signature\privilegedaltes Synonym für . In API-Ebene 23 veraltet . Eine Berechtigung, die vom System nur AndroidApps gewährt wird, die sich in einem dedizierten Ordner im Systemabbild befinden oder mit demselben Zertifikat signiert sind wie die App, die die Berechtigung erklärt. Verwenden Sie diese Option nicht, da signaturedie Schutzstufe für die meisten Anforderungen ausreichend sein sollte und unabhängig davon, wo die App installiert ist, funktioniert. signatureOrSystemBerechtigungen sind in dem speziellen Fall nützlich, in dem mehrere Anbieter Apps in ein einzelnes System-Image einbauen und bestimmte Funktionen explizit gemeinsam nutzen müssen, weil sie zusammen entwickelt wurden.

Passen Sie Signaturberechtigungen und -verwendung an

<permission
        android:protectionLevel="signature"
        android:name="com.xx.xx.receiver" />
<uses-permission android:name="com.xx.xx.receiver"/>

prüfen

Ich werde eine Demo schreiben, um es zu testen, die Testmaschine MI 8ist das System Android 10.

Deklarieren Sie zwei Broadcast, eines mit Erlaubnis und eines ohne Erlaubnis.

public open class CustomReceiver : BroadcastReceiver() {
    
    
    override fun onReceive(context: Context?, intent: Intent?) {
    
    
        if(intent != null) {
    
    
            var param = intent.getStringExtra("message")
            var result:String?
            result = String.format("get the receiver for %s", param)
            XToast.show(result)
        }
    }
}
public class CustomReceiver2 : CustomReceiver() {
    
    }
<!--带签名权限的广播-->
<receiver android:name=".main.receiver.CustomReceiver"
    android:permission="com.xx.xx.receiver">
    <intent-filter>
        <action android:name="com.xx.xx.message"/>
        <category android:name="android.intent.category.DEFAULT" />
    </intent-filter>
</receiver>
<!--普通的广播-->
<receiver android:name=".main.receiver.CustomReceiver2">
    <intent-filter>
        <action android:name="com.xx.xx.message2"/>
        <category android:name="android.intent.category.DEFAULT" />
    </intent-filter>
</receiver>
  1. Sendeberechtigung implizite Übertragung - keine Berechtigung

var intent = Intent("com.xx.xx.message" + num++)
intent.putExtra("message","custom test" + num++)
sendBroadcast(intent)

Ergebnis: Toast kann nicht angezeigt werden.

15:59:23.420#1635#1758#W#BroadcastQueue #Background execution not allowed: receiving Intent {
    
     act=com.xx.xx.message flg=0x10 (has extras) } to com.xx.xx.demo/.main.receiver.CustomReceiver
  1. Sendeberechtigung Implizite Broadcast-Plus-Berechtigung

var intent = Intent("com.xx.xx.message")
intent.putExtra("message","custom test")
sendOrderedBroadcast(intent, "com.xx.xx.receiver")

Ergebnis: Toast entfaltet sich.

  1. Berechtigung senden impliziter Broadcast-plus-Berechtigungsfehler

var intent = Intent("com.xx.xx.message")
intent.putExtra("message","custom test")
sendOrderedBroadcast(intent, "com.xx.xx.receiver.error")

Ergebnis: Toast kann nicht angezeigt werden.

15:44:54.514#1696#1774#W#BroadcastQueue #Permission Denial: receiving Intent {
    
     act=com.xx.xx.message flg=0x1000010 (has extras) } to com.xx.xx.ztemplate/.main.receiver.CustomReceiver requires com.xx.xx.receiver.error due to sender com.xx.xx.demo (uid 10547)
  1. impliziten Broadcast senden

var intent = Intent("com.xx.xx.message2")
intent.putExtra("message","custom test")
sendBroadcast(intent)

Ergebnis: Toast kann nicht angezeigt werden.

15:59:23.420#1635#1758#W#BroadcastQueue #Background execution not allowed: receiving Intent {
    
     act=com.xx.xx.message flg=0x10 (has extras) } to com.xx.xx.demo/.main.receiver.CustomReceiver
  1. Implizites Broadcast senden - Paket hinzufügen

var intent = Intent("com.xx.xx.message2")
intent.`package` = "com.xx.xx.demo"
intent.putExtra("message","custom test")
sendBroadcast(intent)

Ergebnis: Toast entfaltet sich.

  1. Senden Sie implizites Broadcast -setClass (entspricht dem Hinzufügen einer Komponente)

var intent = Intent("com.xx.xx.message2")
intent.setClass(this, CustomReceiver2::class.java)
intent.putExtra("message","custom test")
sendBroadcast(intent)

Ergebnis: Toast entfaltet sich.

Tatsächlich sind der erste 5und der zweite 6Fall keine impliziten Broadcasts mehr, sie geben beide die aktuelle Umgebung für Intentdie Einstellung an.package

Fehleranalyse

BroadcastQueue #Permission Denial:

BroadcastQueue-permission-denial.png

Hier liegt ein Problem mit der Berechtigung vor, und die Berechtigung muss hinzugefügt oder geändert werden.

BroadcastQueue #Background execution not allowed:

BroadcastQueue-not-allow.png

//android.content.Intent.java
public static final int FLAG_RECEIVER_INCLUDE_BACKGROUND = 0x01000000;
public static final int FLAG_RECEIVER_EXCLUDE_BACKGROUND = 0x00800000;

Dieser Codeblock hat eine ||Operation, und wir wollen nicht, dass sie in die Modifikationslogik eingeht, die als zuvor falseund als später beurteilt werden muss false.

Das Flag-Bit wird in die Beurteilung r.intent.getFlags()&Intent.FLAG_RECEIVER_EXCLUDE_BACKGROUNDübernommen FLAG_RECEIVER_EXCLUDE_BACKGROUND. Wir führen es im Allgemeinen nicht, also ist die vorherige Logik false.

Es gibt drei &&Operationen hinter der Logik, also müssen Sie nur eine davon falsesein lassen.

  1. r.intent.getComponent() == null, tritt in diese Logik ein (Einstellungskomponente ) .

  2. r.intent.getPackage() == null, tritt in diese Logik ein (Einstellungskomponente ) .

  3. r.intent.getFlags() & Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND) == 0FLAG_RECEIVER_INCLUDE_BACKGROUNDEs kann dieses Flag nicht haben , andernfalls tritt es in diese Logik ein (setzen Sie FLAG_RECEIVER_INCLUDE_BACKGROUND ).

  4. Wenn die Berechtigung beim Starten der Übertragung übertragen wird, wird sie, wenn es sich nicht um die Signaturerlaubnis handelt, in diese Logik eingegeben ( die Signaturerlaubnis festlegen ).

Tatsächlich haben wir es bereits 1oben 2getestet (der erste 5und der erste 6Fall);

3set Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND, aber das Ändern von Konstanten ist hidenicht Intentüber zugänglich. Wir können nur schreiben 0x01000000, aber das wird nicht empfohlen;

4Tatsächlich werden die im Dokument beschriebenen Signaturberechtigungen nicht Android 8.0durch die Hintergrundausführungsoptimierung gesteuert;

Der Artikel ist hier alles gesagt, wenn Sie andere Kommunikationsbedürfnisse haben, können Sie eine Nachricht hinterlassen ! !

Wenn Sie weitere Artikel des Autors lesen möchten, können Sie meinen persönlichen Blog und mein öffentliches Konto besuchen :
Buchstadt neu beleben

Supongo que te gusta

Origin blog.csdn.net/stven_king/article/details/113173099
Recomendado
Clasificación