Android 12L Beta 3 ist für Entwickler. Wenn Sie Entwickler oder Betatester sind, können Sie die neueste Beta 3 herunterladen und Ihre Apps mit der neuen Version kompatibel machen.
Hier sind einige Verbesserungen in Beta 3:
Die Schaltfläche „Split top“ in PiP wurde entfernt
Der Text „Keine Benachrichtigung“ unter dem Schatten / Bildschirm
Die Winkelradien des geteilten Bildschirms entsprechen dem physikalischen Winkel des Bildschirms [U]
Symbol “Split Top” (Endname) gesetzt.
Passen Sie die Seite mit den Bildschirmschonereinstellungen an (ursprünglich Daydream).
Die Uhrzeit wird jetzt in „Auf einen Blick“ angezeigt
Liste der von Android 12L unterstützten Geräte
Hier ist eine Liste von Geräten, die Android 12L unterstützen:
Pixel 6 Pro
Pixel6
Pixel 5a
Pixel 5
Pixel 4a (5G)
Pixel 4a
Pixel 4 XL
Pixel 4
Pixel 3a XL
Pixel 3a
Wenn sich Ihr Gerät in der Liste der unterstützten Geräte befindet, können Sie es für das Android 12L Beta-Programm auswählen und die neuen Funktionen nutzen.
Vielen Dank für das Lesen des Artikels. Folgen Sie uns weiter Twitter für die neuesten Updates auf Android.
Sie können GitHub-Veröffentlichungsbenachrichtigungen abonnieren, indem Sie auswählen Suchen ???? Brauch ???? Ausgaben:
Markdown-, HTML- und Nur-Text-Versionen der Versionshinweise können unter heruntergeladen werden Eigentum Abschnitt unten auf der Seite der GitHub-Edition.
👋 Hallo und willkommen zu der neuen Reihe von Blogbeiträgen, in denen wir tief in die Android-Sicherheit eintauchen werden. Diese Serie konzentriert sich hauptsächlich auf Top 10 mobil Sicherheitsbedrohungen zu Open Web Application Security Project Foundation (OWASP).die führende Community für Anwendungssicherheit in unserem Bereich.
Während sich diese Posts auf die Android-Plattform konzentrieren, sind viele der Ideen und Gefühle dahinter völlig agnostisch für die Plattform, ebenso wie die OWASP-Top-10-Liste selbst.
Diese Beiträge sind auch eine Ergänzung zu meiner Rede vom Januar 2022 „Don’t Be Stunned by OWASP – An Introduction to Writing Code for Greater Android Security“, in der ich die 5 größten Probleme ausführlicher bespreche. Bitte überprüfen Sie meine Diskussionsseite für weitere Details und relevante Links. EIN begleitender Antrag die die in der Rede vorgestellten Probleme demonstriert, steht ebenfalls zum kostenlosen Download zur Verfügung.
Bitte beachten Sie, dass diese Serie zu Bildungszwecken dient nur. Denken Sie daran, nur Anwendungen zu testen, für die Sie die Erlaubnis dazu haben, und vor allem, sei nicht gemein.
In diesem ersten Teil meiner Serie über Android-Sicherheit werden wir uns mit der Bedrohung Nummer 1 für die Sicherheit mobiler Apps befassen, die von OWASP als unsachgemäße Nutzung der Plattform bezeichnet wird.
Auf den ersten Blick scheint die missbräuchliche Nutzung der Plattform eine etwas vage Aussage über etwas zu sein, das sein sollte das brennendes Problem in der Sicherheit mobiler Anwendungen. Was dieser Titel jedoch subtil auszudrücken versucht, ist, dass die Hauptbedrohung für die Sicherheit unserer mobilen Anwendungen tatsächlich darin besteht uns. Geradeheraus, Wir sind das Problem! ¹
Was meine ich mit dieser hyperbolischen Aussage? Nun, normalerweise führt unbeabsichtigter Missbrauch von Entwicklern, Fahrlässigkeit oder einfach Unverständnis für die Android-Plattform zu unseren schwerwiegendsten Sicherheitsproblemen.
Niemand kann erwarten, dass er die gesamte Plattform von innen kennt, und Entwickler sind auch nicht unfehlbar. Fehler passieren unvermeidlich, aber ich hoffe, dass Sie durch die Einführung einiger der häufigsten Sicherheitsprobleme, die wir versehentlich in unseren Code schreiben, es sich zweimal überlegen, bevor Sie selbst denselben Fehler machen, und sich vor einer potenziellen Sicherheitskatastrophe bewahren.
Entschuldigung für das schreckliche Wortspiel, das erste häufige Beispiel für den Missbrauch der Android-Plattform fällt in die Definition Intent. Für diejenigen, die neu bei Android sind, profitiert die Plattform Intent Klasse als eine Möglichkeit, eine Art von Aktion zu initiieren. Dies kann in Form des Navigierens auf einem neuen Bildschirm in Ihrer App, des Startens eines Hintergrund-/Vordergrund-Dienstes oder der Registrierung eines Rundfunkempfängers erfolgen, um regelmäßige Updates von einer Quelle zu erhalten. Der Intent -Klasse bietet eine einfache Möglichkeit, Daten zu parsen und an separate Anwendungskomponenten zu übergeben, und ist die häufigste Methode, dies mithilfe eines Frameworks zu erreichen.
Allerdings ist das Android-Framework Auch ermöglicht anderen Anwendungen das Senden und Empfangen Intent Instanzen zwischen ihnen, um die „Kommunikation“ zwischen Anwendungen zu erleichtern. Hierin liegt die erste gemeinsame Falle.
Um die Kommunikation zwischen Anwendungen zu ermöglichen, die Komponente der Anwendung, die wir erhalten möchten Intent muss als gekennzeichnet sein android:exported=true Innerhalb AndroidManifest.xml Datei. Wenn Sie eine Komponente mit diesem Flag markieren, können Sie eine „ausdrückliche Absicht“ an eine andere Anwendung (oder ein anderes System) senden, um die angegebene Aktion auszuführen, die die empfangende Komponente verwalten kann.
Darüber hinaus können auch Komponenten definiert werden <intent-filter> Blöcke innerhalb des Manifests, um die Arten von Absichten anzugeben, auf die die Aktivität, der Dienst oder der Broadcast-Empfänger reagieren kann. Durch diese Definition kann eine andere Anwendung „implizite Absicht“ verwenden, um das System aufzufordern, Ihre Anwendung als kompatibel anzuzeigen, wenn sie eine bestimmte Absicht anbietet. Beispielsweise die Weiterleitung an ein implizites Intent-System, um Anwendungen anzuzeigen, die URLs verarbeiten können https://spght.dev kann eine Liste der installierten Webbrowser anbieten. Was jedoch für Anfänger vielleicht nicht offensichtlich ist, ist, dass durch die Angabe des Intent-Filters die Komponente im System als Export gekennzeichnet wird obwohlandroid:exported=true es ist im Manifest nicht explizit definiert.
Meiner Erfahrung nach ist es nicht ungewöhnlich, dass App-Komponenten versehentlich als „Exportieren“ gekennzeichnet werden, obwohl dies eigentlich nicht der Fall sein sollte. Diese falsch definierten Anwendungskomponenten stellen ein großes Sicherheitsrisiko dar, da sie direkt verfügbar sind und daher potenziell ausgenutzt werden können.
Der Hauptgrund, warum schlecht verwaltete Exporte so gefährlich sind, liegt darin, dass es trivial ist, diese Schwachstellen in der Anwendung zu finden und darauf abzuzielen.
Böswillige Akteure können manuell nach Reverse-Engineering-Anwendungen suchen oder Befehlszeilentools wie z drozer oder Cutter um gefährdete exportierte Komponenten zu scannen. Einmal gesammelt, kann es verwendet werden adb entweder um eine Komponente auszuführen oder um eine Absicht zu erstellen, die die gewünschte Aktion des Hackers ausführt.
Ein bemerkenswertes Beispiel dafür aus der realen Welt wurde vom Käferjäger Mehtab Zafar (mzfr) in seinem November 2020 entdeckt. Blogeintrag die detailliert beschreibt, wie die falsch konfigurierte „Deep-Link-Aktivität“ die Ausnutzung von Multi-Site-Scripting (XSS) auf der offiziellen mobilen GitHub-App ermöglichte. Huch.
U begleitender Antrag für meine Rede geschrieben wurde, wurde dies durch Fehlkonfigurationen von Aktivitäten demonstriert MainActivity dass es gemeldet werden kann, obwohl normalerweise eine “Authentifizierung” für den Zugriff von der Anwendung erforderlich ist.
Wie MainActivity exportiert wird, ist es möglich, einfach anzurufen adb dass das System die Aktivität öffnet und somit die Notwendigkeit einer Authentifizierung umgeht.
All dies mag ein wenig entmutigend klingen, aber zum Glück ist es so einfach, diesen Angriffsvektor zu stoppen, wie die relevanten Komponenten in Ihrem zu sichern AndroidManifest.xml die Datei(en) korrekt mit gekennzeichnet sind android:exported.
Tatsächlich ist es ab Android 12 (API 31) nun eine Anfrage zu setzen android:exported Eigentum an allen Ihren Activity, Serviceich BroadcastReceiver Definitionen in Ihrer Anwendung AndroidManifest.xml Datei(en), wenn Sie auf dieses SDK abzielen.
Als zusätzlichen Schutz ermöglicht die Android-Plattform der App auch, eine „benutzerdefinierte Lizenz“ zu definieren Elemente der Genehmigung im Manifest für Wechselwirkungen einschränken mit seinen exponierten Komponenten.
Beispielsweise kann eine Anwendung eine “Signatur”-Berechtigung definieren, die es ihr erlaubt, nur mit anderen Anwendungen zu interagieren, die dieselbe Berechtigung teilen. ich werden mit demselben Signaturzertifikat erstellt:
Um das Schicksal von GitHub zu vermeiden, ist es außerdem eine bewährte Methode, Inhalte zu überprüfen und zu validieren Intent die Sie erhalten, wenn Sie mit Daten umgehen von a <intent-filter>. Tu es Nein blind glauben, dass das, was Sie bekommen, das sein wird, was Sie erwarten!
In zukünftigen Beiträgen dieser Serie werden wir weitere Fälle von „Plattformmissbrauch“ und mehr als die OWASP Top 10 für mobile Geräte untersuchen.
Danke wie immer fürs Lesen! Ich hoffe, Sie fanden diesen Beitrag interessant, zögern Sie nicht, mich mit Feedback zu twittern @Sp4ghettiCode und vergessen Sie nicht zu klatschen, zu liken, zu twittern, zu teilen, zu markieren usw.
Kotlin und Swift haben vielleicht viel funktionale Magie in das Spiel eingeführt, aber da sie die natürlichen Erben von Java und Obj-Ca sind, haben sie starke OOP-Grundlagen. Vererbung ist immer noch ein grundlegendes Konzept, und Schnittstellen / Protokolle spielen eine wichtige Rolle im Toolkit eines mobilen Entwicklers.
Aber wie bei allem gibt es echte Gründe, sie zu verwenden, und es gibt falsche. Beim Code-Design bemühen wir uns, bewährte Verfahren zu befolgen, auch wenn wir uns nicht zu 100 % sicher sind, warum sie gut sind. Und obwohl es überhaupt keine schlechte Sache ist, kann es zu subtilem Missbrauch führen. Wenn wir uns zum Beispiel an die protokollorientierte Programmierung gewöhnen, verspüren wir möglicherweise das Bedürfnis, sie auf jedes einzelne Problem anzuwenden – es ist ein weit verbreitetes Vorurteil, Alles sieht aus wie ein Nagel, wenn man einen Hammer hält.
Sehen wir uns also die verschiedenen Gründe für die Verwendung von Schnittstellen und Protokollen an.
Polymorphismus
Polymorphismus ist genau der Grund, warum Schnittstellen geschaffen wurden. Die häufigsten Beispiele sind Modellklassen, z. Angenommen, Sie haben eine Chat-App und verarbeiten verschiedene Arten von Nachrichten.
Auf diese Weise können Sie die Liste handhaben Message Gegenstände und z.B. sortiere sie nach ihren timestamp aber immer noch in der Lage sein, zwischen Arten von Text- und Bildnachrichten zu unterscheiden. Ohne Schnittstelle müssten Sie auf hässliche Lösungen wie eine Mehrzweckklasse mit vielen Feldern zurückgreifen, die zurückgesetzt werden können.
Mehrfachvererbung
Weder Kotlin noch Swift erlauben Mehrfachklassenvererbung (als Lösung für Diamantproblem), aber seine Vorteile können durch Schnittstellen erreicht werden.
Auf Android, wenn Sie feststellen, dass Sie einigen eine Menge unabhängiger Verpflichtungen hinzufügen BaseStunden, als BaseActivity oder BaseViewModelMöglicherweise möchten Sie ein Upgrade von einfacher Vererbung auf Komposition über eine in Erwägung ziehen Schnittstelle mit Standardimplementierung.
Unter iOS können Sie mithilfe der Protokollerweiterung etwas Ähnliches tun.
In diesen Beispielen können Sie die Kotlina-Erweiterungsfunktion (fun Activity.showToast(...)) und Protokollerweiterungen zu UIView direkt (extension UIView ...), aber die Einführung einer Schnittstelle / eines Protokolls gibt Ihnen mehr Kontrolle – die Funktion ist auf Klassen beschränkt, die davon erben, sodass die Erweiterung nicht an die gesamte Codebasis weitergegeben wird.
Grenzen zwischen Schichten
In seiner Pure Architecture schlägt Uncle Bob eine Struktur vor, die aus bogenartigen Schichten besteht. Die eigentliche Grundlage dieses Paradigmas ist die Regel der Abhängigkeit – die äußeren Schichten können Wissen über die inneren Schichten haben, aber die inneren Schichten sollten nichts über die äußeren wissen.
Reine Architektur ist in der mobilen Entwicklung weit verbreitet, aber eine Sache, die oft missverstanden wird, ist, dass sich die Datenschicht außerhalb der Domänenschicht befindet. Die Geschäftslogik muss nicht wissen, wie Daten geliefert werden, sondern muss nur ihre Eingaben definieren, normalerweise über RepositorySchnittstelledie über eine Datenschicht implementiert werden kann.
In der reinen Architektur definiert die Domänenschicht die Repository-Schnittstelle, die von der Datenschicht implementiert wird
Die Trennung der Geschäftslogik und ihre vollständige Unabhängigkeit von Ansichten und Daten kann große Vorteile haben. Das wird Ihnen jeder sagen, der einen Antrag mit White Labels mit unterschiedlichen Zielen unter Verwendung unterschiedlicher Datenquellen gestellt hat. Wir sollten jedoch die Kosten für übermäßiges Engineering stark berücksichtigen – in vielen mobilen Anwendungen gibt es wirklich nicht viel Geschäftslogik und wir könnten mit einem Haufen trauriger einzeiliger UseCase-Klassen enden, die Daten vom Repository nach ViewModel übertragen.
Dieser Punkt wird erweitert Das hässliche Abschnitt etwas mehr.
Doppeltest
Historisch gesehen waren Schnittstellen unvermeidlich, wenn wir Testduplikate wie haben wollten er spottet ich Fälschungen bei Unit-Tests. Es könnte jedoch argumentiert werden, dass dies eher ein Missbrauch dieser Sprachstruktur als eine legitime Verwendung war. In Java war dies einfach eine Einschränkung des Spott-Frameworks.
In Swift könnte ein protokollbasierter Scheintest so aussehen:
Dies ist jedoch nicht erforderlich. Wir können ein einfaches verwenden class Pro Grinder ich GrinderMock Ich kann davon erben. Ein möglicher Nachteil ist, dass es nicht kompilieren würde, wenn Grinder Er war structDies ist der endgültige Typ, von dem nicht geerbt werden kann.
Ähnlich in Kotlin, in diesem Fall muss die Schnittstelle nicht verwendet werden. Obwohl alle Klassen standardmäßig endlich sind, mögen sich spöttische Frames verspotten oder Mockito kann mit dem endgültigen Typ leicht gehandhabt werden.
Rückrufe
Ein gängiges Muster in der frühen Android-Java-Welt war die Einführung einer Callback-Schnittstelle, die anonym wie folgt implementiert wurde:
Dies ist in Kotlin nicht mehr idiomatisch. Funktionen sind Typen in Kotlin, sodass Sie sie einfach als Variablen weitergeben können
class ListAdapter(val itemClickListener : () -> Unit) { ...
“Weil ich es leicht durch eine andere Implementierung ersetzen kann”
Okay, ich gebe zu, das ist wohl der Hauptgrund, warum ich diesen Artikel überhaupt schreibe. Es ist sehr üblich, diese Antwort zu erhalten, wenn man nach dem Grund für das Schreiben gefragt wird einzige Implementierungsschnittstelle. Manchmal wird es als „Reduzierung von Fusionen“ umformuliert, was sicherlich schlau klingt.
Verstehen Sie mich nicht falsch, die Reduzierung von Fusionen kann sehr sinnvoll sein, z. oben erwähnt Grenzen zwischen Schichten Das Beispiel ist legitim. Aber selbst der Rat von Onkel Bob sollte nicht als Evangelium verstanden werden, jede mögliche Lösung sollte im Kontext des Problems betrachtet werden, das wir zu lösen versuchen.
Daran müssen wir uns alle erinnernclass es hat bereits eine eigene Schnittstelle – dies sind die öffentlichen Methoden, die es präsentiert, und ihre Ergebnisse. Der Schlüssel zum Entwerfen einer guten Schnittstelle ist das Denken in Bezug auf ihre Ein- und Ausgänge, die Verantwortung dieser Klasse. Ein zusätzlicher Hinweis: Unit-Tests sind ein großartiges Werkzeug, um diese Art des Denkens zu fördern.
Am Ende des Tages wollen wir nur einen Wartungscode schreiben. Wie im Zitat zusammengefasst Pragmatischer Programmierer:
Wenn Sie auf ein Problem stoßen, beurteilen Sie, wie lokalisiert die Reparatur ist. Ändern Sie nur ein Modul oder sind die Änderungen über das ganze System verstreut? Wenn Sie eine Änderung vornehmen, wird dadurch alles behoben oder treten auf mysteriöse Weise andere Probleme auf?
Schließen Sie die Schnittstelle von der Implementierung aus formal, mit nur zwei getrennten Typen, ist keine Wunderwaffe, um dies zu erreichen. Getrennt haben interface oder protocol es hat immer seinen Preis – zunehmende kognitive Komplexität, umständlichere Codenavigation usw. Wir sollten immer zwei Dinge bedenken:
wenn es wirklich die Konnektivität reduziert – unsere Schnittstellen können immer noch schlecht gestaltet sein, selbst wenn sie von der Implementierung getrennt sind;
wenn die Reduzierung der Fusion die Kosten wert ist.
Wenn Sie bis hierher gelesen haben und eine einfache Zusammenfassung dieses Artikels wünschen, holen Sie sich diese rote Fahne 🚩: Wenn Sie eine Schnittstelle mit nur einer Klasse entwerfen, die davon erbt, möchten Sie vielleicht innehalten und darüber nachdenken.
Wie bei den meisten akzeptiert Antworten auf SO, werden Sie höchstwahrscheinlich verwenden ActivityManager.getRunningTasks Methode zum Bestimmen, welche Anwendung vorhanden ist Vordergrund Kondition. Für diejenigen, die es nicht wissen Vordergrund ich Hintergrund Android-Anwendungsstatus, hier ist eine kurze Beschreibung,
Für unseren Anwendungsfall Vordergrund dies würde nur bedeuten, dass die Anwendung für den Benutzer nicht sichtbar ist (evtl Dom die Taste wird gedrückt; in diesem Fall wechselt die Anwendung zu Vor kurzem Seite).
Lassen Sie mich auf den Punkt zurückkommen, Ihre erste Beobachtung in offiziellen Dokumenten ActivityManager.getRunningTasks wird sagen, dass die Methode für Android Lollipop (API-Level 21) veraltet ist. ich die der Grund, den Android vorschlägt Es ist ziemlich überzeugend,
Mögen Build.VERSION_CODES.LOLLIPOPDiese Methode steht Anwendungen von Drittanbietern nicht mehr zur Verfügung: Die Einführung neuer dokumentorientierter Methoden bedeutet, dass Anruferinformationen verloren gehen können.
Sie werden auf diese Beobachtung auch stoßen, wenn Sie sich die schrillen Kommentare unter den SO-Antworten ansehen, die die Verwendung von nahelegten ActivityManager.getRunningTasks .
Der Zugriff auf die letzten Aktivitäten von Benutzern ohne Zustimmung kann dazu führen, dass Benutzer glauben, dass Ihre Anwendung eine Art Spyware-Software ist, die auf ihrem Gerät installiert ist. Außerdem könnten Entwickler die Nutzungsmuster von Apps untersuchen, die von Ihrem Gerät gestohlen wurden, um ihre eigenen Apps zu verbessern, alles aus Ihren privaten Daten. Also die Entscheidung zur Aufhebung ActivityManager.getRunningTasks von Android war ein naheliegender Schritt für die Sicherheit der Benutzerdaten.
Wenn Sie nach einem veralteten Ersatz suchen ActivityManager.getRunningTasks Sie werden wahrscheinlich eine Lösung finden, indem Sie verwenden ActivityManager.getRunningAppProcesses Methode. Aber aus irgendeinem Grund gibt die Methode nur den Paketnamen des aktuellen Prozesses zurück, also der Anwendung, die diese Methode aufgerufen hat. Keine andere vom Benutzer verwendete Anwendung wird über die Methode zurückgegeben.
Android scheint diese Methode auch eingeschränkt zu haben, um dem Benutzer eine verbesserte Privatsphäre zu bieten. Außerdem suchen wir nach einem Weg, der mehr ist offiziell und durch Android vor zukünftiger Veralterung geschützt.
Der UsageStatsManager -Klasse bietet Zugriff auf den Gerätenutzungsverlauf und Statistiken. In Anbetracht unseres Anwendungsfalls werden wir spezifische verwenden UsageStatsManager.queryUsageStats eine Methode zum Überprüfen der letzten Benutzeraktivitäten oder kürzlich verwendeten Anwendungen, mit Zustimmung des Nutzers.
Schritt 1: 🔐 Beantragung von Genehmigungen
Offizielle Dokumentation für UsageStatsManager Länder
Die meisten Methoden auf dieser API erfordern eine Genehmigung android.permission.PACKAGE_USAGE_STATS. Das Erklären der Erlaubnis impliziert jedoch die Absicht, die API zu verwenden, und der Gerätebenutzer muss die Erlaubnis dennoch über die Einstellungs-App erteilen.
Es ist also gut, diese Berechtigung zu unserer hinzuzufügen AndroidManifest.xml ,
Clip 1: PACKAGE_USAGE_STATS-Berechtigung zu AndroidManifest.xml hinzufügen
Beachten Sie, dies ist ein Sondergenehmigung und nicht ein Erlaubnis während der Ausführung mögen CAMERA oder WRITE_EXTERNAL_STORAGE die von der Anwendung angefordert werden können. Dies ist offensichtlich, da es sich um eine sensible Erlaubnis zum Zugriff auf die persönlichen Daten des Benutzers handelt, die dem Benutzer bekannt sein muss.
Schritt 2: 🔑 Überprüfen Sie den Status der Genehmigung und suchen Sie danach
In der Logik der Anwendung müssen wir zunächst feststellen, ob dies die vom Benutzer erteilte Erlaubnis ist, und wenn nicht, müssen wir danach fragen. Leider können wir den Status dieser Berechtigung nicht überprüfen ContextCompat.checkSelfPermission weil es sich um eine Sondergenehmigung handelt. Sondergenehmigungen verwaltet er lieber AppOpsManager Dies ist die Klasse, die verwendet wird, um alle Anwendungen zu verwalten und den Zugriff zu steuern.
Clip 2: Überprüfen Sie den Berechtigungsstatus von PACKAGE_USAGE_STATS mit AppOpsManager
Fragen PACKAGE_USAGE_STATS Berechtigungen, die wir nicht verwenden können ActivityCompat.requestPermissions Methode bzw ActivityResultContracts.RequestPermission() weil dies keine Genehmigung während der Ausführung ist, wie wir zuvor besprochen haben. Stattdessen müssen wir den Benutzer zur Seite „Einstellungen“ navigieren, wo der Benutzer diese Anwendungsberechtigung erteilt,
Clip 3: Fordern Sie die Berechtigung PACKAGE_USAGE_STATS an, nachdem Sie den Lizenzstatus überprüft habenNutzungsdateneinstellungen wie auf einem Android 9-Gerät (Samsung J7) beobachtet.
Schritt 3: imanjeLaden Sie das Nutzungsereignis herunter
Sobald der Benutzer die Erlaubnis erteilt, können wir nun auf den Geräteverlauf des Benutzers zugreifen und überprüfen, welche Apps in der Vergangenheit mit Zustimmung des Benutzers verwendet wurden. Jetzt können wir verwenden UsageStatsManager.queryEvents Methode zum Abrufen von Nutzungsereignissen.
Clip 4: Nutzungsereignisse mit der Methode „usageStatsManager.queryEvents“ anfordern.
Wie im Code vermerkt, queryEvents Die Methode benötigt zwei Argumente, beginTime ich endTime . beginTime gibt den Zeitpunkt (in der Vergangenheit) an, ab dem Ereignisse heruntergeladen werden sollen, doc endTime gibt die Zeit an, bis zu der wir Ereignisse benötigen. Beachten Sie, dass beide Argumente sind Unix-Zeit Werte, was beim Gebrauch deutlich wird System.currentTimeMillis() im obigen Code-Snippet.
Der usageEvents.getNextEvent gibt Ereignisse in chronologischer Reihenfolge zurück, also müssen Sie sie sortieren.
Wenn Sie auf Android R-Geräte abzielen, sollten Sie es sich unbedingt ansehen Schritt 5.
Überprüfen Sie die Ausgabe unten, wobei jede Zeile den Paketnamen und den Zeitstempel anzeigt, in dem der Benutzer auf das Paket zugegriffen hat.
Code-Snippet-Ausgabe 4. Die letzte Zeile in der obigen Ausgabe zeigt den Namen des aufrufenden Pakets.
Schritt 4: Vom Benutzer installierte Anwendungen filtern (optional)
Wie Sie sehen können, enthält die obige Ausgabe auch einige Systemanwendungen wie com.sec.android.app.launcher Dies ist die Standardanwendung, die auf Samsung-Geräten ausgeführt wird. Dies liegt daran, dass der Benutzer zum Startbildschirm wechselt, um eine andere Anwendung zu öffnen oder die Geräteeinstellung zu ändern. Möglicherweise möchten Sie diese Systemanwendungen filtern, sodass nur von Benutzern installierte Anwendungen in der Ausgabe sichtbar sind. Wir können eine Methode erstellen, die a zurückgibt Map die vom Benutzer installierte Anwendungen mit ihren Paketnamen und Tags (Anwendungsname, sichtbar für den Benutzer) enthält. Wir können von Benutzern installierte Apps filtern und auch deren Tag abrufen (falls Sie dies in der Logik Ihrer App weiterverarbeiten möchten).
Clip 5: Holen Sie sich einen „Ordner“, der Paketnamen und Tags der vom Benutzer installierten Anwendungen enthält
Schritt 5: Stellen Sie sicher, dass der Benutzer entsperrt ist (mit Android R)
Wenn Sie die Dokumentation auf überprüft haben UsageStatsManager.queryEvent Methode, werden Sie entdecken
Hinweis: Ab Android Rwenn sich das Gerät des Benutzers nicht im entsperrten Zustand befindet (wie definiert durch UserManager#isUserUnlocked()), dann null Wird zurückerstattet.
Mit Android R können wir diese Methode also nicht ausführen, wenn das Gerät gesperrt ist. Wir müssen also sicherstellen, dass der Benutzer entsperrt ist,
Clip 6: Überprüfen Sie, ob der Benutzer mit UserManager entsperrt ist
Denken Sie auch daran UserManager.isUserUnlocked Die Methode ist für API 24 und höher verfügbar, und daher werden wir sie ua bereitstellen if Erklärung.
Dies markiert das Ende unserer Implementierung. Verbinden Sie sich mit einem physischen Gerät und die App funktioniert!
Ich hoffe, dir hat der Blog gefallen! Für Anregungen und Anfragen können Sie gerne einen Kommentar hinterlassen. Lesen Sie weiter, studieren Sie und haben Sie einen schönen Tag!