Kurtarma sistemi, OTA güncellemelerinin Android sistemi dışındaki cihaz parçalarını (ör. temel bant veya radyo işlemcisi) da güncelleyebilmesi için cihaza özel kod eklemeye yönelik çeşitli kancalar içerir.
Aşağıdaki bölümlerde ve örneklerde, yoyodyne satıcısı tarafından üretilen tardis cihazı özelleştirilmektedir.
Bölüm haritası
Android 2.3'ten itibaren platform, eMMc flash cihazları ve bu cihazlarda çalışan ext4 dosya sistemini destekler. Ayrıca, eski sürümlerdeki Memory Technology Device (MTD) flash cihazlarını ve yaffs2 dosya sistemini de destekler.
Bölüm haritası dosyası TARGET_RECOVERY_FSTAB ile belirtilir. Bu dosya hem kurtarma ikilisi hem de paket oluşturma araçları tarafından kullanılır. Harita dosyasının adını BoardConfig.mk dosyasındaki TARGET_RECOVERY_FSTAB içinde belirtebilirsiniz.
Örnek bir bölüm haritası dosyası şu şekilde görünebilir:
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
İsteğe bağlı olan /sdcard
dışında, bu örnekteki tüm bağlama noktaları tanımlanmalıdır (cihazlar ek bölümler de ekleyebilir). Desteklenen beş dosya sistemi türü vardır:
- yaffs2
-
MTD flash cihazının üzerinde bir yaffs2 dosya sistemi. "device", MTD bölümünün adı olmalı ve
/proc/mtd
içinde görünmelidir. - mtd
-
Başlatma ve kurtarma gibi önyüklenebilir bölümler için kullanılan ham bir MTD bölümü. MTD aslında bağlanmaz ancak bağlama noktası, bölümü bulmak için anahtar olarak kullanılır. "device"
/proc/mtd
içindeki MTD bölümünün adı olmalıdır. - ext4
- eMMc flash cihazının üzerinde bir ext4 dosya sistemi. "device", blok cihazının yolu olmalıdır.
- emmc
- Önyükleme ve kurtarma gibi önyüklenebilir bölümler için kullanılan ham bir eMMC blok cihazı. mtd türüne benzer şekilde, eMMC hiçbir zaman gerçekten bağlanmaz ancak bağlama noktası dizesi, cihazı tabloda bulmak için kullanılır.
- vfat
-
Genellikle SD kart gibi harici depolama için kullanılan bir blok cihazın üzerinde FAT dosya sistemi. Birincil cihaz, blok cihazdır. İkincil cihaz ise birincil cihazın bağlanması başarısız olursa sistemin bağlamaya çalıştığı ikinci bir blok cihazdır (bölüm tablosuyla biçimlendirilmiş veya biçimlendirilmemiş olabilecek SD kartlarla uyumluluk için).
Tüm bölümler kök dizine bağlanmalıdır (yani bağlama noktası değeri eğik çizgiyle başlamalı ve başka eğik çizgi içermemelidir). Bu kısıtlama yalnızca kurtarma modunda dosya sistemlerini bağlama işlemi için geçerlidir. Ana sistem, bu dosya sistemlerini istediği yere bağlayabilir.
/boot
,/recovery
ve/misc
dizinleri ham türler (mtd veya emmc),/system
,/data
,/cache
ve/sdcard
dizinleri (varsa) ise dosya sistemi türleri (yaffs2, ext4 veya vfat) olmalıdır.
Android 3.0'dan itibaren recovery.fstab dosyasına isteğe bağlı ek bir alan olan options eklenir. Şu anda tanımlanan tek seçenek length 'tir. Bu seçenek, bölümün uzunluğunu açıkça belirtmenize olanak tanır. Bu uzunluk, bölüm yeniden biçimlendirilirken (ör. veri silme/fabrika ayarlarına sıfırlama işlemi sırasında userdata bölümü için veya tam OTA paketi yüklenirken system bölümü için) kullanılır. Uzunluk değeri negatifse biçimlendirilecek boyut, uzunluk değerinin gerçek bölüm boyutuna eklenmesiyle elde edilir. Örneğin, "length=-16384" ayarlandığında bölüm yeniden biçimlendirilirken bu bölümün son 16k'lık kısmı üzerine yazılmaz. Bu, kullanıcı verileri bölümünün şifrelenmesi (şifreleme meta verilerinin, bölümün sonunda depolandığı ve üzerine yazılmaması gereken yer) gibi özellikleri destekler.
Not: device2 ve options alanları isteğe bağlıdır ve ayrıştırmada belirsizlik oluşturur. Satırdaki dördüncü alandaki giriş "/" karakteriyle başlıyorsa device2 girişi olarak kabul edilir. Giriş "/" karakteriyle başlamıyorsa options alanı olarak kabul edilir.
Açılış animasyonu
Cihaz üreticileri, bir Android cihaz başlatılırken gösterilen animasyonu özelleştirebilir. Bunu yapmak için bootanimation biçimindeki spesifikasyonlara göre düzenlenmiş ve yerleştirilmiş bir .zip dosyası oluşturun.
Android Things cihazlarda, resimlerin seçilen ürüne dahil edilmesi için zip dosyasını Android Things konsoluna yükleyebilirsiniz.
Not: Bu resimler Android marka yönergelerine uygun olmalıdır. Marka kuralları için İş Ortağı Pazarlama Merkezi'nin Android bölümüne bakın.
Kurtarma kullanıcı arayüzü
Farklı donanımlara (fiziksel düğmeler, LED'ler, ekranlar vb.) sahip cihazları desteklemek için, kurtarma arayüzünü, durumu gösterecek ve her cihaz için manuel olarak çalıştırılan gizli özelliklere erişecek şekilde özelleştirebilirsiniz.
Amacınız, cihaza özgü işlevselliği sağlamak için birkaç C++ nesnesi içeren küçük bir statik kitaplık oluşturmaktır. Varsayılan olarak kullanılan bootable/recovery/default_device.cpp
dosyası, cihazınız için bu dosyanın bir sürümünü yazarken kopyalamak için iyi bir başlangıç noktasıdır.
Not: Burada No Command (Komut Yok) mesajını görebilirsiniz. Metni değiştirmek için sesi artırma düğmesine basarken güç düğmesini basılı tutun. Cihazınızda her iki düğme de yoksa metni değiştirmek için herhangi bir düğmeye uzun basın.
device/yoyodyne/tardis/recovery/recovery_ui.cpp
#include <linux/input.h> #include "common.h" #include "device.h" #include "screen_ui.h"
Başlık ve öğe işlevleri
Cihaz sınıfı, gizli kurtarma menüsünde görünen başlıkları ve öğeleri döndürmek için işlevler gerektirir. Başlıklar, menünün nasıl kullanılacağını (ör. vurgulanan öğeyi değiştirme/seçme kontrolleri) açıklar.
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 };
Not: Uzun satırlar kesilir (sarmalanmaz). Bu nedenle, cihaz ekranınızın genişliğini göz önünde bulundurun.
Customize CheckKey
Ardından, cihazınızın RecoveryUI uygulamasını tanımlayın. Bu örnekte, tardis cihazının ekranı olduğu varsayılmaktadır. Bu nedenle, yerleşik ScreenRecoveryUI uygulamasından devralabilirsiniz (ekranı olmayan cihazlarla ilgili talimatlara bakın). ScreenRecoveryUI'den özelleştirilebilen tek işlev, ilk eşzamansız anahtar işleme işlemini yapan CheckKey()
işlevidir:
class TardisUI : public ScreenRecoveryUI { public: virtual KeyAction CheckKey(int key) { if (key == KEY_HOME) { return TOGGLE; } return ENQUEUE; } };
KEY sabitleri
KEY_* sabitleri linux/input.h
içinde tanımlanır. CheckKey()
, kurtarma işleminin geri kalanında ne olursa olsun (menü kapatıldığında, açıkken, paket yükleme sırasında, kullanıcı verileri silinirken vb.) çağrılır. Dört sabitten birini döndürebilir:
- TOGGLE. Menü ve/veya metin günlüğünün gösterilmesini açma veya kapatma
- REBOOT (YENİDEN BAŞLAT). Cihazı hemen yeniden başlatın.
- IGNORE (YOK SAY). Bu tuşa basma işlemini yoksay
- ENQUEUE (KUYRUK) Bu tuşa basma işlemini eşzamanlı olarak kullanılmak üzere (ör.ekran etkinse kurtarma menüsü sistemi tarafından) sıraya alın.
CheckKey()
, aynı tuş için bir tuşa basma etkinliğini bir tuşu bırakma etkinliği her takip ettiğinde çağrılır. (Aşağıdaki etkinlik sırası A-down B-down B-up A-up yalnızca CheckKey(B)
çağrılmasıyla sonuçlanır.) Diğer tuşların basılı tutulup tutulmadığını öğrenmek için CheckKey()
tuşuna basarak IsKeyPressed()
tuşunu arayabilirsiniz. (Yukarıdaki önemli etkinlikler dizisinde, CheckKey(B)
IsKeyPressed(A)
'ı çağırsaydı doğru değerini döndürürdü.)
CheckKey()
sınıfında durumu koruyabilir. Bu, tuş dizilerini algılamak için yararlı olabilir. Bu örnekte biraz daha karmaşık bir kurulum gösterilmektedir: Ekran, güç düğmesi basılı tutulup ses açma düğmesine basılarak açılıp kapatılır. Cihaz, güç düğmesine art arda beş kez basılarak (arada başka bir tuşa basılmadan) hemen yeniden başlatılabilir:
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; } };
ScreenRecoveryUI
ScreenRecoveryUI ile kendi resimlerinizi (hata simgesi, yükleme animasyonu, ilerleme çubukları) kullanırken animasyonların saniyedeki kare hızını (FPS) kontrol etmek için animation_fps
değişkenini ayarlayabilirsiniz.
Not: Mevcut interlace-frames.py
komut dosyası, animation_fps
bilgilerini resmin kendisinde saklamanıza olanak tanır. Android'in önceki sürümlerinde animation_fps
değerini kendiniz ayarlamanız gerekiyordu.
animation_fps
değişkenini ayarlamak için alt sınıfınızdaki ScreenRecoveryUI::Init()
işlevini geçersiz kılın. Değeri ayarlayın, ardından ilk kullanıma hazırlama işlemini tamamlamak için parent Init()
işlevini çağırın. Varsayılan değer (20 FPS), varsayılan kurtarma görüntüleriyle eşleşir. Bu görüntüleri kullanırken Init()
işlevi sağlamanız gerekmez. Resimlerle ilgili ayrıntılar için Kurtarma kullanıcı arayüzü resimleri başlıklı makaleyi inceleyin.
Cihaz sınıfı
RecoveryUI uygulamanız olduktan sonra cihaz sınıfınızı tanımlayın (yerleşik Cihaz sınıfından alt sınıflandırılmış). Kullanıcı arayüzü sınıfınızın tek bir örneğini oluşturmalı ve bunu GetUI()
işlevinden döndürmelidir:
class TardisDevice : public Device { private: TardisUI* ui; public: TardisDevice() : ui(new TardisUI) { } RecoveryUI* GetUI() { return ui; }
StartRecovery
StartRecovery()
yöntemi, kurtarma işleminin başında, kullanıcı arayüzü başlatıldıktan ve bağımsız değişkenler ayrıştırıldıktan sonra ancak herhangi bir işlem yapılmadan önce çağrılır. Varsayılan uygulama hiçbir şey yapmaz. Dolayısıyla yapmanız gereken bir şey yoksa bu işlevi alt sınıfınızda sağlamanız gerekmez:
void StartRecovery() { // ... do something tardis-specific here, if needed .... }
Kurtarma menüsünü sağlama ve yönetme
Sistem, başlık satırları listesini ve öğe listesini almak için iki yöntem çağırır. Bu uygulamada, dosyanın üst kısmında tanımlanan statik diziler döndürülür:
const char* const* GetMenuHeaders() { return HEADERS; } const char* const* GetMenuItems() { return ITEMS; }
HandleMenuKey
Ardından, bir tuşa basma işlemini ve mevcut menü görünürlüğünü alan ve hangi işlemin yapılacağına karar veren bir HandleMenuKey()
işlevi sağlayın:
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; }
Bu yöntem, daha önce işlenmiş ve kullanıcı arayüzü nesnesinin CheckKey()
yöntemi tarafından sıraya alınmış bir anahtar kodu ile menü/metin günlüğü görünürlüğünün mevcut durumunu alır. Döndürülen değer bir tam sayıdır. Değer 0 veya daha yüksekse bu değer, hemen çağrılan bir menü öğesinin konumu olarak kabul edilir (aşağıdaki InvokeMenuItem()
yöntemine bakın). Aksi takdirde, aşağıdaki önceden tanımlanmış sabitlerden biri olabilir:
- kHighlightUp. Menü vurgusunu önceki öğeye taşıma
- kHighlightDown. Menü vurgusunu sonraki öğeye taşıma
- kInvokeItem. Şu anda vurgulanan öğeyi çağırma
- kNoAction. Bu tuş vuruşuyla hiçbir işlem yapma
Görünür bağımsız değişkenden de anlaşılacağı gibi, menü görünür olmasa bile HandleMenuKey()
çağrılır. CheckKey()
'dan farklı olarak, kurtarma işlemi veri silme veya paket yükleme gibi bir işlem yaparken çağrılmaz. Yalnızca kurtarma işlemi boşta kalıp giriş beklerken çağrılır.
İztopu mekanizmaları
Cihazınızda trackball benzeri bir giriş mekanizması varsa (EV_REL türünde ve REL_Y kodlu giriş etkinlikleri oluşturur), kurtarma, trackball benzeri giriş cihazı Y ekseninde hareket bildirdiğinde KEY_UP ve KEY_DOWN tuş basımlarını sentezler. Tek yapmanız gereken KEY_UP ve KEY_DOWN etkinliklerini menü işlemlerine eşlemektir. Bu eşleme gerçekleşmediği için
CheckKey()
, trackball hareketlerini yeniden başlatma veya ekranı açıp kapatma tetikleyicileri olarak kullanamazsınız.
Değiştirici tuşlar
Değiştirici olarak basılı tutulan tuşları kontrol etmek için kendi kullanıcı arayüzü nesnenizin IsKeyPressed()
yöntemini çağırın. Örneğin, bazı cihazlarda kurtarma modunda Alt-W tuşlarına basıldığında menü görünür olsun veya olmasın veri temizleme işlemi başlatılırdı. Aşağıdaki gibi bir uygulama yapabilirsiniz:
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 } ... }
Not: visible değeri yanlışsa kullanıcının vurguyu göremeyeceği için menüyü değiştiren (vurguyu taşıma, vurgulanan öğeyi çağırma) özel değerlerin döndürülmesi mantıklı değildir. Ancak isterseniz değerleri geri döndürebilirsiniz.
InvokeMenuItem
Ardından, GetMenuItems()
tarafından döndürülen öğe dizisindeki tam sayı konumlarını işlemlere eşleyen bir InvokeMenuItem()
yöntemi sağlayın. Tardis örneğindeki öğe dizisi için şunu kullanın:
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; } }
Bu yöntem, sisteme bu işlemi yapmasını söylemek için BuiltinAction numaralandırmasının herhangi bir üyesini (veya sistemin hiçbir şey yapmasını istiyorsanız NO_ACTION üyesini) döndürebilir. Bu, sistemde bulunanların ötesinde ek kurtarma işlevleri sağlamak için kullanılan yerdir: Menünüze bunun için bir öğe ekleyin, bu menü öğesi çağrıldığında burada yürütün ve sistemin başka bir işlem yapmaması için NO_ACTION değerini döndürün.
BuiltinAction aşağıdaki değerleri içerir:
- NO_ACTION. Hiçbir işlem yapmamayı tercih edebilirsiniz.
- REBOOT (YENİDEN BAŞLAT). Kurtarma modundan çıkın ve cihazı normal şekilde yeniden başlatın.
- APPLY_EXT, APPLY_CACHE, APPLY_ADB_SIDELOAD. Çeşitli yerlerden güncelleme paketi yükleme Ayrıntılar için Yan yükleme bölümünü inceleyin.
- WIPE_CACHE. Yalnızca önbellek bölümünü yeniden biçimlendirin. Bu nispeten zararsız olduğundan onay gerekmez.
- WIPE_DATA. Kullanıcı verileri ve önbellek bölümlerini yeniden biçimlendirin. Bu işlem, fabrika ayarlarına sıfırlama olarak da bilinir. Kullanıcıdan devam etmeden önce bu işlemi onaylaması istenir.
Son yöntem olan WipeData()
isteğe bağlıdır ve bir veri silme işlemi başlatıldığında (menü üzerinden kurtarma veya kullanıcının ana sistemden fabrika verilerine sıfırlama işlemini seçmesi) çağrılır. Bu yöntem, kullanıcı verileri ve önbellek bölümleri silinmeden önce çağrılır. Cihazınız, kullanıcı verilerini bu iki bölüm dışında bir yerde saklıyorsa verileri buradan silmeniz gerekir. Başarıyı belirtmek için 0, başarısızlığı belirtmek için ise başka bir değer döndürmeniz gerekir. Ancak şu anda dönüş değeri yoksayılmaktadır. Başarı veya başarısızlık döndürmenizden bağımsız olarak kullanıcı verileri ve önbellek bölümleri silinir.
int WipeData() { // ... do something tardis-specific here, if needed .... return 0; }
Cihazı çal
Son olarak, Device sınıfınızın bir örneğini oluşturan ve döndüren make_device()
işlevi için recovery_ui.cpp dosyasının sonuna bazı standart metinler ekleyin:
class TardisDevice : public Device { // ... all the above methods ... }; Device* make_device() { return new TardisDevice(); }
Cihaz kurtarma oluşturma ve bağlama
recovery_ui.cpp dosyasını tamamladıktan sonra dosyayı oluşturun ve cihazınızdaki kurtarmaya bağlayın. Android.mk dosyasında yalnızca bu C++ dosyasını içeren statik bir kitaplık oluşturun:
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)
Ardından, bu cihazın kart yapılandırmasında, TARGET_RECOVERY_UI_LIB değerini statik kitaplığınız olarak belirtin.
device/yoyodyne/tardis/BoardConfig.mk [...] # device-specific extensions to the recovery UI TARGET_RECOVERY_UI_LIB := librecovery_ui_tardis
Kurtarma kullanıcı arayüzü resimleri
Kurtarma kullanıcı arayüzü resimlerden oluşur. İdeal olarak, kullanıcılar hiçbir zaman kullanıcı arayüzüyle etkileşime girmez: Normal bir güncelleme sırasında telefon kurtarma modunda başlatılır, yükleme ilerleme çubuğu doldurulur, ve kullanıcıdan herhangi bir giriş alınmadan yeni sistemde yeniden başlatılır. Sistem güncellemesiyle ilgili bir sorun olması durumunda, yapılabilecek tek kullanıcı işlemi müşteri hizmetlerini aramaktır.
Yalnızca resimlerden oluşan bir arayüz, yerelleştirme ihtiyacını ortadan kaldırır. Ancak Android 5.0'dan itibaren güncelleme, resimle birlikte bir metin dizesi (ör. "Sistem güncellemesi yükleniyor...") gösterebilir. Ayrıntılar için Yerelleştirilmiş kurtarma metni başlıklı makaleyi inceleyin.
Android 5.0 ve sonraki sürümler
Android 5.0 ve sonraki sürümlerdeki kurtarma kullanıcı arayüzünde iki ana resim kullanılır: hata resmi ve yükleme animasyonu.
![]() Şekil 1. icon_error.png |
![]() Şekil 2. icon_installing.png |
Yükleme animasyonu, animasyonun farklı kareleri satır satır iç içe geçmiş tek bir PNG resmi olarak gösterilir (bu nedenle Şekil 2 sıkıştırılmış gibi görünür). Örneğin, 200x200 boyutunda yedi karelik bir animasyon için tek bir 200x1400 boyutunda resim oluşturun. Bu resimde ilk kare 0, 7, 14, 21, ... satırları, ikinci kare 1, 8, 15, 22, ... satırları vb. şeklindedir. Birleştirilmiş resimde, animasyon karelerinin sayısını ve saniyedeki kare sayısını (FPS) belirten bir metin parçası bulunur. Araç bootable/recovery/interlace-frames.py
, bir dizi giriş karesi alır ve bunları kurtarma tarafından kullanılan gerekli bileşik görüntüde birleştirir.
Varsayılan resimler farklı yoğunluklarda kullanılabilir ve bootable/recovery/res-$DENSITY/images
konumunda bulunur (ör.
bootable/recovery/res-hdpi/images
). Yükleme sırasında statik bir resim kullanmak için yalnızca icon_installing.png resmini sağlamanız ve animasyondaki kare sayısını 0 olarak ayarlamanız gerekir (hata simgesi animasyonlu değildir, her zaman statik bir resimdir).
Android 4.x ve önceki sürümler
Android 4.x ve önceki sürümlerdeki kurtarma kullanıcı arayüzünde hata resmi (yukarıda gösterilmiştir) ve yükleme animasyonu ile birkaç yer paylaşımı resmi kullanılır:
![]() Şekil 3. icon_installing.png |
![]() Şekil 4. icon-installing_overlay01.png |
![]() Şekil 5. icon_installing_overlay07.png |
Kurulum sırasında, ekran görüntüsü icon_installing.png resmi çizilerek ve ardından uygun ofsetle üzerine yerleştirme çerçevelerinden biri çizilerek oluşturulur. Burada, kırmızı bir kutuyla kaplamanın temel resmin üzerine yerleştirildiği nokta vurgulanıyor:
![]() 6.şekil Animasyon karesi 1 yükleniyor (icon_installing.png + icon_installing_overlay01.png) |
![]() Şekil 7. 7. animasyon karesi yükleniyor (icon_installing.png + icon_installing_overlay07.png) |
Sonraki kareler, yalnızca bir sonraki yer paylaşımı resmi mevcut görüntünün üzerine çizilerek gösterilir. Temel resim yeniden çizilmez.
Animasyondaki kare sayısı, istenen hız ve yer paylaşımının tabana göre x ve y uzaklıkları, ScreenRecoveryUI sınıfının üye değişkenleriyle ayarlanır. Varsayılan resimler yerine özel resimler kullanırken alt sınıfınızdaki Init()
yöntemini geçersiz kılarak özel resimlerinizin bu değerlerini değiştirin (ayrıntılar için ScreenRecoveryUI başlıklı makaleyi inceleyin). bootable/recovery/make-overlay.py
komut dosyası, gerekli ofsetlerin hesaplanması da dahil olmak üzere bir dizi görüntü karesini kurtarma için gereken "temel görüntü + yer paylaşımı görüntüleri" biçimine dönüştürmeye yardımcı olabilir.
Varsayılan resimler bootable/recovery/res/images
konumunda bulunur. Yükleme sırasında statik resim kullanmak için yalnızca icon_installing.png resmini sağlamanız ve animasyondaki kare sayısını 0 olarak ayarlamanız gerekir (hata simgesi animasyonlu değildir, her zaman statik bir resimdir).
Yerelleştirilmiş kurtarma metni
Android 5.x'te bir metin dizesi (ör. "Sistem güncellemesi yükleniyor...") mesajı ve resim gösterilir. Ana sistem kurtarma modunda başlatıldığında kullanıcının mevcut yerel ayarını kurtarma moduna komut satırı seçeneği olarak iletir. Kurtarma işlemi, gösterilecek her mesaj için her yerel ayarda bu mesaja ait önceden oluşturulmuş metin dizelerini içeren ikinci bir bileşik resim içerir.
Kurtarma metni dizeleriyle ilgili örnek resim:

Şekil 8. Kurtarma mesajları için yerelleştirilmiş metin
Kurtarma metninde aşağıdaki mesajlar gösterilebilir:
- Sistem güncellemesi yükleniyor...
- Hata!
- Siliniyor... (Verileri silme/fabrika ayarlarına sıfırlama işlemi yaparken)
- Komut yok (kullanıcı kurtarma moduna manuel olarak önyükleme yaptığında)
bootable/recovery/tools/recovery_l10n/
Android uygulaması, mesajın yerelleştirilmiş sürümlerini oluşturur ve birleşik resmi oluşturur. Bu uygulamayı kullanmayla ilgili ayrıntılar için bootable/recovery/tools/recovery_l10n/src/com/android/recovery_l10n/Main.java
bölümündeki yorumlara bakın.
Bir kullanıcı kurtarma moduna manuel olarak önyükleme yaptığında yerel ayar kullanılamayabilir ve metin gösterilmez. Metin mesajlarını kurtarma süreci için kritik hale getirmeyin.
Not: Günlük mesajlarını görüntüleyen ve kullanıcının menüden işlem seçmesine olanak tanıyan gizli arayüz yalnızca İngilizce olarak kullanılabilir.
İlerleme çubukları
İlerleme çubukları, ana resmin (veya animasyonun) altında görünebilir. İlerleme çubuğu, aynı boyutta olması gereken iki giriş resmi birleştirilerek oluşturulur:

Şekil 9. progress_empty.png

Şekil 10. progress_fill.png
İlerleme çubuğunu oluşturmak için dolu resmin sol ucu, boş resmin sağ ucunun yanında gösterilir. İki resim arasındaki sınırın konumu, ilerleme durumunu gösterecek şekilde değiştirilir. Örneğin, yukarıdaki giriş resmi çiftleriyle birlikte şu sonuçlar gösterilir:

11.Şekil %1'de ilerleme çubuğu>

Şekil 12. %10 ilerleme çubuğu

Şekil 13. %50 ilerleme çubuğu
Bu resimleri (bu örnekte) device/yoyodyne/tardis/recovery/res/images
klasörüne yerleştirerek cihaza özel sürümlerini sağlayabilirsiniz. Dosya adları, yukarıda listelenenlerle eşleşmelidir. Bu dizinde bir dosya bulunduğunda derleme sistemi, ilgili varsayılan resim yerine bu dosyayı kullanır. Yalnızca 8 bit renk derinliğine sahip RGB veya RGBA biçimindeki PNG'ler desteklenir.
Not: Android 5.x'te yerel ayar kurtarma tarafından biliniyorsa ve sağdan sola (RTL) yazılan bir dilse (Arapça, İbranice vb.) ilerleme çubuğu sağdan sola doğru dolar.
Ekranı olmayan cihazlar
Tüm Android cihazlarda ekran bulunmaz. Cihazınız başsız bir cihazsa veya yalnızca ses arayüzü varsa kurtarma kullanıcı arayüzünde daha kapsamlı bir özelleştirme yapmanız gerekebilir. ScreenRecoveryUI'nin alt sınıfını oluşturmak yerine, üst sınıfı RecoveryUI'nin alt sınıfını doğrudan oluşturun.
RecoveryUI,"ekranı açma/kapatma", "ilerleme çubuğunu güncelleme", "menüyü gösterme", "menü seçimini değiştirme" gibi alt düzey kullanıcı arayüzü işlemlerini yönetme yöntemlerine sahiptir. Bunları geçersiz kılarak cihazınız için uygun bir arayüz sağlayabilirsiniz. Cihazınızda, durumu belirtmek için farklı renkler veya yanıp sönme düzenleri kullanabileceğiniz LED'ler olabilir ya da ses çalabilirsiniz. (Belki de menüyü veya "metin görüntüleme" modunu hiç desteklemek istemiyorsunuzdur. Bu durumda, ekranı hiçbir zaman açmayan veya menü öğesi seçmeyen CheckKey()
ve HandleMenuKey()
uygulamalarıyla bunlara erişimi engelleyebilirsiniz. Bu durumda, sağlamanız gereken RecoveryUI yöntemlerinin çoğu boş olabilir.)
Desteklemeniz gereken yöntemleri görmek için RecoveryUI beyanına ilişkin bootable/recovery/ui.h
bölümüne bakın. RecoveryUI soyuttur. Bazı yöntemler tamamen sanaldır ve alt sınıflar tarafından sağlanmalıdır. Ancak anahtar girişlerinin işlenmesi için gereken kodu içerir. Cihazınızda tuş yoksa veya bunları farklı şekilde işlemek istiyorsanız bu ayarı da geçersiz kılabilirsiniz.
Güncelleyici
Güncelleme paketinin yüklenmesinde cihaza özel kod kullanmak için kendi uzantı işlevlerinizi sağlayabilirsiniz. Bu işlevler, güncelleyici komut dosyanızdan çağrılabilir. Tardis cihazı için örnek bir işlev aşağıda verilmiştir:
device/yoyodyne/tardis/recovery/recovery_updater.c
#include <stdlib.h> #include <string.h> #include "edify/expr.h"
Her uzantı işlevinin imzası aynıdır. Bağımsız değişkenler, işlevin çağrıldığı ad, bir State*
çerezi, gelen bağımsız değişkenlerin sayısı ve bağımsız değişkenleri temsil eden Expr*
işaretçiler dizisidir. Döndürülen değer, yeni ayrılmış bir Value*
'dır.
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); }
İşleviniz çağrıldığında bağımsız değişkenleriniz değerlendirilmez. Hangi bağımsız değişkenlerin kaç kez değerlendirileceğini işlevinizin mantığı belirler. Bu nedenle, kendi kontrol yapılarınızı uygulamak için uzantı işlevlerini kullanabilirsiniz. Call Evaluate()
işlevi, Expr*
bağımsız değişkenini değerlendirerek Value*
değerini döndürür. Evaluate()
NULL döndürürse tuttuğunuz tüm kaynakları serbest bırakmalı ve hemen NULL döndürmelisiniz (bu, edify yığınında iptalleri yayar). Aksi takdirde, döndürülen değerin sahipliğini alırsınız ve sonunda FreeValue()
işlevini çağırmaktan sorumlu olursunuz.
İşlevin iki bağımsız değişkene ihtiyacı olduğunu varsayalım: dize değerli bir anahtar ve blob değerli bir resim. Şu gibi argümanları okuyabilirsiniz:
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; }
NULL değerini kontrol etme ve daha önce değerlendirilmiş bağımsız değişkenleri serbest bırakma işlemi, birden fazla bağımsız değişken için sıkıcı olabilir. ReadValueArgs()
işlevi bu işlemi kolaylaştırabilir. Yukarıdaki kod yerine şunu yazabilirsiniz:
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()
tür denetimi yapmaz. Bu nedenle, bunu burada yapmanız gerekir. Başarısız olduğunda biraz daha az spesifik bir hata mesajı üretme pahasına tek bir if ifadesiyle yapmak daha uygundur. Ancak ReadValueArgs()
, her bağımsız değişkeni değerlendirme ve değerlendirmelerden herhangi biri başarısız olursa daha önce değerlendirilen tüm bağımsız değişkenleri serbest bırakma (ve yararlı bir hata mesajı ayarlama) işlemlerini gerçekleştirir. Değişken sayıda bağımsız değişkeni değerlendirmek için ReadValueVarArgs()
kolaylık işlevini kullanabilirsiniz (Value*
dizisi döndürür).
Argümanları değerlendirdikten sonra fonksiyonun işini yapın:
// 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 ...
Dönüş değeri bir Value*
nesnesi olmalıdır. Bu nesnenin sahipliği, arayan kişiye geçer. Arayan, bu işaretçinin gösterdiği tüm verilerin (özellikle veri üyesi) sahipliğini alır.Value*
Bu örnekte, başarıyı belirtmek için doğru veya yanlış değeri döndürmek istiyorsunuz. Boş dizenin yanlış, diğer tüm dizelerin ise doğru olduğunu unutmayın. Arayan her ikisini de free()
edeceğinden, döndürülecek sabit dizenin malloc'd kopyasıyla bir Value nesnesi malloc etmeniz gerekir. Argümanlarınızı değerlendirerek elde ettiğiniz nesneler üzerinde FreeValue()
işlevini çağırmayı unutmayın.
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; }
Kolaylık işlevi StringValue()
, bir dizeyi yeni bir Value nesnesine sarmalar.
Yukarıdaki kodu daha kısa yazmak için kullanın:
FreeValue(key); FreeValue(image); return StringValue(strdup(successful ? "t" : "")); }
İşlevleri edify yorumlayıcısına bağlamak için işlevi sağlayın.
Register_foo
Burada foo, bu kodu içeren statik kitaplığın adıdır. Her uzantı işlevini kaydetmek için RegisterFunction()
işlevini çağırın. Gelecekte eklenecek yerleşik işlevlerle çakışmaları önlemek için cihazlara özel işlevleri device.whatever
adlandırın.
void Register_librecovery_updater_tardis() { RegisterFunction("tardis.reprogram", ReprogramTardisFn); }
Artık makefile'ı, kodunuzla statik bir kitaplık oluşturacak şekilde yapılandırabilirsiniz. (Bu, önceki bölümde kurtarma kullanıcı arayüzünü özelleştirmek için kullanılan makefile ile aynıdır. Cihazınızda burada tanımlanan her iki statik kitaplık da olabilir.)
device/yoyodyne/tardis/recovery/Android.mk
include $(CLEAR_VARS) LOCAL_SRC_FILES := recovery_updater.c LOCAL_C_INCLUDES += bootable/recovery
Statik kitaplığın adı, içerdiği Register_libname
işlevinin adıyla eşleşmelidir.
LOCAL_MODULE := librecovery_updater_tardis include $(BUILD_STATIC_LIBRARY)
Son olarak, kitaplığınızı çekmek için kurtarma derlemesini yapılandırın. Kitaplığınızı TARGET_RECOVERY_UPDATER_LIBS'e ekleyin (birden fazla kitaplık içerebilir; hepsi kaydedilir).
Kodunuz, kendileri edify uzantısı olmayan diğer statik kitaplıklara bağlıysa (ör.
işlevi yoksa), bunları TARGET_RECOVERY_UPDATER_EXTRA_LIBS'de listeleyerek kayıt işlevlerini (olmayan) çağırmadan güncelleyiciye bağlayabilirsiniz.Register_libname
Örneğin, cihaza özel kodunuz verileri sıkıştırmak için zlib'i kullanmak istiyorsa libz'yi buraya dahil edersiniz.
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 +=
OTA paketinizdeki güncelleyici komut dosyaları artık işlevinizi diğerleri gibi çağırabilir. Tardis cihazınızı yeniden programlamak için güncelleme komut dosyası şunları içerebilir:
tardis.reprogram("the-key", package_extract_file("tardis-image.dat"))
. Bu işlev, yerleşik işlev package_extract_file()
'nın tek bağımsız değişkenli sürümünü kullanır. Bu sürüm, yeni uzantı işlevinin ikinci bağımsız değişkenini oluşturmak için güncelleme paketinden çıkarılan bir dosyanın içeriğini blob olarak döndürür.
OTA paketi oluşturma
Son bileşen, OTA paketi oluşturma araçlarının cihaza özel verileriniz hakkında bilgi edinmesini ve uzantı işlevlerinize yapılan çağrıları içeren güncelleyici komut dosyaları yayınlamasını sağlamaktır.
Öncelikle, derleme sisteminin cihaza özgü bir veri blobu hakkında bilgi edinmesini sağlayın. Veri dosyanızın device/yoyodyne/tardis/tardis.dat
içinde olduğunu varsayarsak cihazınızın AndroidBoard.mk dosyasında aşağıdakileri beyan edin:
device/yoyodyne/tardis/AndroidBoard.mk
[...] $(call add-radio-file,tardis.dat)
Bunu Android.mk dosyasına da yerleştirebilirsiniz ancak bu durumda, ağaçtaki tüm Android.mk dosyaları hangi cihaz oluşturulursa oluşturulsun yüklendiğinden bir cihaz kontrolüyle korunması gerekir. (Ağacınızda birden fazla cihaz varsa tardis cihazı oluşturulurken yalnızca tardis.dat dosyasının eklenmesini istersiniz.)
device/yoyodyne/tardis/Android.mk
[...] # an alternative to specifying it in AndroidBoard.mk ifeq (($TARGET_DEVICE),tardis) $(call add-radio-file,tardis.dat) endif
Bunlara geçmişte radyo dosyaları deniyordu. Cihaz radyosuyla (varsa) hiçbir ilgisi olmayabilir. Bunlar, derleme sisteminin OTA oluşturma araçları tarafından kullanılan target-files .zip dosyasına kopyaladığı opak veri kümeleridir. Derleme yaptığınızda tardis.dat, RADIO/tardis.dat
olarak target-files.zip içinde depolanır. İstediğiniz kadar dosya eklemek için add-radio-file
işlevini birden fazla kez çağırabilirsiniz.
Python modülü
Yayın araçlarını genişletmek için araçların mevcutsa çağırabileceği bir Python modülü (releasetools.py olarak adlandırılmalıdır) yazın. Örnek:
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"));""")
Artımlı OTA paketi oluşturma durumu ayrı bir işlevle ele alınır. Bu örnekte, tardis.dat dosyası iki derleme arasında değiştiğinde tardisi yeniden programlamanız gerektiğini varsayalım.
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"));""")
Modül işlevleri
Modülde aşağıdaki işlevleri sağlayabilirsiniz (yalnızca ihtiyacınız olanları uygulayın).
FullOTA_Assertions()
- Tam OTA oluşturma işleminin başlangıcına yakın bir zamanda çağrılır. Bu, cihazın mevcut durumuyla ilgili onaylamalar yayınlamak için iyi bir yerdir. Cihazda değişiklik yapan komut dosyası komutları yayınlamayın.
FullOTA_InstallBegin()
- Cihaz durumuyla ilgili tüm onaylar geçildikten sonra ancak herhangi bir değişiklik yapılmadan önce çağrılır. Cihazda başka bir değişiklik yapılmadan önce çalıştırılması gereken cihaza özel güncellemeler için komutlar verebilirsiniz.
FullOTA_InstallEnd()
- Önyükleme ve sistem bölümlerini güncellemek için komut dosyası komutları yayınlandıktan sonra komut dosyası oluşturma işleminin sonunda çağrılır. Cihaza özel güncellemeler için ek komutlar da verebilirsiniz.
IncrementalOTA_Assertions()
-
FullOTA_Assertions()
özelliğine benzer ancak artımlı güncelleme paketi oluşturulurken çağrılır. IncrementalOTA_VerifyBegin()
- Cihaz durumuyla ilgili tüm onaylar geçildikten sonra ancak herhangi bir değişiklik yapılmadan önce çağrılır. Cihazda başka bir şey değiştirilmeden önce çalıştırılması gereken cihaza özel güncellemeler için komutlar verebilirsiniz.
IncrementalOTA_VerifyEnd()
- Doğrulama aşamasının sonunda, komut dosyası dokunacağı dosyaların beklenen başlangıç içeriklerine sahip olduğunu onaylamayı bitirdiğinde çağrılır. Bu noktada cihazda hiçbir şey değiştirilmemiştir. Ayrıca, cihaza özel ek doğrulamalar için de kod yayınlayabilirsiniz.
IncrementalOTA_InstallBegin()
- Yama uygulanacak dosyaların beklenen before durumunda olduğu doğrulandıktan sonra ancak herhangi bir değişiklik yapılmadan önce çağrılır. Cihazda başka bir değişiklik yapılmadan önce çalıştırılması gereken cihaza özel güncellemeler için komutlar verebilirsiniz.
IncrementalOTA_InstallEnd()
- Tam OTA paketi karşılığına benzer şekilde, bu komut dosyası oluşturma işleminin sonunda, önyükleme ve sistem bölümlerini güncellemek için komut dosyası komutları yayınlandıktan sonra çağrılır. Cihaza özel güncellemeler için ek komutlar da verebilirsiniz.
Not: Cihazın gücü kesilirse OTA yüklemesi baştan başlayabilir. Bu komutların tamamen veya kısmen çalıştırıldığı cihazlarla başa çıkmaya hazır olun.
Bilgi nesnelerine işlevler iletme
Çeşitli yararlı öğeler içeren tek bir bilgi nesnesine işlevler iletin:
-
info.input_zip. (Yalnızca tam OTA'lar) Giriş hedef dosyaları .zip'i için
zipfile.ZipFile
nesnesi. -
info.source_zip. (Yalnızca artımlı OTA'lar) Kaynak hedef dosyaları .zip için
zipfile.ZipFile
nesnesi (artımlı paket yüklenirken cihazda bulunan derleme). -
info.target_zip. (Yalnızca artımlı OTA'lar) Hedef target-files .zip için
zipfile.ZipFile
nesnesi (artımlı paketin cihaza yerleştirildiği derleme). -
info.output_zip. Paket oluşturuluyor; yazmak için
zipfile.ZipFile
nesnesi açıldı. Pakete dosya eklemek için common.ZipWriteStr(info.output_zip, filename, data) işlevini kullanın. -
info.script. Komut ekleyebileceğiniz komut dosyası nesnesi. Metni komut dosyasına aktarmak için Call
info.script.AppendExtra(script_text)
işlevini kullanın. Çıkış metninin noktalı virgülle bittiğinden emin olun. Böylece, daha sonra verilen komutlarla çakışmaz.
Bilgi nesnesiyle ilgili ayrıntılar için ZIP arşivleriyle ilgili Python Software Foundation belgelerine bakın.
Modül konumunu belirtme
BoardConfig.mk dosyanızda cihazınızın releasetools.py komut dosyasının konumunu belirtin:
device/yoyodyne/tardis/BoardConfig.mk
[...] TARGET_RELEASETOOLS_EXTENSIONS := device/yoyodyne/tardis
TARGET_RELEASETOOLS_EXTENSIONS ayarlanmamışsa varsayılan olarak $(TARGET_DEVICE_DIR)/../common
dizini (bu örnekte device/yoyodyne/common
) kullanılır. releasetools.py komut dosyasının konumunu açıkça tanımlamanız önerilir.
Tardis cihazı oluşturulurken releasetools.py komut dosyası, target-files.zip dosyasına (META/releasetools.py
) dahil edilir.
Yayın araçlarını (img_from_target_files
veya ota_from_target_files
) çalıştırdığınızda, hedef dosyalar.zip dosyasındaki releasetools .py komut dosyası (varsa) Android kaynak ağacındaki komut dosyasına tercih edilir. Ayrıca, önceliği en yüksek olan -s
(veya --device_specific
) seçeneğiyle cihaza özel uzantıların yolunu açıkça belirtebilirsiniz. Bu sayede, Release Tools uzantılarında hataları düzeltebilir ve değişiklikler yapabilir, bu değişiklikleri eski hedef dosyalara uygulayabilirsiniz.
Artık ota_from_target_files
komutunu çalıştırdığınızda, hedef_dosyalar .zip dosyasındaki cihaza özgü modül otomatik olarak alınır ve OTA paketleri oluşturulurken kullanılır:
./build/make/tools/releasetools/ota_from_target_files \
-i PREVIOUS-tardis-target_files.zip \
dist_output/tardis-target_files.zip \
incremental_ota_update.zip
Alternatif olarak, ota_from_target_files
komutunu çalıştırdığınızda cihaza özel uzantılar belirtebilirsiniz.
./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
Not: Seçeneklerin tam listesi için ota_from_target_files
yorumlarına bakın.
build/make/tools/releasetools/ota_from_target_files
Başka cihazdan yükleme mekanizması
Kurtarma, ana sistem tarafından kablosuz olarak indirilmeden bir güncelleme paketinin manuel olarak yüklenmesi için yan yükleme mekanizmasına sahiptir. Başka cihazdan yükleme, ana sistemin başlatılamadığı cihazlarda hata ayıklama veya değişiklik yapma konusunda faydalıdır.
Geçmişte, yan yükleme işlemi cihazın SD kartından paket yüklenerek yapılıyordu. Açılmayan bir cihaz söz konusu olduğunda, paket başka bir bilgisayar kullanılarak SD karta yüklenebilir ve ardından SD kart cihaza takılabilir. Çıkarılabilir harici depolama alanı olmayan Android cihazları desteklemek için kurtarma, başka cihazdan yükleme konusunda iki ek mekanizmayı destekler: paketleri önbellek bölümünden yükleme ve adb kullanarak USB üzerinden yükleme.
Her bir yan yükleme mekanizmasını çağırmak için cihazınızın Device::InvokeMenuItem()
yöntemi, aşağıdaki BuiltinAction değerlerini döndürebilir:
-
APPLY_EXT. Harici depolama alanından (
/sdcard
dizini) güncelleme paketi yükleyin. recovery.fstab dosyanızda/sdcard
bağlama noktası tanımlanmalıdır. Bu özellik,/data
sembolik bağlantısıyla (veya benzer bir mekanizmayla) SD kartı taklit eden cihazlarda kullanılamaz./data
, şifrelenmiş olabileceği için genellikle kurtarılamaz. Kurtarma kullanıcı arayüzünde,/sdcard
içindeki .zip dosyalarının menüsü gösterilir ve kullanıcının bir dosya seçmesine izin verilir. -
APPLY_CACHE.
/sdcard
konumundan paket yüklemeye benzer. Ancak bunun yerine/cache
dizini (kurtarma için her zaman kullanılabilir) kullanılır. Normal sistemde/cache
yalnızca ayrıcalıklı kullanıcılar tarafından yazılabilir. Cihaz başlatılamıyorsa/cache
dizinine hiç yazılamaz (bu da bu mekanizmayı sınırlı bir şekilde kullanışlı hale getirir). -
APPLY_ADB_SIDELOAD. Kullanıcının, USB kablosu ve adb geliştirme aracıyla cihaza paket göndermesine olanak tanır. Bu mekanizma çağrıldığında kurtarma, bağlı bir ana makine bilgisayarındaki adb'nin kendisiyle iletişim kurmasına izin vermek için adbd daemon'unun kendi mini sürümünü başlatır. Bu mini sürüm yalnızca tek bir komutu destekler:
adb sideload filename
. Adlandırılmış dosya, ana makine tarafından cihaza gönderilir. Cihaz, dosyayı yerel depolama alanında bulunuyormuş gibi doğrulayıp yükler.
Dikkat edilmesi gereken birkaç nokta:
- Yalnızca USB aktarımı desteklenir.
-
Kurtarma işleminiz adbd'yi normal şekilde çalıştırıyorsa (genellikle userdebug ve eng derlemeleri için geçerlidir) bu işlem, cihaz adb sideload modundayken kapatılır ve adb sideload bir paketi almayı bitirdiğinde yeniden başlatılır. adb sideload modundayken
sideload
dışındaki adb komutları çalışmaz (logcat
,reboot
,push
,pull
,shell
vb. komutların tümü başarısız olur). -
Cihazda adb sideload modundan çıkamazsınız. İptal etmek için paket olarak
/dev/null
(veya geçerli bir paket olmayan başka bir şey) gönderebilirsiniz. Ardından cihaz, paketi doğrulayamaz ve yükleme prosedürünü durdurur. Tuş basma işlemleri için RecoveryUI uygulamasınınCheckKey()
yöntemi çağrılmaya devam eder. Böylece cihazı yeniden başlatan ve adb sideload modunda çalışan bir tuş sırası sağlayabilirsiniz.