Das Wiederherstellungssystem enthält mehrere Hooks zum Einfügen von gerätespezifischem Code, sodass OTA Mit Updates können auch andere Teile des Geräts als das Android-System aktualisiert werden (z. B. das Baseband). oder Funkprozessor).
In den folgenden Abschnitten und Beispielen wird das tardis-Gerät angepasst, das vom yoyodyne-Anbieter verfügbar.
Partitionszuordnung
Ab Android 2.3 unterstützt die Plattform eMMc-Flash-Geräte und das ext4-Dateisystem, das ausgeführt wird. auf diesen Geräten. Es unterstützt auch Memory Technology Device (MTD)-Flash-Geräte und yaffs2. von älteren Releases.
Die Partitionszuordnungsdatei wird durch TARGET_RECOVERY_FSTAB angegeben. wird diese Datei sowohl vom das Wiederherstellungsbinärprogramm und die Paketerstellungstools. Sie können den Namen der Kartendatei in TARGET_RECOVERY_FSTAB in BoardConfig.mk
Eine Partitionszuordnungsdatei könnte beispielsweise so aussehen:
device/yoyodyne/tardis/recovery.fstab
# mount point fstype device [device2] [options (3.0+ only)] /sdcard vfat /dev/block/mmcblk0p1 /dev/block/mmcblk0 /cache yaffs2 cache /misc mtd misc /boot mtd boot /recovery emmc /dev/block/platform/s3c-sdhci.0/by-name/recovery /system ext4 /dev/block/platform/s3c-sdhci.0/by-name/system length=-4096 /data ext4 /dev/block/platform/s3c-sdhci.0/by-name/userdata
Mit Ausnahme des optionalen /sdcard
-Objekts werden alle Bereitstellungspunkte in
Beispiel muss definiert werden (Geräte können auch zusätzliche Partitionen hinzufügen). Es gibt fünf unterstützte
Dateisystemtypen:
- Yaffs2
-
Ein yaffs2-Dateisystem auf einem MTD-Flash-Gerät. "Gerät" muss der Name der MTD-Partition sein
und muss auf
/proc/mtd
erscheinen. - Mtd.
-
Eine MTD-Rohpartition, die für bootfähige Partitionen wie Boot- und Wiederherstellungsvorgänge verwendet wird. MTD ist nicht
bereitgestellt werden, aber der
Bereitstellungspunkt dient als Schlüssel zum Auffinden der Partition. "Gerät"
muss der Name der MTD-Partition in
/proc/mtd
sein. - Durchwahl 4
- Ein ext4-Dateisystem auf einem eMMc-Flash-Gerät. "Gerät" muss der Pfad des blockorientierten Geräts sein.
- Emmc
- Rohe eMMc-Blockgerät, das für bootfähige Partitionen wie Booten und Wiederherstellen verwendet wird. Ähnlich wie Mtd-Typ hat, wird eMMc nie bereitgestellt, aber der String für den Bereitstellungspunkt dient dazu, Gerät in der Tabelle.
- VFTT
-
Ein FAT-Dateisystem auf einem Blockgerät, in der Regel für externe Speicher wie eine SD-Karte. Die
„Gerät“ ist das blockorientierte Gerät. "device2" ist ein zweites Blockgerät, das das System zu installieren versucht,
das primäre Gerät kann nicht bereitgestellt werden (aus Gründen der Kompatibilität mit SD-Karten, die möglicherweise
mit einer Partitionstabelle formatiert).
Alle Partitionen müssen im Stammverzeichnis bereitgestellt werden, d.h. der Wert des Bereitstellungspunkts muss mit einem Schrägstrich beginnen und keine anderen Schrägstriche enthalten. Diese Einschränkung gilt nur für die Dateisysteme für die Wiederherstellung; kann das Hauptsystem überall montiert werden. Verzeichnisse
/boot
,/recovery
und/misc
sollten Rohtypen sein (mtd oder emmc), während die Verzeichnisse/system
,/data
,/cache
und/sdcard
(falls verfügbar) sollten Dateisystemtypen sein (yaffs2, ext4 oder vfat).
Ab Android 3.0 erhält die Datei „recovery.fstab“ ein zusätzliches optionales Feld, Optionen. Derzeit ist die einzige Option length , mit der Sie explizit die Länge der Partition an. Diese Länge wird bei der Neuformatierung der Partition verwendet z.B. für die Nutzerdatenpartition während einer Datenlöschung oder auf die Werkseinstellungen Systempartition während der Installation eines vollständigen OTA-Pakets) Wenn der Wert für die Länge negativ ist, wird die zu formatierende Größe berechnet, indem der Wert für die Länge zur tatsächlichen Partitionsgröße addiert wird. Für Instanz, Festlegen von "length=-16384" bedeutet, dass die letzten 16k dieser Partition nicht wird überschrieben, wenn die Partition neu formatiert wird. Dies unterstützt Funktionen wie die Verschlüsselung von die Partition für Nutzerdaten, in der Verschlüsselungsmetadaten am Ende der Partition nicht überschrieben werden darf).
Hinweis:Die Felder device2 und options sind optional. Unklarheiten beim Parsen. Wenn der Eintrag im vierten Feld der Zeile mit einem Schrägstrich („/“) beginnt wird als device2 -Eintrag betrachtet. Der Eintrag beginnt nicht mit einem Schrägstrich („/“). wird es als Optionsfeld angesehen.
Startanimation
Gerätehersteller können die Animation anpassen, die angezeigt wird, wenn ein Android-Gerät startet. Erstellen Sie dazu eine ZIP-Datei, die gemäß dem Spezifikationen in Bootanimation-Format.
Für Android Things-Geräte können Sie die ZIP-Datei in die Android Things-Konsole hochladen, damit die Bilder das ausgewählte Produkt.
Hinweis:Diese Bilder müssen den Markenrichtlinien von Android entsprechen. Markenrichtlinien finden Sie im Abschnitt zu Android Partnermarketing Hub
Benutzeroberfläche für die Wiederherstellung
Zur Unterstützung von Geräten mit unterschiedlicher verfügbarer Hardware (z. B. physische Tasten, LEDs oder Bildschirme) können Sie die Wiederherstellungsoberfläche anpassen, um den Status anzuzeigen und auf manuell versteckte Funktionen für jedes Gerät.
Ihr Ziel ist es, eine kleine statische Bibliothek mit einigen C++-Objekten zu erstellen,
gerätespezifische Funktionen nutzen können. Die Datei
bootable/recovery/default_device.cpp
wird standardmäßig verwendet und ist daher
Startpunkt zu kopieren, wenn Sie eine Version dieser Datei für Ihr Gerät schreiben.
Hinweis:Möglicherweise wird hier die Meldung Kein Befehl angezeigt. Zum Umschalten halte die Ein/Aus-Taste gedrückt, während du auf die Lautertaste drückst. Wenn Ihre Geräte nicht drücken Sie lange auf eine beliebige Taste, um den Text umzuschalten.
device/yoyodyne/tardis/recovery/recovery_ui.cpp
#include <linux/input.h> #include "common.h" #include "device.h" #include "screen_ui.h"
Header- und Elementfunktionen
Für die Geräteklasse sind Funktionen zur Rückgabe von Headern und Elementen erforderlich, die in den ausgeblendeten Elementen erscheinen. Wiederherstellungsmenü. Überschriften beschreiben die Bedienung des Menüs, d.h. Steuerelemente zum Ändern/Auswählen der markiertes Element) angezeigt.
static const char* HEADERS[] = { "Volume up/down to move highlight;", "power button to select.", "", NULL }; static const char* ITEMS[] = {"reboot system now", "apply update from ADB", "wipe data/factory reset", "wipe cache partition", NULL };
Hinweis:Lange Zeilen werden abgeschnitten (nicht umgebrochen). Behalten Sie daher die Breite der Gerätebildschirms zu berücksichtigen.
CheckKey anpassen
Definieren Sie als Nächstes die RecoveryUI-Implementierung Ihres Geräts. In diesem Beispiel wird davon ausgegangen,
tardis-Gerät verfügt über einen Bildschirm, sodass Sie die Einstellungen vom integrierten
ScreenRecoveryUIImplement (siehe Anweisungen für
Geräte ohne Bildschirm. Die einzige Funktion, mit der Sie
von ScreenRecoveryUI anpassen ist CheckKey()
, wodurch die anfängliche
asynchrone Schlüsselverwaltung:
class TardisUI : public ScreenRecoveryUI { public: virtual KeyAction CheckKey(int key) { if (key == KEY_HOME) { return TOGGLE; } return ENQUEUE; } };
KEY-Konstanten
Die KEY_*-Konstanten sind in linux/input.h
definiert. CheckKey()
ist
wird aufgerufen, unabhängig davon, was während der Wiederherstellung vor sich geht:
eingeschaltet ist, während der Paketinstallation,
beim Löschen von Nutzerdaten usw. Es kann eine von vier
Konstanten:
- WECHSELN: Anzeige des Menüs und/oder des Textprotokolls ein- oder ausschalten
- NEU BOOTEN. Gerät sofort neu starten
- IGNORIEREN: Diesen Tastendruck ignorieren
- ENQUEUE sein. Diesen Tastendruck synchron (d.h. von der Wiederherstellung) in die Warteschlange stellen Menüsystem bei aktiviertem Display)
CheckKey()
wird jedes Mal aufgerufen, wenn auf ein Key-Down-Ereignis ein Key-up-Ereignis für
denselben Schlüssel ein. (Die Abfolge der Ereignisse A-Ab-nach-B-nach-B--Auf-oben-Ergebnis ergibt nur
CheckKey(B)
wird angerufen.) CheckKey()
kann anrufen
IsKeyPressed()
, um zu prüfen, ob andere Tasten gedrückt werden. (Im obigen Beispiel
Abfolge von Schlüsselereignissen, wenn mit CheckKey(B)
IsKeyPressed(A)
aufgerufen wird
hätte „true“ zurückgegeben.
CheckKey()
kann den Status in seiner Klasse beibehalten. kann es nützlich sein,
Tastensequenzen. Dieses Beispiel zeigt eine etwas komplexere Einrichtung: Das Display wird durch
die Ein/Aus-Taste gedrückt halten und die Lautertaste drücken. Das Gerät kann dann sofort neu gestartet werden, indem
Drücken der Ein/Aus-Taste fünfmal hintereinander (ohne andere Tasten dazwischen):
class TardisUI : public ScreenRecoveryUI { private: int consecutive_power_keys; public: TardisUI() : consecutive_power_keys(0) {} virtual KeyAction CheckKey(int key) { if (IsKeyPressed(KEY_POWER) && key == KEY_VOLUMEUP) { return TOGGLE; } if (key == KEY_POWER) { ++consecutive_power_keys; if (consecutive_power_keys >= 5) { return REBOOT; } } else { consecutive_power_keys = 0; } return ENQUEUE; } };
Benutzeroberfläche zur Bildschirmwiederherstellung
Bei Verwendung eigener Bilder (Fehlersymbol, Installationsanimation, Fortschrittsanzeige) mit
ScreenRecoveryUI nutzt die Variable animation_fps
, um die Geschwindigkeit in
Bilder pro Sekunde (fps) von Animationen.
Hinweis: Mit dem aktuellen interlace-frames.py
-Script können Sie Folgendes tun:
animation_fps
-Informationen im Bild selbst speichern. In früheren Versionen von
Android musste animation_fps
selbst festlegen.
Um die Variable animation_fps
festzulegen, überschreiben Sie
ScreenRecoveryUI::Init()
-Funktion in Ihrer abgeleiteten Klasse. Legen Sie den Wert fest und rufen Sie dann die Methode
parent Init()
, um die Initialisierung abzuschließen. Der Standardwert (20 fps)
entspricht den Standard-Wiederherstellungs-Images; wenn Sie solche Bilder verwenden,
Eine Init()
-Funktion. Weitere Informationen zu Bildern finden Sie unter
Images der Benutzeroberfläche für die Wiederherstellung.
Geräteklasse
Nachdem Sie über eine RecoveryUI-Implementierung verfügen, definieren Sie Ihre Geräteklasse (untergeordnete Klasse aus der
integrierte Geräteklasse). Sie sollte eine einzelne Instanz Ihrer UI-Klasse erstellen und diese
aus der Funktion GetUI()
:
class TardisDevice : public Device { private: TardisUI* ui; public: TardisDevice() : ui(new TardisUI) { } RecoveryUI* GetUI() { return ui; }
Wiederherstellung starten
Die Methode StartRecovery()
wird zu Beginn der Wiederherstellung aufgerufen, nachdem die UI
initialisiert wurde und nach dem Parsen der Argumente, aber bevor eine Aktion durchgeführt wurde
bereits vergeben sind. Die Standardimplementierung hat keine Auswirkungen. Sie müssen dies also nicht in Ihrem
ab, wenn Sie nichts zu tun haben:
void StartRecovery() { // ... do something tardis-specific here, if needed .... }
Wiederherstellungsmenü bereitstellen und verwalten
Das System ruft zwei Methoden auf, um die Liste der Kopfzeilen und die Liste der Elemente abzurufen. In dieser -Implementierung gibt sie die statischen Arrays zurück, die am Anfang der Datei definiert sind:
const char* const* GetMenuHeaders() { return HEADERS; } const char* const* GetMenuItems() { return ITEMS; }
HandleMenuKey
Stellen Sie als Nächstes eine HandleMenuKey()
-Funktion bereit, die einen Tastendruck und die aktuelle
die Sichtbarkeit des Menüs und entscheidet, welche Aktion ausgeführt werden soll:
int HandleMenuKey(int key, int visible) { if (visible) { switch (key) { case KEY_VOLUMEDOWN: return kHighlightDown; case KEY_VOLUMEUP: return kHighlightUp; case KEY_POWER: return kInvokeItem; } } return kNoAction; }
Die -Methode verwendet einen Schlüsselcode, der zuvor vom
CheckKey()
-Methode des UI-Objekts) und den aktuellen Status des Menü-/Textprotokolls.
Sichtbarkeit. Der Rückgabewert ist eine Ganzzahl. Ist der Wert 0 oder höher, wird dies als
Position eines Menüelements, das sofort aufgerufen wird (siehe
InvokeMenuItem()
-Methode unten). Andernfalls kann es sich um einen der folgenden Werte handeln:
vordefinierte Konstanten:
- kHighlightUp: Menühighlight zum vorherigen Element verschieben
- kHighlightDown: Menühighlight zum nächsten Element verschieben
- kInvokeItem Aktuell markiertes Element aufrufen
- kNoAction angeben. Keine Aktion mit diesem Tastendruck
Wie durch das Argument „visible“ impliziert, wird HandleMenuKey()
aufgerufen, auch wenn das Menü
nicht sichtbar. Im Gegensatz zu CheckKey()
wird es während der Wiederherstellung nicht aufgerufen
wie das Löschen von Daten oder das Installieren eines Pakets.
und auf Eingaben warten.
Trackball-Mechanismen
Verfügt Ihr Gerät über einen Trackball-ähnlichen Eingabemechanismus (generiert Eingabeereignisse vom Typ EV_REL)
und den Code REL_Y) generiert die Wiederherstellung die Tasten KEY_UP und KEY_DOWN, sobald die
Das trackballähnliche Eingabegerät meldet die Bewegung auf der Y-Achse. Sie müssen lediglich KEY_UP und
KEY_DOWN-Ereignisse für Menüaktionen verwenden. Diese Zuordnung erfolgt nicht für
CheckKey()
. Daher können Sie Trackball-Bewegungen nicht als Auslöser für einen Neustart oder
um den Bildschirm umzuschalten.
Modifikatortasten
Rufe die IsKeyPressed()
-Methode auf, um zu prüfen, ob Tasten als Modifikator gedrückt gehalten werden.
Ihres eigenen UI-Objekts. Auf einigen Geräten wird z. B. durch Drücken von Alt+W bei der Wiederherstellung
die Datenlöschung, unabhängig davon, ob das Menü sichtbar war oder nicht. Sie könnten Folgendes implementieren:
int HandleMenuKey(int key, int visible) { if (ui->IsKeyPressed(KEY_LEFTALT) && key == KEY_W) { return 2; // position of the "wipe data" item in the menu } ... }
Hinweis: Falls visible auf „false“ gesetzt ist, ist es nicht sinnvoll, die speziellen Werte, die das Menü manipulieren (Hervorhebung verschieben, hervorgehobenes Element aufrufen), da der Nutzer keine sehen Sie das Highlight. Sie können die Werte jedoch bei Bedarf zurückgeben.
InvokeMenuItem
Stellen Sie als Nächstes eine InvokeMenuItem()
-Methode bereit, die ganzzahlige Positionen im Array zuordnet.
von Artikeln, die von GetMenuItems()
an Aktionen zurückgegeben wurden. Für das Array der Elemente im
Tardis-Beispiel, verwenden Sie:
BuiltinAction InvokeMenuItem(int menu_position) { switch (menu_position) { case 0: return REBOOT; case 1: return APPLY_ADB_SIDELOAD; case 2: return WIPE_DATA; case 3: return WIPE_CACHE; default: return NO_ACTION; } }
Diese Methode kann jedes Mitglied des enum-Werts "BuiltinAction" zurückgeben, um das System anzuweisen, Aktion (oder das Mitglied NO_ACTION, wenn das System nichts tun soll). Hier können Sie bieten zusätzliche Wiederherstellungsfunktionen, die über den Inhalt des Systems hinausgehen: Fügen Sie ein Element dafür hinzu. hier einfügen, hier ausführen, wenn dieser Menüpunkt aufgerufen wird, und NO_ACTION zurückgeben, damit das System sonst nichts.
„BuiltinAction“ enthält die folgenden Werte:
- NO_ACTION: Nichts unternehmen.
- NEU BOOTEN. Beenden Sie die Wiederherstellung und starten Sie das Gerät normal neu.
- APPLY_EXT, APPLY_CACHE, APPLY_ADB_SIDELOAD anwenden. Installieren Sie ein Update-Paket aus verschiedenen an unterschiedlichen Orten. Weitere Informationen finden Sie unter Sideloading.
- WIPE_CACHE ein. Formatieren Sie nur die Cache-Partition neu. Keine Bestätigung erforderlich, da relativ harmlos.
- WIPE_DATA zurück. Die Benutzerdaten neu formatieren und Partitionen im Cache speichern (auch bekannt als Factory Data) zurückgesetzt werden. Der Nutzer wird aufgefordert, diese Aktion zu bestätigen, bevor er fortfahren kann.
Die letzte Methode, WipeData()
, ist optional und wird aufgerufen, wenn eine Datenlöschung durchgeführt wird.
eingeleitet wird (entweder bei der Wiederherstellung über das Menü oder wenn der Nutzer
auf die Werkseinstellungen über das Hauptsystem zurücksetzen). Diese Methode wird vor den Nutzerdaten und dem Cache aufgerufen
werden alle Partitionen gelöscht. Wenn auf Ihrem Gerät Nutzerdaten an einem anderen Ort als diesen beiden gespeichert werden
sollten Sie sie hier löschen. Sie sollten 0 zurückgeben, um eine erfolgreiche Aktion anzuzeigen, und eine weitere
für den Fehler zurückgegeben, obwohl der Rückgabewert derzeit ignoriert wird. Nutzerdaten und Cache
werden alle Partitionen
gelöscht, unabhängig davon, ob der Vorgang erfolgreich war.
int WipeData() { // ... do something tardis-specific here, if needed .... return 0; }
Gerät festlegen
Fügen Sie abschließend Textbausteine am Ende der Datei „recovery_ui.cpp“ für den
make_device()
-Funktion, die eine Instanz Ihrer Geräteklasse erstellt und zurückgibt:
class TardisDevice : public Device { // ... all the above methods ... }; Device* make_device() { return new TardisDevice(); }
Build und Verknüpfung zur Gerätewiederherstellung
Nachdem Sie die Datei „recovery_ui.cpp“ fertiggestellt haben, erstellen Sie sie und verknüpfen Sie sie mit der Wiederherstellung auf Ihrem Gerät. In Erstellen Sie unter Android.mk eine statische Bibliothek, die nur diese C++-Datei enthält:
device/yoyodyne/tardis/recovery/Android.mk
LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) LOCAL_MODULE_TAGS := eng LOCAL_C_INCLUDES += bootable/recovery LOCAL_SRC_FILES := recovery_ui.cpp # should match TARGET_RECOVERY_UI_LIB set in BoardConfig.mk LOCAL_MODULE := librecovery_ui_tardis include $(BUILD_STATIC_LIBRARY)
Geben Sie dann in der Board-Konfiguration für dieses Gerät Ihre statische Bibliothek als Wert von TARGET_RECOVERY_UI_LIB.
device/yoyodyne/tardis/BoardConfig.mk [...] # device-specific extensions to the recovery UI TARGET_RECOVERY_UI_LIB := librecovery_ui_tardis
UI-Images für die Wiederherstellung
Die Benutzeroberfläche für die Wiederherstellung besteht aus Images. Im Idealfall interagieren Nutzende nie mit der Benutzeroberfläche: Während eines normalen Updates startet das Smartphone bei der Wiederherstellung und füllt die Fortschrittsanzeige der Installation aus. und startet das neue System ohne Eingabe des Nutzers. Im Falle eines Update-Problem besteht, besteht die einzige Nutzeraktion, die durchgeführt werden kann, darin, den Kundendienst anzurufen.
Eine reine Image-Schnittstelle macht eine Lokalisierung überflüssig. Ab Android 5.0 Bei einem Update kann neben dem Bild auch eine Textzeichenfolge wie „Systemupdate wird installiert...“ angezeigt werden. Weitere Informationen finden Sie unter Lokalisierter Wiederherstellungstext.
Android 5.0 und höher
Die Wiederherstellungs-UI unter Android 5.0 und höher verwendet zwei Haupt-Images: das error-Image. und der Animation Installation.
Die Installationsanimation wird als einzelnes PNG-Bild mit verschiedenen Frames des
Animation mit Zeilensprüngen (wodurch erscheint Abbildung 2 zerdrückt). Beispiel: Für eine
7-Frame-Animation im Format 200 x 200, erstellen Sie ein einzelnes Bild mit 200 x 1400 Pixel, wobei der erste Frame die Zeilen 0, 7,
14, 21, ...; der zweite Frame die Zeilen 1, 8, 15, 22, ...; Das kombinierte Bild enthält ein
Text-Chunk, der die Anzahl der Animationsframes und die Anzahl der Frames pro Sekunde angibt
(fps) Das Tool bootable/recovery/interlace-frames.py
verwendet eine Reihe von Eingabeframes
und kombiniert sie zu dem
erforderlichen zusammengesetzten Image, das für die Wiederherstellung verwendet wird.
Standardbilder sind in verschiedenen Dichten verfügbar und befinden sich
bootable/recovery/res-$DENSITY/images
(z.B.
bootable/recovery/res-hdpi/images
. Um während der Installation ein statisches Image zu verwenden,
müssen Sie nur das Bild icon_installing.png bereitstellen und die Anzahl der Frames
Animation auf 0 (das Fehlersymbol ist nicht animiert, es ist immer ein statisches Bild).
Android 4.x und niedriger
Die Wiederherstellungs-UI unter Android 4.x und niedriger verwendet das error-Abbild (siehe oben) und den Installation einer Animation und mehrerer Overlay-Bilder:
Während der Installation wird der Bildschirminhalt durch Zeichnen der Datei icon_installing.png erstellt. Bild und dann einen der Overlay-Frames mit dem entsprechenden Versatz darüber zeichnen. Hier ist eine rote wird überlagert, um die Position des Overlays über dem Basisbild hervorzuheben:
Die nachfolgenden Frames werden angezeigt, indem nur das nächste Overlay-Bild darüber gezeichnet wird. bereits vorhanden; wird das Basis-Image nicht neu gezeichnet.
Die Anzahl der Frames in der Animation, die gewünschte Geschwindigkeit sowie x- und y-Offsets des Overlays
relativ zur Basis durch Mitgliedsvariablen der ScreenRecoveryUI-Klasse festgelegt werden. Bei Verwendung
statt Standard-Images verwenden, überschreiben Sie die Init()
-Methode in
können Sie diese Werte für Ihre benutzerdefinierten Images ändern (Details finden Sie unter
ScreenRecoveryUI). Das Skript
bootable/recovery/make-overlay.py
kann beim Konvertieren einer Reihe von Bildframes helfen
den Wert „Basisbild + Overlay-Bilder“ die für die Wiederherstellung benötigt werden, einschließlich der Berechnung der
notwendige Offsets.
Die Standardbilder befinden sich in bootable/recovery/res/images
. Statisches Bild verwenden
Während der Installation müssen Sie nur das Image "icon_installing.png" bereitstellen und die Anzahl der
Frames in der Animation auf 0 setzen (das Fehlersymbol ist nicht animiert, es ist immer ein statisches Bild).
Lokalisierter Wiederherstellungstext
Android 5.x zeigt eine Textzeichenfolge (z.B. „Systemupdate wird installiert...“. Bild. Wenn das Hauptsystem bei der Wiederherstellung startet, wird die aktuelle Sprache des Nutzers als Befehlszeilenoption zur Wiederherstellung. Für jede anzuzeigende Nachricht umfasst die Wiederherstellung zusammengesetztes Bild mit vorab gerenderten Textzeichenfolgen für diese Nachricht in jeder Sprache.
Beispielbild für Wiederherstellungstextstrings:
Im Wiederherstellungstext können die folgenden Meldungen angezeigt werden:
- Systemupdate wird installiert...
- Fehler!
- Wird gelöscht... (beim Löschen der Daten auf die Werkseinstellungen)
- Kein Befehl (wenn ein Nutzer manuell in die Wiederherstellung startet)
Die Android-App in bootable/recovery/tools/recovery_l10n/
rendert Lokalisierungen
einer Nachricht und
erstellt das zusammengesetzte Bild. Weitere Informationen zur Verwendung dieser App findest du in der
Kommentare in
bootable/recovery/tools/recovery_l10n/src/com/android/recovery_l10n/Main.java
Wenn ein Nutzer die Wiederherstellung manuell startet, ist die Sprache möglicherweise nicht verfügbar und es wird kein Text angezeigt. angezeigt. Verwenden Sie die SMS nicht als kritische Nachricht für den Wiederherstellungsprozess.
Hinweis: Die ausgeblendete Oberfläche, auf der Protokollmeldungen angezeigt werden und Nutzer die folgenden Aktionen ausführen können: Auswahlaktionen aus dem Menü sind nur auf Englisch verfügbar.
Fortschrittsanzeigen
Fortschrittsbalken können unter dem Hauptbild (oder der Animation) angezeigt werden. Der Fortschrittsbalken wird erstellt, Kombinieren von zwei Eingabebildern, die dieselbe Größe haben müssen:
Das linke Ende des fill-Bildes wird neben dem leeres Bild, um die Fortschrittsanzeige einzublenden. Die Position der Grenze zwischen den beiden Bilder den Fortschritt anzeigen. Mit den obigen Paaren von Eingabebildern Anzeige:
Sie können gerätespezifische Versionen dieser Bilder bereitstellen, indem Sie sie in (in dieser
Beispiel) device/yoyodyne/tardis/recovery/res/images
. Die Dateinamen müssen mit den oben aufgeführten übereinstimmen. eine Datei in diesem Verzeichnis gefunden wird,
verwendet das Build-System diese anstelle des entsprechenden Standard-Images. Nur PNGs im RGB- oder
Das RGBA-Format mit einer Farbtiefe von 8 Bit wird unterstützt.
Hinweis: Wenn unter Android 5.x die Sprache für die Wiederherstellung bekannt ist und Rechts-nach-links-Sprache (Arabisch, Hebräisch usw.) angezeigt wird, füllt sich die Fortschrittsanzeige von rechts nach hat den Chat verlassen.
Geräte ohne Bildschirme
Nicht alle Android-Geräte haben ein Display. Wenn es sich bei Ihrem Gerät um ein monitorloses Gerät handelt oder Audio-UI verwenden, müssen Sie die Wiederherstellungs-UI möglicherweise umfassender anpassen. Stattdessen zur Erstellung einer abgeleiteten Klasse von ScreenRecoveryUI, erstellen Sie eine direkte Unterklasse der übergeordneten Klasse "RecoveryUI".
RecoveryUI bietet Methoden zur Verarbeitung untergeordneter UI-Vorgänge wie
„aktualisiere die Fortschrittsanzeige“, „Zeig mir das Menü“ „Menüauswahl ändern“, und so weiter. Sie können die
um eine geeignete Schnittstelle für Ihr Gerät bereitzustellen. Vielleicht hat Ihr Gerät LEDs,
können Sie verschiedene Farben oder Blinkmuster verwenden, um den Zustand anzuzeigen, oder Sie können
Audio. Vielleicht möchten Sie ein Menü oder den "Textanzeige"-Modus überhaupt nicht unterstützen. Sie können
den Zugriff über CheckKey()
und
HandleMenuKey()
-Implementierungen, bei denen nie die Anzeige ein- oder ausgeschaltet wird
ein. In diesem Fall können viele der erforderlichen RecoveryUI-Methoden leer sein.
Stubs.)
Unter bootable/recovery/ui.h
finden Sie die Deklaration von RecoveryUI. Dort erfahren Sie, welche Methoden Sie verwenden.
die Sie unterstützen müssen. RecoveryUI ist abstrakt – einige Methoden sind rein virtuell und müssen von
abgeleiteten Klassen erstellt, enthält aber den Code für die Verarbeitung der wichtigsten Eingaben. Sie können das überschreiben,
wenn Ihr Gerät keine Schlüssel hat oder Sie sie anders verarbeiten möchten.
Updater
Sie können in der Installation des Update-Pakets gerätespezifischen Code verwenden, indem Sie Ihre eigene Erweiterungsfunktionen, die in Ihrem Updater-Skript aufgerufen werden können. Hier ein Beispiel für das Tardis-Gerät:
device/yoyodyne/tardis/recovery/recovery_updater.c
#include <stdlib.h> #include <string.h> #include "edify/expr.h"
Jede Erweiterungsfunktion hat dieselbe Signatur. Die Argumente sind der Name, unter dem der
-Funktion, ein State*
-Cookie, die Anzahl der eingehenden Argumente und ein
Array von Expr*
-Zeigern, die die Argumente darstellen. Der Rückgabewert ist ein
neu zugewiesene Value*
.
Value* ReprogramTardisFn(const char* name, State* state, int argc, Expr* argv[]) { if (argc != 2) { return ErrorAbort(state, "%s() expects 2 args, got %d", name, argc); }
Ihre Argumente wurden zum Zeitpunkt des Funktionsaufrufs nicht ausgewertet – die
welche von ihnen ausgewertet werden und wie oft. Daher können Sie Erweiterungen verwenden,
können Sie Ihre eigenen Kontrollstrukturen implementieren. Call Evaluate()
zum Auswerten
Ein Expr*
-Argument, das ein Value*
zurückgibt. Wenn Evaluate()
gibt NULL zurück, sollten Sie alle Ressourcen freigeben, die Sie halten, und sofort NULL zurückgeben (dies
bricht den Edify-Stack ab). Andernfalls übernehmen Sie die Eigentumsrechte für den zurückgegebenen Wert und
sind dafür verantwortlich,
FreeValue()
.
Angenommen, die Funktion benötigt zwei Argumente: einen Schlüssel mit Stringwert und einen mit einem Blobwert. image an. Sie könnten Argumente wie folgt lesen:
Value* key = EvaluateValue(state, argv[0]); if (key == NULL) { return NULL; } if (key->type != VAL_STRING) { ErrorAbort(state, "first arg to %s() must be string", name); FreeValue(key); return NULL; } Value* image = EvaluateValue(state, argv[1]); if (image == NULL) { FreeValue(key); // must always free Value objects return NULL; } if (image->type != VAL_BLOB) { ErrorAbort(state, "second arg to %s() must be blob", name); FreeValue(key); FreeValue(image) return NULL; }
Die Suche auf NULL und das Freigeben zuvor ausgewerteter Argumente kann bei mehreren
Argumente. Die Funktion ReadValueArgs()
kann Ihnen dabei helfen. Anstelle des Codes
hätten Sie Folgendes schreiben können:
Value* key; Value* image; if (ReadValueArgs(state, argv, 2, &key, &image) != 0) { return NULL; // ReadValueArgs() will have set the error message } if (key->type != VAL_STRING || image->type != VAL_BLOB) { ErrorAbort(state, "arguments to %s() have wrong type", name); FreeValue(key); FreeValue(image) return NULL; }
ReadValueArgs()
führt keine Typprüfung durch, daher müssen Sie dies hier tun: es ist mehr
dies mit einer if-Anweisung zu tun, auf die Kosten einer etwas geringeren
wenn er fehlschlägt. Aber ReadValueArgs()
übernimmt die Auswertung
Argumenten erstellen und alle zuvor bewerteten Argumente freigeben (sowie ein nützliches
Fehlermeldung angezeigt wird, wenn eine der Bewertungen fehlschlägt. Sie können einen
ReadValueVarArgs()
-Funktion zum Auswerten einer variablen Anzahl von
Argumente. Sie gibt ein Array von Value*
zurück.
Nachdem Sie die Argumente ausgewertet haben, führen Sie die Arbeit der Funktion aus:
// key->data is a NUL-terminated string // image->data and image->size define a block of binary data // // ... some device-specific magic here to // reprogram the tardis using those two values ...
Der Rückgabewert muss ein Value*
-Objekt sein. die Eigentümerschaft dieses Objekts an
für den Anrufer. Der Aufrufer übernimmt die Eigentümerschaft für alle Daten, auf die dieses
Value*
, insbesondere das Datenelement.
In diesem Fall möchten Sie einen true- oder false-Wert zurückgeben, um den Erfolg anzuzeigen. Denken Sie an die
Konvention, dass der leere String false und alle anderen Strings true sind. Ich
muss ein Wertobjekt mit einer "maloc'd"-Kopie der konstanten Zeichenfolge angeben, die zurückgegeben werden soll, da das Objekt
free()
wird beide. Vergessen Sie nicht, FreeValue()
anzurufen in der
die Sie durch Auswertung Ihrer Argumente erhalten haben.
FreeValue(key); FreeValue(image); Value* result = malloc(sizeof(Value)); result->type = VAL_STRING; result->data = strdup(successful ? "t" : ""); result->size = strlen(result->data); return result; }
Die Convenience-Funktion StringValue()
verpackt einen String in ein neues Wertobjekt.
Verwenden Sie , um den obigen Code kürzer zu formulieren:
FreeValue(key); FreeValue(image); return StringValue(strdup(successful ? "t" : "")); }
Um Funktionen mit dem edify-Interpreter zu verknüpfen, geben Sie die Funktion
Register_foo
, wobei foo der Name der statischen Bibliothek ist, die Folgendes enthält:
diesem Code. Rufen Sie RegisterFunction()
auf, um jede Erweiterungsfunktion zu registrieren. Von
der Konvention sollten gerätespezifische Funktionen device.whatever
verwendet werden, um sie zu vermeiden.
Konflikte mit zukünftig hinzugefügten
integrierten Funktionen besteht.
void Register_librecovery_updater_tardis() { RegisterFunction("tardis.reprogram", ReprogramTardisFn); }
Sie können das Makefile jetzt so konfigurieren, dass mit Ihrem Code eine statische Bibliothek erstellt wird. (Das gleiche Makefile, mit dem die Wiederherstellungs-UI im vorherigen Abschnitt angepasst wurde hat Ihr Gerät möglicherweise statische Bibliotheken definiert sind.)
device/yoyodyne/tardis/recovery/Android.mk
include $(CLEAR_VARS) LOCAL_SRC_FILES := recovery_updater.c LOCAL_C_INCLUDES += bootable/recovery
Der Name der statischen Bibliothek muss mit dem Namen des
Register_libname
-Funktion enthalten.
LOCAL_MODULE := librecovery_updater_tardis include $(BUILD_STATIC_LIBRARY)
Konfigurieren Sie schließlich den Wiederherstellungs-Build, um Ihre Bibliothek abzurufen. Mediathek hinzufügen zu
TARGET_RECOVERY_UPDATER_LIBS (kann mehrere Bibliotheken enthalten; alle werden registriert).
Wenn Ihr Code von anderen statischen Bibliotheken abhängt, die selbst keine Erweiterungen sind (z.B.
keine Register_libname
-Funktion haben), können Sie diese in
TARGET_RECOVERY_UPDATER_EXTRA_LIBS, um ihn mit dem Updater zu verknüpfen, ohne den
(nicht vorhandene) Registrierungsfunktion. Wenn Sie mit Ihrem gerätespezifischen Code z. B.
zlib zum Dekomprimieren von Daten verwenden, fügen Sie hier libz ein.
device/yoyodyne/tardis/BoardConfig.mk
[...] # add device-specific extensions to the updater binary TARGET_RECOVERY_UPDATER_LIBS += librecovery_updater_tardis TARGET_RECOVERY_UPDATER_EXTRA_LIBS +=
Die Updater-Skripts in deinem OTA-Paket können deine Funktion jetzt wie jede andere aufrufen. Um neu zu programmieren
Ihrem Tardis-Gerät enthält, kann das Update-Skript Folgendes enthalten:
tardis.reprogram("the-key", package_extract_file("tardis-image.dat"))
Hierbei wird
der Version mit einem Argument der integrierten Funktion package_extract_file()
gibt den Inhalt einer Datei zurück, die aus dem Update-Paket extrahiert wurde, als Blob zur Erstellung
das zweite Argument für die neue Erweiterungsfunktion.
OTA-Paketerstellung
Der letzte Schritt besteht darin, die Tools zur OTA-Paketgenerierung über eure gerätespezifische Daten und Ausgabe-Updater-Skripte, die Aufrufe Ihrer Erweiterungsfunktionen enthalten.
Zuerst muss das Build-System von einem gerätespezifischen Daten-BLOB erfahren. Annahme Ihrer Daten
Datei befindet sich in device/yoyodyne/tardis/tardis.dat
, deklarieren Sie Folgendes in Ihrer
AndroidBoard.mk des Geräts:
device/yoyodyne/tardis/AndroidBoard.mk
[...] $(call add-radio-file,tardis.dat)
Sie können sie auch in einer Android.mk-Datei speichern, dann muss sie dann aber von einem Gerät geschützt werden. da alle Android.mk-Dateien im Baum unabhängig vom Gerät geladen werden. entwickelt. Wenn Ihre Baumstruktur mehrere Geräte enthält, soll die Datei tardis.dat nur hinzugefügt werden, wenn Erstellen des Tardis-Geräts)
device/yoyodyne/tardis/Android.mk
[...] # an alternative to specifying it in AndroidBoard.mk ifeq (($TARGET_DEVICE),tardis) $(call add-radio-file,tardis.dat) endif
Aus historischen Gründen werden diese Dateien als Optionsfelder bezeichnet. haben sie vielleicht nichts mit
Geräteradio (falls vorhanden). Sie sind einfach undurchsichtige Daten-Blobs, in die das Build-System kopiert
Die von den OTA-Generierungstools verwendeten ZIP-Dateien mit Zieldateien. Beim Erstellen eines Builds
ist tardis.dat
in der Datei target-files.zip als RADIO/tardis.dat
gespeichert. Sie können
add-radio-file
, um beliebig viele Dateien hinzuzufügen.
Python-Modul
Schreiben Sie zum Erweitern der Releasetools ein Python-Modul (muss den Namen „releasetools.py“) tragen. aufrufen können, falls vorhanden. Beispiel:
device/yoyodyne/tardis/releasetools.py
import common def FullOTA_InstallEnd(info): # copy the data into the package. tardis_dat = info.input_zip.read("RADIO/tardis.dat") common.ZipWriteStr(info.output_zip, "tardis.dat", tardis_dat) # emit the script code to install this data on the device info.script.AppendExtra( """tardis.reprogram("the-key", package_extract_file("tardis.dat"));""")
Eine separate Funktion übernimmt die Generierung eines inkrementellen OTA-Pakets. In diesem Fall Angenommen, Sie müssen die Tardis-Datei nur dann neu programmieren, wenn sich die Datei tardis.dat geändert hat. zwischen zwei Builds.
def IncrementalOTA_InstallEnd(info): # copy the data into the package. source_tardis_dat = info.source_zip.read("RADIO/tardis.dat") target_tardis_dat = info.target_zip.read("RADIO/tardis.dat") if source_tardis_dat == target_tardis_dat: # tardis.dat is unchanged from previous build; no # need to reprogram it return # include the new tardis.dat in the OTA package common.ZipWriteStr(info.output_zip, "tardis.dat", target_tardis_dat) # emit the script code to install this data on the device info.script.AppendExtra( """tardis.reprogram("the-key", package_extract_file("tardis.dat"));""")
Modulfunktionen
Sie können im -Modul die folgenden Funktionen bereitstellen (nur diejenigen implementieren, die Sie benötigen).
FullOTA_Assertions()
- Wird kurz vor Beginn der Generierung eines vollständigen OTA-Updates aufgerufen. Hier können Sie Assertions ausgeben über den aktuellen Status des Geräts. Geben Sie keine Skriptbefehle aus, durch die Änderungen am .
FullOTA_InstallBegin()
- Wird aufgerufen, nachdem alle Assertions zum Gerätestatus vorbei sind, aber vor Änderungen gemacht wurden. Sie können Befehle für gerätespezifische Updates ausgeben, die vor dem alles andere auf dem Gerät geändert wurde.
FullOTA_InstallEnd()
- Wird am Ende der Skriptgenerierung nach den Skriptbefehlen zum Aktualisieren des Boot- und Systempartitionen ausgegeben wurden. Sie können auch zusätzliche Befehle für gerätespezifische Updates.
IncrementalOTA_Assertions()
-
Ähnlich wie
FullOTA_Assertions()
, wird aber beim Generieren einer inkrementellen Update-Paket. IncrementalOTA_VerifyBegin()
- Wird aufgerufen, nachdem alle Assertions zum Gerätestatus vorbei sind, aber bevor Änderungen gemacht wurden. Sie können Befehle für gerätespezifische Updates ausgeben, die vor der Ausführung von Updates ausgeführt werden müssen. auf dem Gerät geändert.
IncrementalOTA_VerifyEnd()
- Wird am Ende der Überprüfungsphase aufgerufen, wenn das Skript die Bestätigung der die es angetippt wird, den erwarteten Startinhalt haben. Zu diesem Zeitpunkt gibt es noch nichts Gerät geändert wurde. Sie können auch Code für zusätzliche gerätespezifische und Überprüfungen.
IncrementalOTA_InstallBegin()
- Wird aufgerufen, nachdem die zu patchenden Dateien auf die erwartete Version geprüft wurden before (vorherige Änderungen) Sie können Befehle für gerätespezifische Updates, die ausgeführt werden müssen, bevor andere Änderungen auf dem Gerät vorgenommen wurden.
IncrementalOTA_InstallEnd()
- Ähnlich wie beim vollständigen Gegenstück für das OTA-Paket wird dies am Ende des Skripts aufgerufen. nach der Aktualisierung der Boot- und Systempartitionen. ausgegeben. Sie können auch zusätzliche Befehle für gerätespezifische Updates ausgeben.
Hinweis:Wenn die Stromversorgung des Geräts unterbrochen wird, wird die OTA-Installation möglicherweise vom beginnen. Seien Sie darauf vorbereitet, mit Geräten vorzugehen, auf denen diese Befehle bereits ausgeführt wurden, vollständig oder teilweise.
Funktionen an Infoobjekte übergeben
Übergeben Sie Funktionen an ein einzelnes Informationsobjekt, das verschiedene nützliche Elemente enthält:
-
info.input_zip: (Nur vollständige OTAs) Das
zipfile.ZipFile
-Objekt für das .zip als Zieldateien eingeben. -
info.source_zip. (Nur inkrementelle OTAs) Das
zipfile.ZipFile
-Objekt für Die ZIP-Datei mit den Quellzieldateien (der Build, der bereits auf dem Gerät vorhanden ist, wenn das inkrementelle Paket installiert wird). -
info.target_zip (Nur inkrementelle OTAs) Das
zipfile.ZipFile
-Objekt für die Zieldateien im ZIP-Format (das inkrementelle Paket wird auf dem Gerät abgelegt) -
info.output_zip: Paket wird erstellt; ein
zipfile.ZipFile
-Objekt geöffnet für das Schreiben. Verwenden Sie „common.ZipWriteStr(info.output_zip, filename, data)“ zum Hinzufügen eines in das Paket. -
info.script Skriptobjekt, an das Sie Befehle anhängen können. Anruf
info.script.AppendExtra(script_text)
, um Text in das Skript auszugeben. Achten Sie darauf, dass der Ausgabetext mit einem Semikolon endet, damit keine Befehle ausgegeben werden .
Details zum Objekt „info“ finden Sie in der Python Software Foundation-Dokumentation für ZIP-Archive
Modulstandort angeben
Geben Sie den Speicherort des Releasetools.py-Skripts Ihres Geräts in der Datei BoardConfig.mk an:
device/yoyodyne/tardis/BoardConfig.mk
[...] TARGET_RELEASETOOLS_EXTENSIONS := device/yoyodyne/tardis
Wenn TARGET_RELEASETOOLS_EXTENSIONS nicht festgelegt ist, wird standardmäßig die
Verzeichnis $(TARGET_DEVICE_DIR)/../common
(device/yoyodyne/common
)
in diesem Beispiel). Es empfiehlt sich, den Speicherort des Skriptsreleasetools.py explizit zu definieren.
Beim Erstellen des Tardis-Geräts ist das Skript „releasetools.py“ in den Zieldateien enthalten.
ZIP-Datei (META/releasetools.py
).
Wenn Sie die Release-Tools ausführen (entweder img_from_target_files
oder
ota_from_target_files
) dem Skript „releasetools.py“ in der ZIP-Datei „target-files“, wenn
vorhanden ist, gegenüber derjenigen aus der Android-Quellstruktur. Sie können auch explizit
den Pfad zu den gerätespezifischen Erweiterungen mit -s
(oder
--device_specific
) angezeigt, die die höchste Priorität hat. So können Sie
Fehler beheben, Änderungen an den Releasetools-Erweiterungen vornehmen und diese Änderungen auf alte
Zieldateien.
Wenn Sie jetzt ota_from_target_files
ausführen, wird automatisch
gerätespezifisches Modul aus der ZIP-Datei „target_files“ und verwendet es bei der OTA-Generierung
Pakete:
./build/make/tools/releasetools/ota_from_target_files \
-i PREVIOUS-tardis-target_files.zip \
dist_output/tardis-target_files.zip \
incremental_ota_update.zip
Alternativ können Sie bei der Ausführung gerätespezifische Erweiterungen angeben.
ota_from_target_files
./build/make/tools/releasetools/ota_from_target_files \
-s device/yoyodyne/tardis \
-i PREVIOUS-tardis-target_files.zip \
dist_output/tardis-target_files.zip \
incremental_ota_update.zip
Hinweis:Eine vollständige Liste der Optionen finden Sie in der
ota_from_target_files
Kommentare in
build/make/tools/releasetools/ota_from_target_files
.
Sideloading-Mechanismus
Die Wiederherstellung verfügt über einen Sideloading-Mechanismus zum manuellen Installieren eines Updatepakets ohne Over-the-Air über das Hauptsystem herunterladen. Sideloading ist nützlich für das Debugging auf Geräten, auf denen das Hauptsystem nicht gestartet werden kann.
Bisher wurden beim Sideloading Pakete von der SD-Karte des Geräts geladen. in Lässt sich das Gerät nicht starten, kann das Paket mit einem anderen Computer und dann die SD-Karte, die in das Gerät eingelegt ist. Für Android-Geräte ohne externe Wechseldatenträger, unterstützt die Wiederherstellung zwei weitere Mechanismen für das Sideloading: Pakete werden aus der Cache-Partition geladen und sie werden mit ADB über USB geladen.
Zum Aufrufen der einzelnen Sideload-Mechanismen muss die Device::InvokeMenuItem()
-Methode deines Geräts verwendet werden
kann die folgenden Werte von „BuiltinAction“ zurückgeben:
-
ANWENDEN_EXT. Update-Paket per Sideload aus dem externen Speicher (
/sdcard
) übertragen -Verzeichnis). In „recovery.fstab“ muss der Bereitstellungspunkt/sdcard
definiert werden. Dies ist nicht verwendbar auf Geräten, die eine SD-Karte mit einem Symlink zu/data
(oder einigen ähnlichen Mechanismus)./data
ist normalerweise nicht für die Wiederherstellung verfügbar, weil verschlüsselt sein. Auf der Benutzeroberfläche zur Wiederherstellung wird in/sdcard
ein Menü mit ZIP-Dateien angezeigt. kann der Nutzer eine Option auswählen. -
ANWENDEN_CACHE Ähnlich wie beim Laden eines Pakets aus
/sdcard
, mit der Ausnahme, dass Das Verzeichnis/cache
(das immer für die Wiederherstellung verfügbar ist) wird verwendet . Im regulären System kann/cache
nur von privilegierten Nutzern geschrieben werden. Wenn das Gerät nicht bootfähig ist, kann nicht in das Verzeichnis/cache
geschrieben werden. wodurch dieser Mechanismus nur begrenzt nützlich ist. -
APPLY_ADB_SIDELOAD festlegen. Ermöglicht dem Nutzer, über ein USB-Kabel ein Paket an das Gerät zu senden und
das ADB-Entwicklungstool. Wenn dieser Mechanismus aufgerufen wird, startet die Wiederherstellung eine eigene Miniversion
Version des adbd-Daemons, damit ADB auf einem
verbundenen Hostcomputer mit ihm kommunizieren kann. Dieses Mini
Version unterstützt nur einen Befehl:
adb sideload filename
. Die benannte Datei wird vom Hostcomputer an das Gerät gesendet, das dann installiert es genau wie im lokalen Speicher.
Einige Einschränkungen:
- Es wird nur USB-Transport unterstützt.
-
Wenn bei der Wiederherstellung adbd normal ausgeführt wird (normalerweise bei UserDebug- und Eng-Builds „true“),
wird heruntergefahren, während sich das Gerät im ADB-Sideload-Modus befindet und wird neu gestartet, wenn ADB
Sideload hat ein Paket empfangen. Im ADB-Sideload-Modus werden keine ADB-Befehle
als
sideload
(logcat
,reboot
,push
,pull
,shell
usw. schlagen fehl). -
Sie können den ADB-Sideload-Modus auf dem Gerät nicht beenden. Zum Abbrechen können Sie
/dev/null
(oder etwas anderes, das kein gültiges Paket ist) als Paket und kann dies nicht bestätigt werden und der Installationsvorgang wird abgebrochen. Wiederherstellungs-UI wird die MethodeCheckKey()
der Implementierung für Tastendruck Sie können also eine Zeichenfolge bereitstellen, die das Gerät neu startet und im ADB-Sideload-Modus funktioniert.