Bei Google Play darf das komprimierte APK, das Nutzer herunterladen, nicht größer als 100 MB sein. Bei den meisten Apps bietet dies viel Platz für den gesamten Code und die Assets der App. Einige Apps benötigen jedoch mehr Speicherplatz für High-Fidelity-Grafiken, Mediendateien oder andere große Assets. Bisher mussten bei komprimierten Dateien über 100 MB die Dateien zusätzliche Ressourcen, wenn der Nutzer die App öffnet. Das Hosten und Bereitstellen der zusätzlichen Dateien und die Nutzererfahrung ist oft nicht ideal. Um Ihnen diesen Vorgang zu erleichtern, und angenehmer für die Nutzer ist, können Sie bei Google Play zwei große Erweiterungsdateien anhängen, Ihr APK ergänzen.
Google Play hostet die Erweiterungsdateien für Ihre App und stellt sie dem Gerät unter für Sie kostenlos. Die Erweiterungsdateien werden im freigegebenen Speicher des Geräts (der SD-Karte oder USB-Partition auch als „externe“ Speicher), auf die Ihre App zugreifen kann . Auf den meisten Geräten lädt Google Play die Erweiterungsdatei(en) gleichzeitig herunter. lädt das APK herunter, sodass Ihre App alles hat, was sie braucht, wenn der Nutzer sie für die beim ersten Mal. In einigen Fällen muss Ihre App die Dateien jedoch von Google Play herunterladen. wenn deine App gestartet wird.
Wenn du auf Erweiterungsdateien verzichten möchtest und die komprimierte Downloadgröße deiner App größer ist als 100 MB, laden Sie Ihre App stattdessen mit einer Android-App Bundles mit einer komprimierten Downloadgröße von bis zu 200 MB. Da die Verwendung von App Bundles verschieben die APK-Erstellung und -Signatur bei Google Play, Nutzer laden optimierte APKs mit nur den Code und die Ressourcen, die sie zum Ausführen Ihrer Anwendung benötigen. Sie müssen nicht selbst erstellen, mehrere APKs oder Erweiterungsdateien verwalten und Nutzer erhalten kleinere, optimierte Downloads.
Übersicht
Jedes Mal, wenn Sie ein APK über die Google Play Console hochladen, können Sie Fügen Sie der APK eine oder zwei Erweiterungsdateien hinzu. Jede Datei kann bis zu 2 GB groß sein und in einem beliebigen auswählen. Wir empfehlen jedoch die Verwendung einer komprimierten Datei, um Bandbreite während des Downloads zu sparen. Konzeptionell spielt jede Erweiterungsdatei eine andere Rolle:
- Die Haupt-Erweiterungsdatei primäre Erweiterungsdatei für zusätzliche Ressourcen, die für Ihre App erforderlich sind.
- Die Erweiterungsdatei patch ist optional und für kleine Aktualisierungen des Haupt-Erweiterungsdatei.
Sie können die beiden Erweiterungsdateien beliebig verwenden. Wir empfehlen jedoch, die Hauptdatei Erweiterungsdatei liefert die primären Assets und sollte nur selten aktualisiert werden. die Patcherweiterung sollte kleiner sein und als „Patch-Anbieter“ dienen, der mit jedem größeren oder nach Bedarf veröffentlicht werden.
Selbst wenn für Ihr App-Update nur eine neue Patch-Erweiterungsdatei erforderlich ist, müssen Sie
ein neues APK mit einem aktualisierten versionCode
im Manifest hochladen. Der Parameter
In der Play Console ist es nicht möglich, eine Erweiterungsdatei in ein vorhandenes APK hochzuladen.)
Hinweis: Die Patch-Erweiterungsdatei ist semantisch identisch mit dem Haupterweiterungsdatei – Sie können jede Datei beliebig verwenden.
Format des Dateinamens
Jede Erweiterungsdatei, die Sie hochladen, kann ein beliebiges Format haben (ZIP, PDF, MP4 usw.). Sie können auch das Tool JOBB zum Kapseln und Verschlüsseln eines Satzes verwenden von Ressourcendateien und nachfolgenden Patches für diesen Satz. Unabhängig vom Dateityp betrachtet sie als undurchsichtige binäre Blobs und benennt die Dateien nach dem folgenden Schema um:
[main|patch].<expansion-version>.<package-name>.obb
Dieses Schema besteht aus drei Komponenten:
main
oderpatch
- Gibt an, ob die Datei die Haupt- oder Patch-Erweiterungsdatei ist. Es kann sein, nur eine Hauptdatei und eine Patchdatei für jedes APK.
<expansion-version>
- Dies ist eine Ganzzahl, die dem Versionscode des APK entspricht, mit dem die Erweiterung beginnt
zuerst verknüpft (sie stimmt mit den
android:versionCode
der App überein) -Wert)."Erste" betont, weil ihr mit der Play Console eine hochgeladene Erweiterungsdatei mit einem neuen APK wiederverwenden, ändert sich der Name der Erweiterungsdatei nicht, sondern Die Version, die beim ersten Hochladen der Datei angewendet wurde, wird beibehalten.
<package-name>
- Der Name des App-Pakets im Java-Stil.
Angenommen, Ihre APK-Version lautet 314159 und Ihr Paketname ist com.beispiel.app. Wenn Sie eine Haupt-Erweiterungsdatei hochladen, wird die Datei umbenannt in:
main.314159.com.example.app.obb
Speicherort
Wenn Google Play Ihre Erweiterungsdateien auf ein Gerät herunterlädt, speichert es sie im System freigegebener Speicher. Um einwandfreies Verhalten sicherzustellen, dürfen Sie die Elemente nicht löschen, verschieben oder umbenennen Erweiterungsdateien. Falls Ihre App den Download von Google Play ausführen muss müssen Sie die Dateien am selben Speicherort speichern.
Die Methode getObbDir()
gibt den spezifischen Standort zurück.
für Ihre Erweiterungsdateien im folgenden Format:
<shared-storage>/Android/obb/<package-name>/
<shared-storage>
ist der Pfad zum freigegebenen Speicherplatz, der verfügbar ist vongetExternalStorageDirectory()
.<package-name>
ist der Name des App-Pakets im Java-Stil, verfügbar vongetPackageName()
.
In diesem Verzeichnis befinden sich für jede Anwendung nie mehr als zwei Erweiterungsdateien.
Das eine ist die Haupterweiterungsdatei und das andere ist die Patch-Erweiterungsdatei (falls erforderlich). Zurück
Versionen werden überschrieben, wenn du deine App mit neuen Erweiterungsdateien aktualisierst. Seit Android
4.4 (API-Level 19): Apps können Erweiterungsdateien von OBB
ohne externen Speicher lesen
Berechtigung. Für einige Implementierungen von Android 6.0 (API-Level 23) und höher ist jedoch
Berechtigungen erteilen, also müssen Sie
READ_EXTERNAL_STORAGE
im App-Manifest und fordern Sie die Berechtigung unter an
Laufzeit so:
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
Unter Android 6 und höher muss die Berechtigung für den externen Speicher zur Laufzeit angefordert werden. Einige Implementierungen von Android benötigen jedoch keine Berechtigung zum Lesen von OBB-Dateien. Die Das folgende Code-Snippet zeigt, wie Sie den Lesezugriff prüfen, bevor Sie externen Speicher anfordern Berechtigung:
Kotlin
val obb = File(obb_filename) var open_failed = false try { BufferedReader(FileReader(obb)).also { br -> ReadObbFile(br) } } catch (e: IOException) { open_failed = true } if (open_failed) { // request READ_EXTERNAL_STORAGE permission before reading OBB file ReadObbFileWithPermission() }
Java
File obb = new File(obb_filename); boolean open_failed = false; try { BufferedReader br = new BufferedReader(new FileReader(obb)); open_failed = false; ReadObbFile(br); } catch (IOException e) { open_failed = true; } if (open_failed) { // request READ_EXTERNAL_STORAGE permission before reading OBB file ReadObbFileWithPermission(); }
Wenn Sie den Inhalt der Erweiterungsdateien entpacken müssen, löschen Sie die Datei
OBB
anschließend Erweiterungsdateien und speichern Sie die entpackten Daten nicht.
im selben Verzeichnis. Speichern Sie die entpackten Dateien im Verzeichnis,
angegeben durch getExternalFilesDir()
. Sie können jedoch
Verwenden Sie nach Möglichkeit ein Erweiterungsdateiformat, mit dem Sie direkt aus
anstatt sie entpacken zu müssen. Wir stellen z. B. eine Bibliothek mit
Projekt namens APK Expansion Zip Library, das Ihre Daten direkt liest
aus der ZIP-Datei.
Achtung:Im Gegensatz zu APK-Dateien werden alle gespeicherten Dateien im freigegebenen Speicher können vom Nutzer und von anderen Apps gelesen werden.
Tipp:Wenn Sie Mediendateien in eine ZIP-Datei packen, können Sie dafür Mediendateien
mit Offset- und Längensteuerelementen (z. B. MediaPlayer.setDataSource()
und
SoundPool.load()
) ohne das
Ihre ZIP-Datei entpacken müssen. Damit dies funktioniert, dürfen Sie die
Mediendateien beim Erstellen der ZIP-Pakete. Wenn Sie beispielsweise das zip
-Tool verwenden,
sollten Sie mit der Option -n
die Dateisuffixe angeben, die nicht
komprimiert:
zip -n .mp4;.ogg main_expansion media_files
Download
Meistens lädt Google Play deine Erweiterungsdateien herunter und speichert sie gleichzeitig lädt das APK auf das Gerät herunter. In einigen Fällen kann Google Play kann die Erweiterungsdateien nicht herunterladen oder der Nutzer hat zuvor heruntergeladene Erweiterungsdateien gelöscht. Dateien. Um diese Situationen zu bewältigen, muss Ihre App in der Lage sein, die Dateien herunterzuladen. sich selbst, wenn die Hauptaktivität beginnt. Verwenden Sie dazu eine von Google Play bereitgestellte URL.
Der Downloadvorgang sieht im Allgemeinen so aus:
- Der Nutzer entscheidet, deine App über Google Play zu installieren.
- Wenn Google Play die Erweiterungsdateien herunterladen kann (was bei den meisten
Geräte), werden sie zusammen mit dem APK heruntergeladen.
Wenn Google Play die Erweiterungsdateien nicht herunterladen kann, werden die Nur APK.
- Wenn der Nutzer Ihre App startet, muss Ihre App prüfen, ob die Erweiterungsdateien
die bereits auf dem Gerät gespeichert sind.
- Wenn ja, ist Ihre App einsatzbereit.
- Falls nicht, muss deine App die Erweiterungsdateien über HTTP von Google Play herunterladen. Ihre App muss über den App-Lizenzierungsdienst von Google Play eine Anfrage an den Google Play-Client senden, die gibt für jede Erweiterungsdatei den Namen, die Dateigröße und die URL zurück. Mit diesen Informationen laden Sie die Dateien herunter und speichern Sie sie am richtigen Speicherort.
Achtung:Sie müssen unbedingt den erforderlichen Code für die Laden Sie die Erweiterungsdateien aus Google Play herunter, falls sich die Dateien nicht bereits im wenn die App gestartet wird. Wie im folgenden Abschnitt zum Herunterladen der Erweiterungsdateien beschrieben, steht Ihnen eine Bibliothek zur Verfügung, die vereinfacht diesen Vorgang erheblich und führt den Download von einem Dienst mit minimaler Code von Ihnen.
Checkliste für die Entwicklung
Im Folgenden finden Sie eine Zusammenfassung der Aufgaben, die Sie ausführen sollten, um Erweiterungsdateien mit Ihrem App:
- Ermitteln Sie zuerst, ob die komprimierte Downloadgröße Ihrer App größer als 100 MB sein muss. Speicherplatz ist kostbar und die Downloadgröße sollte so klein wie möglich sein. Wenn Ihre App verwendet mehr als 100 MB, um mehrere Versionen deiner Grafikinhalte für mehrere Bildschirme bereitzustellen sollten Sie stattdessen mehrere APKs veröffentlichen, in denen jedes APK enthält nur die Assets, die für die Bildschirme erforderlich sind, auf die die Anzeige ausgerichtet ist. Um optimale Ergebnisse zu erzielen, bei Google Play veröffentlichen, laden Sie ein Android App Bundle hoch, enthält den gesamten kompilierten Code und die Ressourcen Ihrer App, verschiebt jedoch die APK-Erstellung und -Anmeldung bei Google Spielen.
- Bestimmen Sie, welche App-Ressourcen von Ihrem APK getrennt werden sollen, und verpacken Sie sie in einem
-Datei, die als Haupterweiterungsdatei verwendet werden soll.
Normalerweise sollten Sie nur die zweite Patch-Erweiterungsdatei verwenden, wenn Sie Updates für die Haupterweiterungsdatei. Wenn Ihre Ressourcen jedoch die Beschränkung von 2 GB für den Haupt- Erweiterungsdatei verwenden, können Sie die Patchdatei für Ihre restlichen Assets verwenden.
- Entwickeln Sie Ihre App so, dass sie die Ressourcen aus Ihren Erweiterungsdateien in der
freigegebenen Speicherort des Geräts.
Sie dürfen die Erweiterungsdateien nicht löschen, verschieben oder umbenennen.
Wenn Ihre App kein bestimmtes Format erfordert, empfehlen wir Ihnen, ZIP-Dateien für Ihre Erweiterungsdateien und lesen Sie sie mit dem APK Expansion Zip Mediathek.
- Fügen Sie der Hauptaktivität Ihrer App eine Logik hinzu, die prüft, ob die Erweiterungsdateien
befinden sich beim Start auf dem Gerät. Wenn sich die Dateien nicht auf dem Gerät befinden, verwenden Sie den App-Lizenzierungsdienst von Google Play, um URLs anzufordern.
für die Erweiterungsdateien, laden Sie sie herunter und speichern Sie sie.
Um die Menge an Code, den Sie schreiben müssen, erheblich zu reduzieren und eine gute User Experience zu gewährleisten empfehlen wir dir, den Downloader zu verwenden, Bibliothek zum Implementieren des Downloadverhaltens.
Wenn Sie statt der Bibliothek einen eigenen Downloaddienst erstellen, Der Name der Erweiterungsdateien darf nicht geändert werden und sie müssen an der richtigen Speicherort.
Nachdem Sie Ihre App-Entwicklung abgeschlossen haben, folgen Sie der Anleitung zum Testen Ihre Erweiterungsdateien.
Regeln und Einschränkungen
Das Hinzufügen von APK-Erweiterungsdateien ist eine Funktion, die verfügbar ist, wenn du deine App über die Play Console Wenn Sie Ihre App zum ersten Mal hochladen oder eine App verwenden, die Erweiterungsdateien verwendet, müssen Sie die folgenden Regeln und Einschränkungen beachten:
- Eine Erweiterungsdatei darf nicht größer als 2 GB sein.
- Um Ihre Erweiterungsdateien bei Google Play herunterzuladen, muss der Nutzer Ihre App bei Google Play erworben haben. Google Play wird keine die URLs für Ihre Erweiterungsdateien angeben, falls die App auf andere Weise installiert wurde.
- Beim Download in Ihrer App wird die URL, die von Google Play stellt für jede Datei bereit, die für jeden Download eindeutig ist, und jeder Download läuft kurz nach seiner Bereitstellung ab. zu Ihrer App hinzufügen.
- Wenn Sie Ihre App mit einem neuen APK aktualisieren oder mehrere APKs für dasselbe APK hochladen App können Sie Erweiterungsdateien auswählen, die Sie für eine vorherige APK-Datei hochgeladen haben. Die Der Name der Erweiterungsdatei ändert sich nicht. Die vom APK empfangene Version wird beibehalten, mit der die Datei ursprünglich verknüpft war.
- Wenn Sie Erweiterungsdateien in Kombination mit mehreren APKs verwenden, um
unterschiedliche Erweiterungsdateien für verschiedene Geräte zur Verfügung stellen, müssen Sie dennoch separate APKs hochladen.
für jedes Gerät, um eine eindeutige
versionCode
und legen Sie verschiedene Filter für für jedes APK. - Du kannst kein Update deiner App durchführen, indem du die Erweiterungsdateien änderst
Laden Sie ein neues APK hoch, um Ihre App zu aktualisieren. Wenn Ihre Änderungen nur
die Assets in Ihren Erweiterungsdateien betreffen, können Sie Ihr APK aktualisieren, indem Sie
versionCode
(und vielleicht auch dieversionName
). - Speichere keine anderen Daten auf deinem
obb/
Verzeichnis. Wenn Sie einige Daten entpacken müssen, speichern Sie sie an dem durchgetExternalFilesDir()
angegebenen Speicherort. - Löschen Sie die Erweiterungsdatei
.obb
nicht und benennen Sie sie nicht um, es sei denn, Sie der Aktualisierung). Dies führt dazu, dass Google Play (oder Ihre App selbst) wiederholt laden Sie die Erweiterungsdatei herunter. - Wenn Sie eine Erweiterungsdatei manuell aktualisieren, müssen Sie die vorherige Erweiterungsdatei löschen.
Erweiterungsdateien herunterladen
In den meisten Fällen lädt Google Play Ihre Erweiterungsdateien herunter und speichert sie gleichzeitig auf dem Gerät. Zeitpunkt der Installation oder Aktualisierung des APK. So sind die Erweiterungsdateien verfügbar, wenn Ihre wenn die App zum ersten Mal veröffentlicht wird. In einigen Fällen muss Ihre App jedoch die Datei Erweiterungsdateien selbst, indem sie von einer URL angefordert werden, die Sie in einer Antwort erhalten. über den App-Lizenzierungsservice von Google Play.
Zum Herunterladen Ihrer Erweiterungsdateien benötigen Sie folgende grundlegende Logik:
- Suchen Sie beim Start der App im freigegebenen Speicher (in der
Android/obb/<package-name>/
-Verzeichnis).- Wenn die Erweiterungsdateien vorhanden sind, müssen Sie nichts weiter tun und Ihre App kann fortfahren.
- Wenn die Erweiterungsdateien nicht vorhanden sind:
<ph type="x-smartling-placeholder">
- </ph>
- Stellen Sie eine Anfrage über die App-Lizenzierung von Google Play, um Ihre die Namen, Größen und URLs von Erweiterungsdateien der App.
- Lade die Erweiterungsdateien über die von Google Play bereitgestellten URLs herunter und speichere sie
die Erweiterungsdateien. Sie müssen die Dateien am freigegebenen Speicherort speichern.
(
Android/obb/<package-name>/
) und verwenden Sie exakt den angegebenen Dateinamen. der Reaktion von Google Play.Hinweis:Die URL, die Google Play für Ihre Erweiterungsdateien sind für jeden Download eindeutig und laufen kurz nach der Übergabe an für Ihre App.
Wenn Ihre App kostenlos und keine kostenpflichtige App ist, haben Sie den App-Lizenzierungsdienst wahrscheinlich noch nicht genutzt. Hauptsächlich die Sie durchsetzen, Lizenzierungsrichtlinien für Ihre App und stellen Sie sicher, dass der Nutzer das Recht hat, Ihre App verwenden (er oder sie hat sie rechtmäßig bei Google Play bezahlt). Um die Erweiterungsdatei-Funktionalität wurde der Lizenzierungsservice erweitert, um eine Antwort zu Ihrer App hinzufügen, die die URL der Erweiterungsdateien enthält, die in Ihrer App gehostet werden bei Google Play. Auch wenn deine App für Nutzer kostenlos ist, musst du also die License Verification Library (LVL) zur Verwendung von APK-Erweiterungsdateien Wenn Ihre App ist kostenlos. Sie müssen keine Lizenzüberprüfung durchsetzen, sondern nur die um die Anfrage auszuführen, die die URL Ihrer Erweiterungsdateien zurückgibt.
Hinweis:Unabhängig davon, ob Ihre App kostenlos ist oder nicht, gibt die URLs der Erweiterungsdateien nur dann zurück, wenn der Nutzer Ihre App über Google Play erworben hat.
Neben der LVL benötigen Sie einen Codesatz, mit dem die Erweiterungsdateien heruntergeladen werden. über eine HTTP-Verbindung und speichert sie am richtigen Speicherort im freigegebenen Speicher des Geräts. Beim Einbinden dieses Verfahrens in Ihre App gibt es einige Probleme, die Sie berücksichtigen sollten. Kaufbereitschaft:
- Möglicherweise ist auf dem Gerät nicht genügend Speicherplatz für die Erweiterungsdateien vorhanden, daher sollten Sie prüfen, bevor Sie den Download starten und den Nutzer warnen, wenn nicht genügend Speicherplatz vorhanden ist.
- Dateidownloads sollten im Hintergrunddienst erfolgen, um den Nutzer nicht zu blockieren Interaktion und ermöglichen es dem Nutzer, die App während des Downloads zu verlassen.
- Während der Anforderung und des Downloads können verschiedene Fehler auftreten, die Sie an die Arbeit denken.
- Die Netzwerkverbindung kann sich während des Downloads ändern. Falls der Download unterbrochen wird, setzen Sie den Download nach Möglichkeit fort.
- Während der Download im Hintergrund erfolgt, sollten Sie eine Benachrichtigung bereitstellen, zeigt den Downloadfortschritt an, benachrichtigt den Nutzer, wenn er abgeschlossen ist, und leitet ihn zurück zu Ihre App auswählen.
Um Ihnen diese Arbeit zu erleichtern, haben wir die Downloader-Bibliothek entwickelt. das die Erweiterungsdateien an den Lizenzierungsservice anfordert, die Erweiterungsdateien herunterlädt, alle oben aufgeführten Aufgaben ausgeführt und ermöglicht sogar das Pausieren und Fortsetzen herunterladen. Durch das Hinzufügen der Downloader-Bibliothek und einiger Code-Hooks zu Ihrer App können fast alle dass die Erweiterungsdateien bereits für Sie codiert sind. Um die bestmögliche Leistung mit minimalem Aufwand für dich nutzerfreundlich ist, empfehlen wir dir, die Downloader Library zu verwenden, Ihre Erweiterungsdateien herunterladen. In den Informationen in den folgenden Abschnitten wird die Integration von Bibliothek in Ihre App einbinden.
Falls Sie lieber eine eigene Lösung zum Herunterladen der Erweiterungsdateien mithilfe der Google
Google Play-URLs aufrufen, müssen Sie der App
Dokumentation zur Lizenzierung, um eine Lizenzanfrage durchzuführen. Anschließend können Sie die Namen der Erweiterungsdateien abrufen.
Größen und URLs aus den Antwortextras. Sie sollten die Klasse APKExpansionPolicy
(in der Library zur Lizenzüberprüfung) als Lizenzierung verwenden
, die die Namen, Größen und URLs der Erweiterungsdateien des Lizenzierungsdienstes erfasst.
Downloader-Bibliothek
Um APK-Erweiterungsdateien mit Ihrer App zu verwenden und eine optimale Nutzererfahrung mit für dich mit minimalem Aufwand. Wir empfehlen dir, die Downloader Library zu verwenden, die in der Paket der APK-Erweiterungsbibliothek für Google Play Diese Bibliothek lädt Ihre Erweiterungsdateien Hintergrunddienst, zeigt eine Nutzerbenachrichtigung mit dem Downloadstatus an, verarbeitet die Netzwerkverbindung und den Download nach Möglichkeit fortsetzen.
So implementieren Sie Downloads von Erweiterungsdateien mithilfe der Downloader-Bibliothek:
- Erweitern Sie eine spezielle
Service
- und eineBroadcastReceiver
-Unterklasse, die jeweils nur wenige Codezeilen von Ihnen. - Fügen Sie Ihrer Hauptaktivität Logik hinzu, die prüft, ob die Erweiterungsdateien bereits heruntergeladen wurde. Falls nicht, wird der Download-Prozess aufgerufen und eine Meldung mit einem Fortschritts-UI.
- Implementieren Sie eine Callback-Oberfläche mit einigen Methoden in Ihrer Hauptaktivität, erhält Updates zum Downloadfortschritt.
In den folgenden Abschnitten wird erläutert, wie Sie Ihre App mithilfe der Downloader-Bibliothek einrichten.
Verwendung der Downloader-Bibliothek vorbereiten
Um die Downloader-Bibliothek zu verwenden, musst du zwei Pakete aus dem SDK Manager herunterladen und die entsprechenden Bibliotheken
Öffnen Sie zuerst den Android SDK Manager (Tools > SDK-Manager) und unter Darstellung und Verhalten > Systemeinstellungen > Android SDK, wählen Sie Tab SDK-Tools, um Folgendes auszuwählen und herunterzuladen:
- Paket mit der Google Play-Lizenzierungsbibliothek
- Paket der APK-Erweiterungsbibliothek für Google Play
Neues Bibliotheksmodul für die Lizenzüberprüfungsbibliothek und den Downloader erstellen Mediathek. Für jede Bibliothek:
- Wählen Sie Datei > Neu > Neues Modul.
- Wähle im Fenster Create New Module (Neues Modul erstellen) die Option Android Library (Android-Bibliothek) aus. und wähle dann Weiter aus.
- Geben Sie einen Namen für die App oder Bibliothek an, z. B. „Google Play-Lizenzbibliothek“. und „Google Play Downloader Library“, wählen Sie Minimum SDK Level (Mindest-SDK-Level) und dann Fertigstellen.
- Wählen Sie Datei > Projektstruktur.
- Wählen Sie den Tab Eigenschaften und dann in der Bibliothek
Repository: Geben Sie die Bibliothek aus dem Verzeichnis
<sdk>/extras/google/
ein. (play_licensing/
für die License Verification Library oderplay_apk_expansion/downloader_library/
für die Downloader Library). - Wählen Sie OK aus, um das neue Modul zu erstellen.
Hinweis:Die Downloader-Bibliothek hängt von der Lizenz ab. Verifizierungsbibliothek. Fügen Sie unbedingt die Lizenz hinzu „Überprüfungsbibliothek“ auf die Projekteigenschaften der Downloader-Bibliothek.
Alternativ können Sie über eine Befehlszeile Ihr Projekt so aktualisieren, dass es die Bibliotheken enthält:
- Wechseln Sie in das Verzeichnis
<sdk>/tools/
. - Führen Sie
android update project
mit der Option--library
aus, um LVL und die Downloader-Bibliothek in Ihr Projekt. Hier einige Beispiele:android update project --path ~/Android/MyApp \ --library ~/android_sdk/extras/google/market_licensing \ --library ~/android_sdk/extras/google/market_apk_expansion/downloader_library
Wenn Sie die Bibliothek für die Lizenzüberprüfung und die Downloader Library App haben, können Sie die Möglichkeit zum Herunterladen von Erweiterungsdateien aus Google Play Das Format, das Sie für die Erweiterungsdateien auswählen, und die Art und Weise, wie sie gelesen werden vom freigegebenen Speicher ist eine separate Implementierung, die Sie aufgrund Ihres App-Anforderungen.
Tipp:Das APK-Erweiterungspaket enthält ein Beispiel App in dem erklärt wird, wie die Downloader-Bibliothek in einer App verwendet wird. Im Beispiel wird eine dritte Bibliothek verwendet. die im APK-Erweiterungspaket namens "APK Expansion Zip Library" verfügbar ist. Wenn Sie planen, für Ihre Erweiterungsdateien verwenden, sollten Sie auch die APK Expansion Zip Library zu für Ihre App. Weitere Informationen finden Sie im folgenden Abschnitt. zur Verwendung der APK Expansion Zip Library
Nutzerberechtigungen deklarieren
Zum Herunterladen der Erweiterungsdateien enthält die Downloader Library erfordert mehrere Berechtigungen, die Sie in der Manifestdatei Ihrer App deklarieren müssen. Sie sind:
<manifest ...> <!-- Required to access Google Play Licensing --> <uses-permission android:name="com.android.vending.CHECK_LICENSE" /> <!-- Required to download files from Google Play --> <uses-permission android:name="android.permission.INTERNET" /> <!-- Required to keep CPU alive while downloading files (NOT to keep screen awake) --> <uses-permission android:name="android.permission.WAKE_LOCK" /> <!-- Required to poll the state of the network connection and respond to changes --> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <!-- Required to check whether Wi-Fi is enabled --> <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/> <!-- Required to read and write the expansion files on shared storage --> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> ... </manifest>
Hinweis:Standardmäßig erfordert die Downloader Library eine API. Ebene 4, aber die APK Expansion Zip Library erfordert API-Level 5.
Downloader-Dienst implementieren
Um Downloads im Hintergrund ausführen zu können, stellt die Downloader Library ihre
eigene abgeleitete Service
-Klasse namens DownloaderService
, die Sie erweitern sollten. In
hat der DownloaderService
nicht nur die Erweiterungsdateien für Sie heruntergeladen, sondern auch Folgendes:
- Registriert einen
BroadcastReceiver
, der auf Änderungen am die Netzwerkverbindung des Geräts (CONNECTIVITY_ACTION
Übertragung) verwenden, um den Download bei Bedarf (z. B. bei Verbindungsverlust) zu unterbrechen, und Setzen Sie den Download nach Möglichkeit fort (Verbindung wird hergestellt). - Plant einen
RTC_WAKEUP
-Wecker, um den Download zu wiederholen für in denen der Dienst beendet wird. - Erstellt eine benutzerdefinierte
Notification
, die den Downloadfortschritt anzeigt und Fehler oder Statusänderungen zu erkennen. - Ermöglicht Ihrer App, den Download manuell anzuhalten und fortzusetzen.
- Überprüft, ob der freigegebene Speicher bereitgestellt und verfügbar ist bzw. dass die Dateien noch nicht vorhanden sind. und dass genügend Speicherplatz vorhanden ist, bevor Sie die Erweiterungsdateien herunterladen. Der Nutzer wird dann wenn einer dieser Punkte nicht zutrifft.
Sie müssen lediglich eine Klasse in Ihrer App erstellen, die die DownloaderService
-Klasse erweitert, und drei Methoden überschreiben, um bestimmte App-Details anzugeben:
getPublicKey()
- Es muss ein String zurückgegeben werden, der der Base64-codierte öffentliche RSA-Schlüssel für Ihren Publisher ist. -Konto, verfügbar über die Profilseite in der Play Console (siehe Einrichtung der Lizenzierung).
getSALT()
- Es muss ein Array von zufälligen Byte zurückgegeben werden, die die Lizenzierung
Policy
verwendet, um erstellen Sie einObfuscator
. Das Salz sorgt dafür, dass deine verschleiertenSharedPreferences
Datei, in der Ihre Lizenzierungsdaten gespeichert sind, sind eindeutig und nicht auffindbar. getAlarmReceiverClassName()
- Hierbei muss der Klassenname der
BroadcastReceiver
in die den Alarm empfangen soll, der besagt, dass der Download neu gestartet. Dies kann passieren, wenn der Downloader-Dienst unerwartet beendet wird.
Hier ein Beispiel einer vollständigen Implementierung von DownloaderService
:
Kotlin
// You must use the public key belonging to your publisher account const val BASE64_PUBLIC_KEY = "YourLVLKey" // You should also modify this salt val SALT = byteArrayOf( 1, 42, -12, -1, 54, 98, -100, -12, 43, 2, -8, -4, 9, 5, -106, -107, -33, 45, -1, 84 ) class SampleDownloaderService : DownloaderService() { override fun getPublicKey(): String = BASE64_PUBLIC_KEY override fun getSALT(): ByteArray = SALT override fun getAlarmReceiverClassName(): String = SampleAlarmReceiver::class.java.name }
Java
public class SampleDownloaderService extends DownloaderService { // You must use the public key belonging to your publisher account public static final String BASE64_PUBLIC_KEY = "YourLVLKey"; // You should also modify this salt public static final byte[] SALT = new byte[] { 1, 42, -12, -1, 54, 98, -100, -12, 43, 2, -8, -4, 9, 5, -106, -107, -33, 45, -1, 84 }; @Override public String getPublicKey() { return BASE64_PUBLIC_KEY; } @Override public byte[] getSALT() { return SALT; } @Override public String getAlarmReceiverClassName() { return SampleAlarmReceiver.class.getName(); } }
Hinweis: Sie müssen den Wert BASE64_PUBLIC_KEY
aktualisieren.
ist der öffentliche Schlüssel, der zu Ihrem Publisher-Konto gehört. Den Schlüssel finden Sie in der
Console unter Ihren Profilinformationen. Dies ist auch beim Testen
Ihre Downloads.
Denken Sie daran, den Dienst in Ihrer Manifestdatei zu deklarieren:
<app ...> <service android:name=".SampleDownloaderService" /> ... </app>
Alarmempfänger implementieren
Um den Fortschritt des Dateidownloads zu beobachten und den Download bei Bedarf neu zu starten,
DownloaderService
richtet einen RTC_WAKEUP
-Wecker ein, der
liefert Intent
für BroadcastReceiver
in Ihrem
Sie müssen die BroadcastReceiver
definieren, um eine API aufzurufen
aus der Downloader Library, die den Status des Downloads prüft und neu startet
wenn nötig.
Sie müssen lediglich die Methode onReceive()
überschreiben, um DownloaderClientMarshaller.startDownloadServiceIfRequired()
aufzurufen.
Beispiel:
Kotlin
class SampleAlarmReceiver : BroadcastReceiver() { override fun onReceive(context: Context, intent: Intent) { try { DownloaderClientMarshaller.startDownloadServiceIfRequired( context, intent, SampleDownloaderService::class.java ) } catch (e: PackageManager.NameNotFoundException) { e.printStackTrace() } } }
Java
public class SampleAlarmReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { try { DownloaderClientMarshaller.startDownloadServiceIfRequired(context, intent, SampleDownloaderService.class); } catch (NameNotFoundException e) { e.printStackTrace(); } } }
Beachten Sie, dass dies die Klasse ist, für die Sie den Namen zurückgeben müssen.
in der getAlarmReceiverClassName()
-Methode Ihres Dienstes ein (siehe vorherigen Abschnitt).
Denk daran, den Empfänger in deiner Manifestdatei zu deklarieren:
<app ...> <receiver android:name=".SampleAlarmReceiver" /> ... </app>
Download wird gestartet
Die Hauptaktivität in Ihrer App (die durch das Launcher-Symbol gestartet wird) ist ist für die Überprüfung, ob die Erweiterungsdateien bereits auf dem Gerät vorhanden sind, und die Initiierung falls dies nicht der Fall ist.
Um den Download über die Downloader-Bibliothek zu starten, ist Folgendes erforderlich: Verfahren:
- Prüfen Sie, ob die Dateien heruntergeladen wurden.
Die Downloader-Bibliothek enthält einige APIs in der Klasse
Helper
, um Hilfe bei diesem Prozess:getExpansionAPKFileName(Context, c, boolean mainFile, int versionCode)
doesFileExist(Context c, String fileName, long fileSize)
Beispiel: Die im APK-Erweiterungspaket enthaltene Beispiel-App ruft die die folgende Methode in der
onCreate()
-Methode der Aktivität, Gibt an, ob die Erweiterungsdateien bereits auf dem Gerät vorhanden sind:Kotlin
fun expansionFilesDelivered(): Boolean { xAPKS.forEach { xf -> Helpers.getExpansionAPKFileName(this, xf.isBase, xf.fileVersion).also { fileName -> if (!Helpers.doesFileExist(this, fileName, xf.fileSize, false)) return false } } return true }
Java
boolean expansionFilesDelivered() { for (XAPKFile xf : xAPKS) { String fileName = Helpers.getExpansionAPKFileName(this, xf.isBase, xf.fileVersion); if (!Helpers.doesFileExist(this, fileName, xf.fileSize, false)) return false; } return true; }
In diesem Fall enthält jedes
XAPKFile
-Objekt die Versionsnummer und Dateigröße einer bekannten Erweiterungsdatei und einem booleschen Wert, der angibt, ob es sich um die Haupterweiterungsdatei handelt. (Siehe BeispielSampleDownloaderActivity
der App.)Wenn diese Methode „false“ zurückgibt, muss der Download der Anwendung beginnen.
- Starten Sie den Download durch Aufrufen der statischen Methode
DownloaderClientMarshaller.startDownloadServiceIfRequired(Context c, PendingIntent notificationClient, Class<?> serviceClass)
.Die Methode nimmt folgende Parameter an:
context
: DieContext
deiner App.notificationClient
: EinPendingIntent
zum Starten deines Haupt- Aktivitäten. Dieser wird in derNotification
verwendet, die vomDownloaderService
erstellt, um den Downloadfortschritt anzuzeigen. Wenn der Nutzer die Benachrichtigung auswählt, Ruft diePendingIntent
auf, die Sie hier angeben, und sollte die Aktivität öffnen der den Downloadfortschritt anzeigt (normalerweise die Aktivität, mit der der Download gestartet wurde).serviceClass
: DasClass
-Objekt für die Implementierung vonDownloaderService
, um den Dienst zu starten und gegebenenfalls den Download zu starten.
Die Methode gibt eine Ganzzahl zurück, ob der Download erforderlich ist. Mögliche Werte sind:
NO_DOWNLOAD_REQUIRED
: Wird zurückgegeben, wenn die Dateien bereits existieren oder ein Download läuft.LVL_CHECK_REQUIRED
: Wird zurückgegeben, wenn eine Lizenzüberprüfung erfolgt ist. erforderlich, um die URLs der Erweiterungsdateien zu erhalten.DOWNLOAD_REQUIRED
: Wird zurückgegeben, wenn die URLs der Erweiterungsdateien bereits bekannt sind. aber nicht heruntergeladen wurden.
Das Verhalten für
LVL_CHECK_REQUIRED
undDOWNLOAD_REQUIRED
entspricht im Wesentlichen und Sie müssen sich darüber keine Gedanken machen. In deiner Hauptaktivität, diestartDownloadServiceIfRequired()
aufruft, kannst du einfach prüfen, ob die AntwortNO_DOWNLOAD_REQUIRED
ist. Wenn die Antwort nichtNO_DOWNLOAD_REQUIRED
ist, der Downloader-Bibliothek beginnt und Sie sollten Ihre Aktivitäts-UI so aktualisieren: Downloadfortschritt anzeigen (siehe nächster Schritt). Wenn die Antwort istNO_DOWNLOAD_REQUIRED
, sind die Dateien verfügbar und Ihre Anwendung kann gestartet werden.Beispiel:
Kotlin
override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) // Check if expansion files are available before going any further if (!expansionFilesDelivered()) { val pendingIntent = // Build an Intent to start this activity from the Notification Intent(this, MainActivity::class.java).apply { flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TOP }.let { notifierIntent -> PendingIntent.getActivity( this, 0, notifierIntent, PendingIntent.FLAG_UPDATE_CURRENT ) } // Start the download service (if required) val startResult: Int = DownloaderClientMarshaller.startDownloadServiceIfRequired( this, pendingIntent, SampleDownloaderService::class.java ) // If download has started, initialize this activity to show // download progress if (startResult != DownloaderClientMarshaller.NO_DOWNLOAD_REQUIRED) { // This is where you do set up to display the download // progress (next step) ... return } // If the download wasn't necessary, fall through to start the app } startApp() // Expansion files are available, start the app }
Java
@Override public void onCreate(Bundle savedInstanceState) { // Check if expansion files are available before going any further if (!expansionFilesDelivered()) { // Build an Intent to start this activity from the Notification Intent notifierIntent = new Intent(this, MainActivity.getClass()); notifierIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP); ... PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, notifierIntent, PendingIntent.FLAG_UPDATE_CURRENT); // Start the download service (if required) int startResult = DownloaderClientMarshaller.startDownloadServiceIfRequired(this, pendingIntent, SampleDownloaderService.class); // If download has started, initialize this activity to show // download progress if (startResult != DownloaderClientMarshaller.NO_DOWNLOAD_REQUIRED) { // This is where you do set up to display the download // progress (next step) ... return; } // If the download wasn't necessary, fall through to start the app } startApp(); // Expansion files are available, start the app }
- Wenn die Methode
startDownloadServiceIfRequired()
etwas anderes alsNO_DOWNLOAD_REQUIRED
, erstellen Sie eine Instanz vonIStub
, indem SieDownloaderClientMarshaller.CreateStub(IDownloaderClient client, Class<?> downloaderService)
aufrufen.IStub
stellt eine Bindung zwischen deiner Aktivität und dem Downloader her. -Dienst, sodass Ihre Aktivität Rückrufe über den Download-Fortschritt empfängt.Um
IStub
durch Aufrufen vonCreateStub()
zu instanziieren, müssen Sie sie übergeben eine Implementierung derIDownloaderClient
-Schnittstelle und IhresDownloaderService
Implementierung. Im nächsten Abschnitt Downloadfortschritt erhalten wird dies DieIDownloaderClient
-Schnittstelle, die du normalerweise in deinerActivity
-Klasse implementieren solltest, damit du die Aktivitäts-UI aktualisieren kannst, wenn sich der Downloadstatus ändert.Wir empfehlen,
CreateStub()
aufzurufen, um dieIStub
während deronCreate()
-Methode deiner Aktivität nach demstartDownloadServiceIfRequired()
zu instanziieren startet den Download.Im vorherigen Codebeispiel für
onCreate()
können Sie auf dasstartDownloadServiceIfRequired()
-Ergebnis beispielsweise so antworten:Kotlin
// Start the download service (if required) val startResult = DownloaderClientMarshaller.startDownloadServiceIfRequired( this@MainActivity, pendingIntent, SampleDownloaderService::class.java ) // If download has started, initialize activity to show progress if (startResult != DownloaderClientMarshaller.NO_DOWNLOAD_REQUIRED) { // Instantiate a member instance of IStub downloaderClientStub = DownloaderClientMarshaller.CreateStub(this, SampleDownloaderService::class.java) // Inflate layout that shows download progress setContentView(R.layout.downloader_ui) return }
Java
// Start the download service (if required) int startResult = DownloaderClientMarshaller.startDownloadServiceIfRequired(this, pendingIntent, SampleDownloaderService.class); // If download has started, initialize activity to show progress if (startResult != DownloaderClientMarshaller.NO_DOWNLOAD_REQUIRED) { // Instantiate a member instance of IStub downloaderClientStub = DownloaderClientMarshaller.CreateStub(this, SampleDownloaderService.class); // Inflate layout that shows download progress setContentView(R.layout.downloader_ui); return; }
Nachdem die Methode
onCreate()
zurückgegeben wurde, wird Ihre Aktivität erhält einen Anruf anonResume()
. Anschließend sollten Sie Rufen Sieconnect()
auf derIStub
auf und übergeben Sie dieContext
Ihrer App. Umgekehrt sollten Siedisconnect()
imonStop()
-Callback deiner Aktivität.Kotlin
override fun onResume() { downloaderClientStub?.connect(this) super.onResume() } override fun onStop() { downloaderClientStub?.disconnect(this) super.onStop() }
Java
@Override protected void onResume() { if (null != downloaderClientStub) { downloaderClientStub.connect(this); } super.onResume(); } @Override protected void onStop() { if (null != downloaderClientStub) { downloaderClientStub.disconnect(this); } super.onStop(); }
Durch den Aufruf von
connect()
amIStub
wird Ihre Aktivität an dieDownloaderService
gebunden, sodass Ihre Aktivität Callbacks bezüglich Änderungen am Download erhält. über dieIDownloaderClient
-Schnittstelle.
Downloadfortschritt wird empfangen
Um Updates zum Downloadfortschritt zu erhalten und mit der DownloaderService
zu interagieren, musst du die IDownloaderClient
-Schnittstelle der Downloader-Bibliothek implementieren.
Die Aktivität, mit der Sie den Download starten,
sollte diese Schnittstelle in der Regel implementieren,
um den Downloadfortschritt anzuzeigen und Anfragen an den Dienst zu senden.
Die erforderlichen Schnittstellenmethoden für IDownloaderClient
sind:
onServiceConnected(Messenger m)
- Nachdem Sie die
IStub
in Ihrer Aktivität instanziiert haben, erhalten Sie einen Aufruf an diese , die einMessenger
-Objekt übergibt, das mit der Instanz verbunden ist. vonDownloaderService
. Zum Senden von Anfragen an den Dienst, z. B. zum Pausieren und Fortsetzen heruntergeladen wird, musst duDownloaderServiceMarshaller.CreateProxy()
aufrufen, um dieIDownloaderService
-Schnittstelle zu empfangen, die mit dem Dienst verbunden ist.Eine empfohlene Implementierung sieht so aus:
Kotlin
private var remoteService: IDownloaderService? = null ... override fun onServiceConnected(m: Messenger) { remoteService = DownloaderServiceMarshaller.CreateProxy(m).apply { downloaderClientStub?.messenger?.also { messenger -> onClientUpdated(messenger) } } }
Java
private IDownloaderService remoteService; ... @Override public void onServiceConnected(Messenger m) { remoteService = DownloaderServiceMarshaller.CreateProxy(m); remoteService.onClientUpdated(downloaderClientStub.getMessenger()); }
Wenn das
IDownloaderService
-Objekt initialisiert ist, können Sie Befehle an die Downloaddienst, beispielsweise zum Pausieren und Fortsetzen des Downloads (requestPauseDownload()
undrequestContinueDownload()
). onDownloadStateChanged(int newState)
- Der Downloaddienst ruft dies auf, wenn sich der Downloadstatus ändert, z. B. die
der Download beginnt oder
vollständig abgeschlossen ist.
Der Wert
newState
ist einer von mehreren möglichen Werten, die in durch eine derSTATE_*
-Konstanten derIDownloaderClient
-Klasse.Sie können einen entsprechenden String anfordern, um Ihren Nutzern eine hilfreiche Nachricht zur Verfügung zu stellen für jeden Bundesstaat durch Aufrufen von
Helpers.getDownloaderStringResourceIDFromState()
. Dieses gibt die Ressourcen-ID für einen der mit dem Downloader gebündelten Strings zurück. Mediathek. Beispiel: Der String „Download aufgrund von Roaming pausiert“ entsprichtSTATE_PAUSED_ROAMING
. onDownloadProgress(DownloadProgressInfo progress)
- Der Downloaddienst ruft dies auf, um ein
DownloadProgressInfo
-Objekt bereitzustellen. Sie enthält verschiedene Informationen zum Downloadfortschritt, darunter die geschätzte verbleibende Zeit, die aktuelle Geschwindigkeit, den Gesamtfortschritt und den Gesamtwert, sodass Sie die Benutzeroberfläche für den Downloadfortschritt aktualisieren können.
Tipp:Beispiele für diese Callbacks, die den Download aktualisieren
siehe SampleDownloaderActivity
in der Beispiel-App, die mit dem
APK-Erweiterungspaket.
Einige öffentliche Methoden für die IDownloaderService
-Schnittstelle, die Sie möglicherweise nützlich finden, sind:
requestPauseDownload()
- Haltt den Download an.
requestContinueDownload()
- Setzt einen pausierten Download fort.
setDownloadFlags(int flags)
- Hiermit werden die Nutzereinstellungen für Netzwerktypen festgelegt, von denen das Herunterladen der Dateien erlaubt wird. Die
Die aktuelle Implementierung unterstützt nur das Flag
FLAGS_DOWNLOAD_OVER_CELLULAR
. Sie können jedoch andere. Standardmäßig ist dieses Flag nicht aktiviert, d. h., der Nutzer muss zum Herunterladen eine WLAN-Verbindung haben. Erweiterungsdateien. Sie können festlegen, dass Downloads über mit dem Mobilfunknetz verbunden. Rufen Sie in diesem Fall folgende Nummer an:Kotlin
remoteService = DownloaderServiceMarshaller.CreateProxy(m).apply { ... setDownloadFlags(IDownloaderService.FLAGS_DOWNLOAD_OVER_CELLULAR) }
Java
remoteService .setDownloadFlags(IDownloaderService.FLAGS_DOWNLOAD_OVER_CELLULAR);
APKExpansionPolicy verwenden
Wenn Sie sich dafür entscheiden, einen eigenen Downloader-Dienst zu entwickeln, anstatt Google Play zu verwenden
Downloader Library, solltest du weiterhin die APKExpansionPolicy
aus der Bibliothek für die Lizenzüberprüfung verwenden. Die Klasse APKExpansionPolicy
ist fast identisch mit ServerManagedPolicy
(verfügbar in der
Google Play License Verification Library, enthält aber zusätzliche Abläufe für die APK-Erweiterung
Extras für Dateiantworten.
Hinweis:Wenn Sie die Downloader-Bibliothek wie im vorherigen Abschnitt beschrieben verwenden,
alle Interaktionen mit der APKExpansionPolicy
-Bibliothek vornehmen. Sie müssen
direkt in diesen Kurs.
Die Klasse enthält Methoden, mit denen Sie die erforderlichen Informationen Erweiterungsdateien:
getExpansionURLCount()
getExpansionURL(int index)
getExpansionFileName(int index)
getExpansionFileSize(int index)
Weitere Informationen zur Verwendung von APKExpansionPolicy
, wenn nicht
über die Downloader-Bibliothek finden Sie in der Dokumentation zum Hinzufügen der Lizenzierung zu Ihrer App.
in dem erklärt wird, wie eine Lizenzrichtlinie wie diese implementiert wird.
Erweiterungsdatei lesen
Wenn deine APK-Erweiterungsdateien auf dem Gerät gespeichert sind,
hängt davon ab, welchen Dateityp Sie verwenden. Wie in der Übersicht erläutert,
Erweiterungsdateien können jede Art von Datei sein,
aber mit einem bestimmten Dateinamenformat umbenannt und unter folgendem Pfad gespeichert:
<shared-storage>/Android/obb/<package-name>/
Unabhängig davon, wie Sie Ihre Dateien lesen, sollten Sie immer zuerst prüfen, ob die externen Dateien Speicherplatz zum Lesen verfügbar ist. Es kann vorkommen, dass der Speicherplatz Computer über USB angeschlossen oder die SD-Karte entfernt hat.
Hinweis:Beim Starten Ihrer App sollten Sie immer prüfen,
Der externe Speicherplatz ist verfügbar und kann durch Aufrufen von getExternalStorageState()
gelesen werden. Dadurch wird einer von mehreren möglichen Strings zurückgegeben.
die den Status des externen Speichers darstellen. Damit die Daten in Ihrem Konto
App verwenden, muss der Rückgabewert MEDIA_MOUNTED
sein.
Dateinamen abrufen
Wie in der Übersicht beschrieben, werden Ihre APK-Erweiterungsdateien gespeichert mit einem bestimmten Dateinamensformat:
[main|patch].<expansion-version>.<package-name>.obb
Verwenden Sie zum Abrufen des Speicherorts und der Namen Ihrer Erweiterungsdateien die Methode
getExternalStorageDirectory()
und getPackageName()
, um den Pfad zu Ihren Dateien zu erstellen.
Mit dieser Methode können Sie in Ihrer App ein Array abrufen, das den vollständigen Pfad enthält. auf beide Erweiterungsdateien:
Kotlin
fun getAPKExpansionFiles(ctx: Context, mainVersion: Int, patchVersion: Int): Array<String> { val packageName = ctx.packageName val ret = mutableListOf<String>() if (Environment.getExternalStorageState() == Environment.MEDIA_MOUNTED) { // Build the full path to the app's expansion files val root = Environment.getExternalStorageDirectory() val expPath = File(root.toString() + EXP_PATH + packageName) // Check that expansion file path exists if (expPath.exists()) { if (mainVersion > 0) { val strMainPath = "$expPath${File.separator}main.$mainVersion.$packageName.obb" val main = File(strMainPath) if (main.isFile) { ret += strMainPath } } if (patchVersion > 0) { val strPatchPath = "$expPath${File.separator}patch.$mainVersion.$packageName.obb" val main = File(strPatchPath) if (main.isFile) { ret += strPatchPath } } } } return ret.toTypedArray() }
Java
// The shared path to all app expansion files private final static String EXP_PATH = "/Android/obb/"; static String[] getAPKExpansionFiles(Context ctx, int mainVersion, int patchVersion) { String packageName = ctx.getPackageName(); Vector<String> ret = new Vector<String>(); if (Environment.getExternalStorageState() .equals(Environment.MEDIA_MOUNTED)) { // Build the full path to the app's expansion files File root = Environment.getExternalStorageDirectory(); File expPath = new File(root.toString() + EXP_PATH + packageName); // Check that expansion file path exists if (expPath.exists()) { if ( mainVersion > 0 ) { String strMainPath = expPath + File.separator + "main." + mainVersion + "." + packageName + ".obb"; File main = new File(strMainPath); if ( main.isFile() ) { ret.add(strMainPath); } } if ( patchVersion > 0 ) { String strPatchPath = expPath + File.separator + "patch." + mainVersion + "." + packageName + ".obb"; File main = new File(strPatchPath); if ( main.isFile() ) { ret.add(strPatchPath); } } } } String[] retArray = new String[ret.size()]; ret.toArray(retArray); return retArray; }
Sie können diese Methode aufrufen, indem Sie sie an Ihre App Context
übergeben.
und die Version der gewünschten Erweiterungsdatei.
Es gibt viele Möglichkeiten, die Versionsnummer der Erweiterungsdatei zu ermitteln. Eine einfache Möglichkeit besteht darin,
die Version zu Beginn des Downloads in einer SharedPreferences
-Datei speichern, indem Sie
Abfrage des Namens der Erweiterungsdatei mit der Methode getExpansionFileName(int index)
der Klasse APKExpansionPolicy
. Sie können dann den Versionscode abrufen, indem Sie die Datei SharedPreferences
lesen, wenn Sie auf die Erweiterung zugreifen möchten
-Datei.
Weitere Informationen zum Auslesen aus dem freigegebenen Speicher finden Sie im Abschnitt zur Datenspeicherung. Dokumentation.
Verwenden der APK Expansion Zip-Bibliothek
Das APK-Erweiterungspaket für Google Market enthält eine APK-Bibliothek.
Erweiterungs-Zip-Bibliothek (in <sdk>/extras/google/google_market_apk_expansion/zip_file/
). Dies ist eine optionale Bibliothek,
können Sie die Erweiterung
wenn sie als ZIP-Dateien gespeichert werden. Mit dieser Bibliothek können Sie ganz einfach Ressourcen aus
ZIP-Erweiterungsdateien als virtuelles Dateisystem.
Die APK Expansion Zip-Bibliothek enthält die folgenden Klassen und APIs:
APKExpansionSupport
- Bietet einige Methoden für den Zugriff auf Namen von Erweiterungsdateien und ZIP-Dateien:
<ph type="x-smartling-placeholder">
- </ph>
getAPKExpansionFiles()
- Dieselbe Methode wie oben, bei der der vollständige Dateipfad sowohl an die Erweiterung Dateien.
getAPKExpansionZipFile(Context ctx, int mainVersion, int patchVersion)
- Gibt eine
ZipResourceFile
zurück, die die Summe aus Hauptdatei und Patch-Datei. Wenn Sie also sowohl dasmainVersion
als auch daspatchVersion
, wird einZipResourceFile
zurückgegeben, das Lesezugriff auf alle Daten, wobei die Daten der Patchdatei über der Hauptdatei zusammengeführt wurden.
ZipResourceFile
- Repräsentiert eine ZIP-Datei im freigegebenen Speicher und führt alle erforderlichen Schritte für die Bereitstellung einer virtuellen
basierend auf Ihren ZIP-Dateien. Sie können eine Instanz mit
APKExpansionSupport.getAPKExpansionZipFile()
oder mit demZipResourceFile
abrufen, indem Sie die Pfad zu Ihrer Erweiterungsdatei. Diese Klasse umfasst eine Vielzahl nützlicher Methoden. In der Regel auf die meisten von ihnen nicht zugreifen. Einige wichtige Methoden sind: <ph type="x-smartling-placeholder">- </ph>
getInputStream(String assetPath)
- Stellt ein
InputStream
zum Lesen einer Datei in der ZIP-Datei bereit. DieassetPath
muss der Pfad zur gewünschten Datei sein, relativ zu das Stammverzeichnis des Inhalts der ZIP-Datei. getAssetFileDescriptor(String assetPath)
- Stellt ein
AssetFileDescriptor
für eine Datei im ZIP-Datei.assetPath
muss der Pfad zur gewünschten Datei sein, relativ zu das Stammverzeichnis des Inhalts der ZIP-Datei. Dies ist bei bestimmten Android-APIs nützlich, die eineAssetFileDescriptor
erfordern, z. B. einigeMediaPlayer
-APIs.
APEZProvider
- Die meisten Apps benötigen diesen Kurs nicht. Diese Klasse definiert ein
ContentProvider
, das die Daten aus den ZIP-Dateien über einen Inhalt verteilt.Uri
, um Dateizugriff für bestimmte Android-APIs bereitzustellen, dieUri
-Zugriff auf Mediendateien. Dies ist beispielsweise nützlich, wenn Sie Spiel ein Video mitVideoView.setVideoURI()
ab.
ZIP-Komprimierung von Mediendateien überspringen
Auch wenn Sie Ihre Erweiterungsdateien zum Speichern von Mediendateien verwenden, können Sie mit einer ZIP-Datei
Android-Anrufe für die Medienwiedergabe verwenden, die Versatz- und Längensteuerung ermöglichen (z. B. MediaPlayer.setDataSource()
und
SoundPool.load()
). Damit
Damit dies funktioniert, dürfen die Mediendateien beim Erstellen der ZIP-Datei nicht zusätzlich komprimiert werden.
Pakete. Wenn Sie beispielsweise das zip
-Tool verwenden, sollten Sie das -n
-Tool verwenden.
zur Angabe der Dateisuffixe, die nicht komprimiert werden sollen:
zip -n .mp4;.ogg main_expansion media_files
Aus einer ZIP-Datei lesen
Wenn Sie die APK Expansion Zip Library verwenden, benötigen Sie zum Lesen einer Datei aus Ihrer ZIP-Datei in der Regel die Folgendes:
Kotlin
// Get a ZipResourceFile representing a merger of both the main and patch files val expansionFile = APKExpansionSupport.getAPKExpansionZipFile(appContext, mainVersion, patchVersion) // Get an input stream for a known file inside the expansion file ZIPs expansionFile.getInputStream(pathToFileInsideZip).use { ... }
Java
// Get a ZipResourceFile representing a merger of both the main and patch files ZipResourceFile expansionFile = APKExpansionSupport.getAPKExpansionZipFile(appContext, mainVersion, patchVersion); // Get an input stream for a known file inside the expansion file ZIPs InputStream fileStream = expansionFile.getInputStream(pathToFileInsideZip);
Der obige Code bietet Zugriff auf jede Datei, die entweder in Ihrer Haupt-Erweiterungsdatei oder in
Patch-Erweiterungsdatei, indem alle Dateien aus beiden Dateien aus einer zusammengeführten Zuordnung gelesen werden. Alles für dich
die getAPKExpansionFile()
-Methode deine App-android.content.Context
und die Versionsnummer für die Haupterweiterungsdatei und den Patch angeben müssen.
Erweiterungsdatei.
Wenn Sie lieber aus einer bestimmten Erweiterungsdatei lesen möchten, können Sie den ZipResourceFile
-Konstruktor mit dem Pfad zur gewünschten Erweiterungsdatei verwenden:
Kotlin
// Get a ZipResourceFile representing a specific expansion file val expansionFile = ZipResourceFile(filePathToMyZip) // Get an input stream for a known file inside the expansion file ZIPs expansionFile.getInputStream(pathToFileInsideZip).use { ... }
Java
// Get a ZipResourceFile representing a specific expansion file ZipResourceFile expansionFile = new ZipResourceFile(filePathToMyZip); // Get an input stream for a known file inside the expansion file ZIPs InputStream fileStream = expansionFile.getInputStream(pathToFileInsideZip);
Weitere Informationen zur Verwendung dieser Bibliothek für Ihre Erweiterungsdateien finden Sie unter
Die Klasse SampleDownloaderActivity
der Beispiel-App, die zusätzlichen Code zum
Überprüfen Sie die heruntergeladenen Dateien mit CRC. Wenn Sie dieses Beispiel als Grundlage für
Ihre eigene Implementierung verwenden, müssen Sie die Bytegröße Ihrer Erweiterung
Dateien im xAPKS
-Array.
Erweiterungsdateien testen
Bevor Sie Ihre App veröffentlichen, sollten Sie zwei Dinge testen: Erweiterungsdateien und Herunterladen der Dateien.
Dateilesevorgänge testen
Bevor Sie Ihre App bei Google Play hochladen, sollte die Fähigkeit Ihrer App testen, Dateien aus dem freigegebenen Speicher zu lesen. Alles, was du tun musst fügen Sie die Dateien am entsprechenden Speicherort im freigegebenen Gerätespeicher hinzu und starten die App:
- Erstellen Sie auf Ihrem Gerät das entsprechende Verzeichnis im freigegebenen Speicher, in dem Google
Google Play speichert deine Dateien.
Lautet der Paketname beispielsweise
com.example.android
, müssen Sie das VerzeichnisAndroid/obb/com.example.android/
im freigegebenen Speicherplatz. (Anschließen das Testgerät an Ihren Computer an, um den freigegebenen Speicher bereitzustellen, und erstellen Sie Verzeichnis.) - Fügen Sie die Erweiterungsdateien manuell zu diesem Verzeichnis hinzu. Benennen Sie Ihre Dateien in
Sie entsprechen dem Format des Dateinamens, das von Google Play verwendet wird.
Unabhängig vom Dateityp sollte die Haupterweiterungsdatei für die App
com.example.android
beispielsweisemain.0300110.com.example.android.obb
sein. Der Versionscode kann ein beliebiger Wert sein. Denken Sie daran:- Die Haupterweiterungsdatei beginnt immer mit
main
und die Patchdatei mitpatch
. - Der Paketname stimmt immer mit dem Namen des APK überein, an das die Datei angehängt ist. Google Play
- Die Haupterweiterungsdatei beginnt immer mit
- Da sich nun die Erweiterungsdateien auf dem Gerät befinden, können Sie Ihre App installieren und ausführen, Testen Sie Ihre Erweiterungsdatei(en).
Im Folgenden finden Sie einige Hinweise zum Umgang mit Erweiterungsdateien:
.obb
-Erweiterungsdateien nicht löschen oder umbenennen (auch nicht beim Entpacken) an einem anderen Ort speichern). Dies führt dazu, dass Google Play (oder Ihre App selbst) die Erweiterungsdatei wiederholt herunterladen.- Speichere keine anderen Daten auf deinem
obb/
Verzeichnis. Wenn Sie einige Daten entpacken müssen, speichern Sie sie an dem durchgetExternalFilesDir()
angegebenen Speicherort.
Dateidownloads testen
Weil Ihre App die Erweiterungsdateien manchmal manuell herunterladen muss öffnen, ist es wichtig, dass Sie diesen Prozess testen, um sicherzustellen, dass Ihre App erfolgreich Abfragen für die URLs, laden Sie die Dateien herunter und speichern Sie sie auf dem Gerät.
So testen Sie die Implementierung des manuellen Downloadvorgangs in Ihrer App: können Sie es im internen Test-Track veröffentlichen, damit es nur für Nutzer verfügbar ist, autorisierten Testern. Wenn alles wie erwartet funktioniert, sollte Ihre App die Erweiterungsdateien herunterladen, sobald die Hauptaktivität beginnt.
Hinweis:Bisher konnten Sie Apps testen, indem Sie Hochladen eines unveröffentlichten "Entwurfs" Version. Diese Funktion ist nicht mehr unterstützt. Sie müssen sie stattdessen in einem internen, geschlossenen oder offenen Test veröffentlichen. Titel. Weitere Informationen finden Sie unter App-Entwürfe sind nicht Länger unterstützt.
App aktualisieren
Einer der großen Vorteile von Erweiterungsdateien bei Google Play ist die Möglichkeit, aktualisieren, ohne alle ursprünglichen Assets noch einmal herunterzuladen. Weil Google Play kannst du mit jedem APK zwei Erweiterungsdateien bereitstellen. Die zweite Datei kann als Patch verwendet werden. mit Updates und neuen Assets. Dadurch wird der Fehler die Haupterweiterungsdatei, die für Nutzer sehr groß und teuer sein könnte, erneut herunterladen.
Die Patch-Erweiterungsdatei entspricht technisch der Haupt-Erweiterungsdatei und Das Android-System oder Google Play führen tatsächliche Patches zwischen der Haupt- und der Patcherweiterung aus. Dateien. Alle erforderlichen Patches müssen von Ihrem App-Code selbst ausgeführt werden.
Wenn Sie ZIP-Dateien als Erweiterungsdateien verwenden, gibt die APK Expansion Zip Die im APK-Erweiterungspaket enthaltene Bibliothek enthält die Möglichkeit, Ihr Patchdatei mit der Haupterweiterungsdatei.
Hinweis:Auch wenn Sie nur Änderungen am Patch vornehmen müssen
Erweiterungsdatei müssen Sie trotzdem das APK aktualisieren, damit Google Play ein Update durchführen kann.
Wenn keine Codeänderungen in der App erforderlich sind, aktualisieren Sie einfach versionCode
in der
Manifests.
Solange Sie die Haupterweiterungsdatei, die mit dem APK verknüpft ist, nicht ändern in der Play Console angezeigt, können Nutzer, die Ihre App bereits installiert haben, die Haupterweiterungsdatei herunterladen. Bestehende Nutzer erhalten nur das aktualisierte APK und den neuen Patch Erweiterungsdatei (unter Beibehaltung der vorherigen Haupterweiterungsdatei).
Im Zusammenhang mit der Aktualisierung von Erweiterungsdateien sind folgende Punkte zu beachten:
- Es können immer nur zwei Erweiterungsdateien für Ihre App gleichzeitig vorhanden sein. Eine Haupterweiterung und eine Patch-Erweiterungsdatei. Während der Aktualisierung einer Datei löscht Google Play Folgendes: frühere Version (genauso wie bei manueller Aktualisierung der App).
- Beim Hinzufügen einer Patch-Erweiterungsdatei wird Ihre Datei vom Android-System nicht gepatcht. App- oder Haupterweiterungsdatei. Sie müssen Ihre App so konzipieren, dass sie die Patchdaten unterstützt. Das APK-Erweiterungspaket enthält jedoch eine Bibliothek zur Verwendung von ZIP-Dateien. als Erweiterungsdateien, wodurch die Daten aus der Patchdatei in der Haupterweiterungsdatei zusammengeführt werden, können Sie alle Daten der Erweiterungsdateien leicht lesen.