Cihaza özel kod

Kurtarma sistemi, OTA güncellemelerinin Android sistem dışındaki cihaz bölümlerini de (ör. baz band veya radyo işlemcisi) güncelleyebilmesi için cihaza özgü kod eklemek üzere ç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ölme haritası

Platform, Android 2.3'ten itibaren eMMc flash cihazları ve bu cihazlarda çalışan ext4 dosya sistemini destekler. Ayrıca, Memory Technology Device (MTD) flash cihazları ve eski sürümlerdeki yaffs2 dosya sistemini de destekler.

Bölüm haritası dosyası TARGET_RECOVERY_FSTAB tarafından belirtilir; bu dosya hem kurtarma ikili dosyası hem de paket oluşturma araçları tarafından kullanılır. Eşleme dosyasının adını BoardConfig.mk'deki TARGET_RECOVERY_FSTAB içinde belirtebilirsiniz.

Örnek bir bölüm haritası dosyası aşağıdaki gibi 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 hariç, 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
Bir MTD flash cihazın üzerindeki 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 MTD bölümü. MTD aslında monte edilmez ancak bölüm bulmak için anahtar olarak montaj noktası kullanılır. "device", /proc/mtd içindeki MTD bölümünün adıdır.
ext4
eMMc flash cihazın üstünde bir ext4 dosya sistemi. "device", engellenen cihazın yolu olmalıdır.
emmc
Açılış ve kurtarma gibi önyüklenebilir bölümler için kullanılan ham eMMC blok cihazı. mtd türüne benzer şekilde, eMMC hiçbir zaman gerçekten monte edilmez ancak cihazı tabloda bulmak için monte noktası dizesi kullanılır.
vfat
Genellikle SD kart gibi harici depolama alanı için bir blok cihazın üstünde FAT dosya sistemi. device, blok cihazdır; device2, birincil cihazın takılması başarısız olursa sistemin takmaya çalıştığı ikinci bir blok cihazdır (bölüm tablosuyla biçimlendirilmiş veya biçimlendirilmemiş SD kartlarla uyumluluk için).

Tüm bölümler root dizininde monte edilmelidir (yani, monte noktası değeri eğik çizgi ile başlamalı ve başka eğik çizgi içermemelidir). Bu kısıtlama yalnızca dosya sistemlerinin kurtarma modunda monte edilmesi için geçerlidir. Ana sistem, dosya sistemlerini istediği yere monte edebilir. /boot, /recovery ve /misc dizinleri ham türde (mtd veya emmc) olmalıdır. /system, /data, /cache ve /sdcard (varsa) dizinleri ise dosya sistemi türünde (yaffs2, ext4 veya vfat) olmalıdır.

Android 3.0'dan itibaren recovery.fstab dosyasında options adlı isteğe bağlı bir alan eklenir. Şu anda yalnızca length (uzunluk) seçeneği tanımlanmıştır. Bu seçenek, bölümün uzunluğunu açıkça belirtmenize olanak tanır. Bu uzunluk, bölüm yeniden biçimlendirilirken kullanılır (ör. veri silme/fabrika ayarlarına sıfırlama işlemi sırasında kullanıcı verileri bölümü için veya tam OTA paketi yükleme sırasında sistem bölümü için). Uzunluk değeri negatifse biçimlendirilecek boyut, uzunluk değeri gerçek bölüm boyutuna eklenerek alınır. Örneğin, "length=-16384" ayarı, söz konusu bölüm yeniden biçimlendirildiğinde bu bölümün son 16 KB'sının üstüne yazılmayacağı anlamına gelir. Bu, kullanıcı verileri bölümünün şifrelenmesiyle (şifreleme meta verilerinin, üzerine yazılmaması gereken bölümün sonunda depolandığı yer) ilgili özellikleri destekler.

Not: device2 ve options alanları isteğe bağlıdır ve ayrıştırma işleminde 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, Android cihaz açılırken gösterilen animasyonu özelleştirebilir. Bunun için bootanimation biçimindeki spesifikasyonlara göre düzenlenmiş ve yerleştirilmiş bir .zip dosyası oluşturun.

Android Things cihazlarda, resimlerin seçili ürüne dahil edilmesi için sıkıştırılmış dosyayı Android Things konsoluna yükleyebilirsiniz.

Not: Bu resimler Android marka kurallarına 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örüntüleyecek ve her cihazın manuel olarak çalıştırılan gizli özelliklerine erişecek şekilde özelleştirebilirsiniz.

Amacınız, cihaza özgü işlevi sağlamak için birkaç C++ nesnesi içeren küçük bir statik kitaplık oluşturmaktır. Varsayılan olarak bootable/recovery/default_device.cpp dosyası kullanılır ve bu dosyanın cihazınız için bir sürümünü yazarken kopyalamak üzere iyi bir başlangıç noktası oluşturur.

Not: Burada Komut Yok mesajını görebilirsiniz. Metni açma/kapatma için ses artırma düğmesine basıp 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 üstbilgileri ve öğeleri döndürmek için işlevler gerektirir. Üstbilgiler, menünün nasıl kullanılacağını (ör. vurgulanan öğeyi değiştirmek/seçmek için kullanılan kontroller) 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 kısaltılır (sarmalanmaz), bu nedenle cihaz ekranınızın genişliğini göz önünde bulundurun.

CheckKey'i özelleştirme

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 miras alabilirsiniz (Ekranı olmayan cihazlar ile ilgili talimatları inceleyin.) ScreenRecoveryUI'den özelleştirilecek tek işlev, ilk eşzamansız anahtar işlemeyi 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 çağrılır: menü kapalıyken, açıkken, paket yükleme sırasında, kullanıcı verisi silme sırasında vb. Dört sabit değerden birini döndürebilir:

  • DEĞİŞTİRME. Menünün ve/veya metin günlüğünün görüntülenmesini açma veya kapatma
  • YENIDEN BAŞLAT'ı tıklayın. Cihazı hemen yeniden başlatın
  • IGNORE (İÇERİĞİ İHMAL ET). Bu tuş basma işlemini yoksay
  • ENQUEUE. Bu tuş basışını, senkronize olarak kullanılacak şekilde (ör. ekran etkinse kurtarma menüsü sistemi tarafından) sıraya ekleyin

CheckKey(), bir tuş aşağı etkinliğinin ardından aynı tuş için bir tuş yukarı etkinliği her gerçekleştiğinde çağrılır. (A-aşağı B-aşağı B-yukarı A-yukarı etkinlik sırası yalnızca CheckKey(B) işlevinin çağrılmasına neden olur.) CheckKey() , diğer tuşların basılı olup olmadığını öğrenmek için IsKeyPressed() işlevini çağırabilir. (Yukarıdaki önemli etkinlik dizisinde, CheckKey(B) IsKeyPressed(A)'u çağırırsa doğru değerini döndürür.)

CheckKey() sınıfında durumu koruyabilir. Bu, anahtar dizilerini algılamak için yararlı olabilir. Bu örnekte biraz daha karmaşık bir kurulum gösterilmektedir: Güç düğmesi basılı tutulup ses düğmesine basılarak ekran açılıp kapatılır. Güç düğmesine art arda beş kez basılarak (aralarında başka düğme basılmaz) cihaz 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 animation_fps değişkenini ayarlayarak animasyonların saniyedeki kare sayısı (FPS) hızını kontrol edebilirsiniz.

Not: Mevcut interlace-frames.py komut dosyası, animation_fps bilgilerini resmin içinde saklamanıza olanak tanır. Android'in önceki sürümlerinde animation_fps'yi 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 resimlerine karşılık gelir. Bu resimleri 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ı oluşturduktan sonra cihaz sınıfınızı tanımlayın (yerleşik Device sınıfından alt sınıf olarak). Bu işlev, kullanıcı arayüzü sınıfınızın tek bir örneğini oluşturup 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 bunu 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ının ve öğelerin listesini almak için iki yöntem çağırır. Bu uygulamada, dosyanın üst kısmında tanımlanan statik dizileri döndürür:

const char* const* GetMenuHeaders() { return HEADERS; }
const char* const* GetMenuItems() { return ITEMS; }

HandleMenuKey

Ardından, bir HandleMenuKey() işlevi sağlayın. Bu işlev, bir tuş basımını ve mevcut menü görünürlüğünü alır ve hangi işlemin yapılacağına karar verir:

   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;
    }

Yöntem, bir anahtar kodu (daha önce kullanıcı arayüzü nesnesinin CheckKey() yöntemi tarafından işlenmiş ve sıraya alınmış) ve 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 alınır (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 şey yapmayın

visible bağımsız değişkeninin belirttiği gibi, menü görünmese bile HandleMenuKey() çağrılır. CheckKey()'ün aksine, kurtarma işlemi veri silme veya paket yükleme gibi bir işlem yaparken çağrılmaz. Yalnızca kurtarma işlemi boştayken ve giriş beklerken çağrılır.

İztopu mekanizmaları

Cihazınızda trackball benzeri bir giriş mekanizması varsa (EV_REL türü ve REL_Y koduyla giriş etkinlikleri oluşturur) trackball benzeri giriş cihazı Y ekseninde hareket bildirdiğinde kurtarma, KEY_UP ve KEY_DOWN tuş basmalarını sentezleyebilir. Tek yapmanız gereken KEY_UP ve KEY_DOWN etkinliklerini menü işlemleriyle eşleştirmektir. Bu eşleme CheckKey() için yapılmaz. Bu nedenle, ekranı yeniden başlatmak veya kapatmak için dokunmatik yüzey hareketlerini tetikleyici 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 olup olmadığına bakılmaksızın veri silme işlemi başlatılır. Bunu aşağıdaki gibi uygulayabilirsiniz:

   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 yanlışsa kullanıcı vurguyu göremediğinden menüyü değiştiren özel değerlerin (vurgulanan öğeyi taşıma, vurgulanan öğeyi çağırma) döndürülmesinin bir anlamı yoktur. Ancak dilerseniz değerleri döndürebilirsiniz.

InvokeMenuItem

Ardından, GetMenuItems() tarafından döndürülen öğe dizisindeki tam sayı konumlarını işlemlerle eşleyen bir InvokeMenuItem() yöntemi sağlayın. tardis örneğindeki öğe dizisi için:

   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 ilgili işlemi yapmasını söylemek için BuiltinAction enum'unun herhangi bir üyesini döndürebilir (veya sistemin hiçbir şey yapmamasını istiyorsanız NO_ACTION üyesini döndürebilir). Sistemde bulunanın ötesinde ek kurtarma işlevleri sağlamak için bu işlevi kullanın: Menünüze bu işlev için bir öğe ekleyin, söz konusu menü öğesi çağrıldığında burada çalıştırın ve sistemin başka bir şey 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.
  • YENIDEN BAŞLAT'ı tıklayın. 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 Bilinmeyen kaynaklardan yükleme bölümüne göz atın.
  • WIPE_CACHE. Yalnızca önbellek bölümünü yeniden biçimlendirin. Bu işlem nispeten zararsız olduğundan onay gerekmez.
  • WIPE_DATA. userdata ve önbellek bölümlerini yeniden biçimlendirin (fabrika verilerine sıfırlama olarak da bilinir). Devam etmeden önce kullanıcıdan bu işlemi onaylaması istenir.

Son yöntem olan WipeData() isteğe bağlıdır ve veri silme işlemi başlatıldığında (menü üzerinden kurtarma işlemi veya kullanıcı ana sistemden fabrika verilerini sıfırlamayı seçtiğinde) çağrılır. Bu yöntem, kullanıcı verileri ve önbellek bölümleri silinmeden önce çağrılır. Cihazınızda kullanıcı verileri bu iki bölümden başka bir yerde depolanıyorsa burada silmeniz gerekir. Başarıyı belirtmek için 0, hatayı 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ılı veya başarısız bir sonuç döndürdüğünüzde kullanıcı verileri ve önbellek bölümleri silinir.

   int WipeData() {
       // ... do something tardis-specific here, if needed ....
       return 0;
    }

Cihaz markası

Son olarak, recovery_ui.cpp dosyasının sonuna Device sınıfınızın bir örneğini oluşturup döndüren make_device() işlevi için bazı standart metinler ekleyin:

class TardisDevice : public Device {
   // ... all the above methods ...
};

Device* make_device() {
    return new TardisDevice();
}

recovery_ui.cpp dosyasını tamamladıktan sonra derleyin ve cihazınızdaki kurtarma bölümüne bağlayın. Android.mk'de, 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 statik kitaplığınızı TARGET_RECOVERY_UI_LIB değerine göre 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 işleminin kullanıcı arayüzü resimlerden oluşur. İdeal olarak kullanıcılar kullanıcı arayüzüyle hiçbir zaman etkileşime girmemelidir: Normal bir güncelleme sırasında telefon kurtarma moduna geçer, yükleme ilerleme çubuğunu doldurur ve kullanıcıdan giriş almadan yeni sisteme yeniden açılır. Sistem güncelleme sorunu oluştuğunda kullanıcının yapabileceği tek işlem müşteri hizmetlerini aramaktır.

Yalnızca resim içeren bir arayüz, yerelleştirme ihtiyacını ortadan kaldırır. Ancak Android 5.0'den itibaren güncelleme, resimle birlikte bir metin dizisi de (ör. "Sistem güncellemesi yükleniyor...") gösterebilir. Ayrıntılı bilgi 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ümlerin kurtarma kullanıcı arayüzünde iki ana resim kullanılır: Hata resmi ve yükleme animasyonu.

ota hatası sırasında gösterilen resim

Şekil 1. icon_error.png

OTA yükleme sırasında gösterilen resim

Şekil 2. icon_installing.png

Yükleme animasyonu, animasyondaki farklı karelerin satıra göre çakıştırıldığı tek bir PNG resmi olarak temsil edilir (Şekil 2'nin sıkıştırılmış görünmesinin nedeni budur). Örneğin, 200x200 boyutunda yedi karelik bir animasyon için ilk karenin 0, 7, 14, 21, ...; ikinci karenin 1, 8, 15, 22, ... vb. satırların yer aldığı tek bir 200x1400 resim oluşturun. Birleştirilmiş resimde, animasyon karelerinin sayısını ve saniye başına kare sayısını (FPS) belirten bir metin parçası bulunur. bootable/recovery/interlace-frames.py aracı, bir giriş karesi grubunu alır ve bunları kurtarma işlemi tarafından kullanılan gerekli birleşik görüntüde birleştirir.

Varsayılan resimler farklı yoğunluklarda mevcuttur ve bootable/recovery/res-$DENSITY/images (ör. bootable/recovery/res-hdpi/images). Yükleme sırasında statik resim kullanmak için tek yapmanız gereken icon_installing.png resmini sağlamak ve animasyondaki kare sayısını 0 olarak ayarlamaktır (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ümlerin kurtarma kullanıcı arayüzünde hata resmi (yukarıda gösterilmiştir) ve yükleme animasyonunun yanı sıra birkaç yer paylaşımı resmi kullanılır:

OTA yükleme sırasında gösterilen resim

Şekil 3. icon_installing.png

İlk yer paylaşımı olarak gösterilen resim

Şekil 4. icon-installing_overlay01.png

Yedinci yer paylaşımı olarak gösterilen resim

Şekil 5. icon_installing_overlay07.png

Yükleme sırasında ekrandaki görüntü, icon_installing.png resminin çizilmesiyle ve ardından bunun üzerine yer paylaşımı çerçevelerinden birinin uygun ofsette çizilmesiyle oluşturulur. Burada, temel görüntünün üzerine yerleştirilen yer paylaşımının yerini vurgulamak için kırmızı bir kutu yerleştirilmiştir:

install plus first overlay&#39;ın birleşik resmi

Şekil 6. 1. animasyon karesi yükleniyor (icon_installing.png + icon_installing_overlay01.png)

yükleme ve yedinci yer paylaşımının birleşik resmi

Şekil 7. 7. animasyon karesi yükleniyor (icon_installing.png + icon_installing_overlay07.png)

Sonraki kareler, mevcut görüntünün üzerine yalnızca bir sonraki yer paylaşımı resmi çizilerek görüntülenir. Temel resim yeniden çizilmez.

Animasyondaki kare sayısı, istenen hız ve yer paylaşımının temele göre x ve y ofsetleri, ScreenRecoveryUI sınıfının üye değişkenleri tarafından belirlenir. Varsayılan resimler yerine özel resimler kullandığınızda, bu değerleri özel resimleriniz için değiştirmek üzere alt sınıfınızdaki Init() yöntemini geçersiz kılın (ayrıntılar için ScreenRecoveryUI bölümüne bakın). Komut dosyası bootable/recovery/make-overlay.py , gerekli ofsetlerin hesaplanması da dahil olmak üzere bir dizi resim çerçevesini, kurtarma için gereken "temel resim + yer paylaşımı resimleri" biçimine dönüştürmenize yardımcı olabilir.

Varsayılan resimler bootable/recovery/res/images konumundadır. Yükleme sırasında statik bir resim kullanmak için tek yapmanız gereken icon_installing.png resmini sağlamak ve animasyondaki kare sayısını 0 olarak ayarlamaktır (hata simgesi animasyonlu değildir, her zaman statik bir resimdir).

Yerelleştirilmiş kurtarma metni

Android 5.x, bir metin dizesi (ör. "Sistem güncellemesi yükleniyor...") ve görüntüyü Ana sistem kurtarma modunda açıldığında, kullanıcının mevcut yerel ayarını kurtarma moduna komut satırı seçeneği olarak iletir. Gösterilecek her mesaj için kurtarma işlemi, her yerel ayarda söz konusu mesaj için önceden oluşturulmuş metin dizelerini içeren ikinci bir birleşik resim içerir.

Kurtarma metin dizelerinin örnek resmi:

kurtarma metninin resmi

Şekil 8. Kurtarma mesajları için yerelleştirilmiş metin

Kurtarma metninde aşağıdaki mesajlar gösterilebilir:

  • Sistem güncellemesi yükleniyor...
  • Hata!
  • Siliniyor... (veri silme/fabrika ayarlarına sıfırlama işlemi yaparken)
  • Komut yok (kullanıcı kurtarma moduna manuel olarak başlattığında)

bootable/recovery/tools/recovery_l10n/'teki Android uygulaması, bir mesajın yerelleştirmelerini oluşturur ve birleşik resmi oluşturur. Bu uygulamanın kullanımıyla ilgili ayrıntılar için bootable/recovery/tools/recovery_l10n/src/com/android/recovery_l10n/Main.java'teki yorumlara bakın.

Kullanıcı kurtarma moduna manuel olarak başlattığında yerel ayar kullanılamayabilir ve metin gösterilmeyebilir. Kısa mesajları kurtarma işlemi 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ş resminin birleştirilmesiyle oluşturulur:

boş ilerleme çubuğu

Şekil 9. progress_empty.png

tam ilerleme çubuğu

Ş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, ilerlemeyi belirtecek şekilde değiştirilir. Örneğin, yukarıdaki giriş resmi çiftleriyle şunu görüntüleyin:

%1&#39;de ilerleme çubuğu

Şekil 11. İlerleme çubuğu %1>

%10&#39;da ilerleme çubuğu

Şekil 12. %10'da ilerleme çubuğu

%50&#39;de ilerleme çubuğu

Şekil 13. %50'de ilerleme çubuğu

Bu resimlerin cihaza özel sürümlerini, bu resimleri (bu örnekte) device/yoyodyne/tardis/recovery/res/images içine yerleştirerek sağlayabilirsiniz. Dosya adları yukarıda listelenenlerle eşleşmelidir. Bu dizinde bir dosya bulunduğunda derleme sistemi, ilgili varsayılan görüntüye tercih ederek 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 doğru (RTL) bir dilse (Arapça, İbranice vb.) ilerleme çubuğu sağdan sola doğru doldurulur.

Ekranı olmayan cihazlar

Bazı Android cihazlarda ekran yoktur. Cihazınız başsız bir cihazsa veya yalnızca sesli bir arayüze sahipse kurtarma kullanıcı arayüzünü daha kapsamlı bir şekilde özelleştirmeniz gerekebilir. ScreenRecoveryUI sınıfının alt sınıfını oluşturmak yerine doğrudan üst sınıfı RecoveryUI'nin alt sınıfını oluşturun.

RecoveryUI,"ekranı açma/kapatma", "ilerleme çubuğunu güncelleme", "menüyü gösterme", "menü seçimini değiştirme" gibi daha düşük düzeyli kullanıcı arayüzü işlemlerini gerçekleştirme yöntemlerine sahiptir. Cihazınız için uygun bir arayüz sağlamak amacıyla bu yöntemleri geçersiz kılabilirsiniz. Cihazınızda, durumu belirtmek için farklı renkleri veya yanıp sönme kalıplarını kullanabileceğiniz LED'ler olabilir ya da ses çalabilirsiniz. (Menüyü veya "metin görüntüleme" modunu hiç desteklemek istemiyorsanız ekranı hiç açmayan veya bir menü öğesi seçmeyen CheckKey() ve HandleMenuKey() uygulamalarını kullanarak bunlara erişimi engelleyebilirsiniz. Bu durumda, sağlamanız gereken RecoveryUI yöntemlerinin çoğu boş stub'lar olabilir.)

Hangi yöntemleri desteklemeniz gerektiğini görmek için RecoveryUI beyanı için 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 temel girişlerin işlenmesini yapacak kodu içerir. Cihazınızda anahtar yoksa veya anahtarları farklı şekilde işlemek istiyorsanız bu ayarı da geçersiz kılabilirsiniz.

Güncelleyici

Güncelleme paketinin yüklenmesinde, güncelleyici komut dosyanızdan çağrılabilecek kendi uzantı işlevlerinizi sağlayarak cihaza özgü kod kullanabilirsiniz. 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 bir Expr* işaretçi dizisidir. Döndürülen değer, yeni atanan bir Value* olur.

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ılırken bağımsız değişkenleriniz değerlendirilmez. Bunlardan hangisinin kaç kez değerlendirileceği işlevinizin mantığına bağlıdır. Bu nedenle, kendi kontrol yapılarınızı uygulamak için uzatma işlevlerini kullanabilirsiniz. Call Evaluate() işlevi, bir Expr* bağımsız değişkenini değerlendirerek Value* döndürür. Evaluate() NULL döndürürse beklettiğiniz tüm kaynakları serbest bırakmalı ve hemen NULL döndürmelisiniz (bu, edify yığınına iptalleri iletir). 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. Argümanları şu şekilde 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 olup olmadığını kontrol etmek ve daha önce değerlendirilmiş bağımsız değişkenleri serbest bırakmak, birden fazla bağımsız değişken için zahmetli olabilir. ReadValueArgs() işlevi bunu kolaylaştırabilir. Yukarıdaki kod yerine şunu yazabilirdiniz:

   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; bu işlemi tek bir if ifadesiyle yapmak daha uygundur ancak başarısız olduğunda biraz daha az spesifik bir hata mesajı oluşturulur. Ancak ReadValueArgs(), her bağımsız değişkenin değerlendirilmesini ve değerlendirmelerden herhangi biri başarısız olursa daha önce değerlendirilmiş tüm bağımsız değişkenlerin serbest bırakılmasını (ayrıca yararlı bir hata mesajı ayarlanmasını) sağlar. 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 işlevin 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öndürülen değer bir Value* nesnesi olmalıdır; bu nesnenin sahipliği, arayana aktarılır. Çağırıcı, bu Value* tarafından işaretlenen tüm verilerin (özellikle de veri üyesinin) sahipliğini alır.

Bu durumda, başarıyı belirtmek için true veya false değerini döndürmek istersiniz. Boş dizenin false, diğer tüm dizelerin ise true olduğunu unutmayın. Çağırıcı her ikisini de free() kullanacağından, döndürülecek sabit dizenin malloc'lanmış bir kopyasıyla bir Value nesnesi malloc etmeniz gerekir. Bağımsız değişkenlerinizi değerlendirerek elde ettiğiniz nesnelerde 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;
}

StringValue() kolaylık işlevi, bir dizeyi yeni bir Değer nesnesine sarar. Yukarıdaki kodu daha kısa yazmak için şunu kullanın:

   FreeValue(key);
    FreeValue(image);

    return StringValue(strdup(successful ? "t" : ""));
}

İşlevleri edify yorumlayıcısına bağlamak için işlevi Register_foo sağlayın. Bu kod, foo adlı statik kitaplıkta bulunur. Her bir uzantı işlevini kaydetmek için RegisterFunction() işlevini çağırın. Gelecekte eklenecek yerleşik işlevlerle çakışmayı önlemek için, cihaza özgü işlevleri device.whatever olarak adlandırın.

void Register_librecovery_updater_tardis() {
    RegisterFunction("tardis.reprogram", ReprogramTardisFn);
}

Artık makefile'i, 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 statik kitaplıklar bulunabilir.)

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çinde bulunan Register_libname işlevinin adıyla eşleşmelidir.

LOCAL_MODULE := librecovery_updater_tardis
include $(BUILD_STATIC_LIBRARY)

Son olarak, kitaplığınızı alacak şekilde kurtarma derlemesini yapılandırın. Kitaplığınızı TARGET_RECOVERY_UPDATER_LIBS'e ekleyin (birden fazla kitaplık içerebilir; tümü kaydedilir). Kodunuz, edify uzantısı olmayan diğer statik kitaplıklara (ör. işlevi yoksa) bu kitaplıkları TARGET_RECOVERY_UPDATER_EXTRA_LIBS içinde listeleyerek (mevcut olmayan) kayıt işlevlerini çağırmadan güncelleyiciye bağlayabilirsiniz.Register_libname Örneğin, cihaza özgü kodunuz verileri sıkıştırmak için zlib kullanmak istiyorsa buraya libz'yi eklersiniz.

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ğer işlevler 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 örnekte, yerleşik package_extract_file() işlevinin tek bağımsız değişkenli sürümü kullanılır. Bu işlev, yeni uzantı işlevinin ikinci bağımsız değişkenini oluşturmak için güncelleme paketinden ayıklanan bir dosyanın içeriğini bir blob olarak döndürür.

OTA paketi oluşturma

Son bileşen, OTA paket oluşturma araçlarının cihaza özgü verileriniz hakkında bilgi edinmesini ve uzantı işlevlerinize çağrılar içeren güncelleyici komut dosyaları yayınlamasını sağlamaktır.

İlk olarak, derleme sisteminin cihaza özgü bir veri kümesi hakkında bilgi sahibi olmasını sağlayın. Veri dosyanızı device/yoyodyne/tardis/tardis.dat içinde olduğunu varsayarak, cihazınızın AndroidBoard.mk dosyasında şunları beyan edin:

device/yoyodyne/tardis/AndroidBoard.mk
  [...]

$(call add-radio-file,tardis.dat)

Bunun yerine bir Android.mk dosyasına da ekleyebilirsiniz. Ancak bu durumda, hangi cihazın derlendiğine bakılmaksızın ağaçtaki tüm Android.mk dosyaları yükleneceğinden, bir cihaz kontrolü tarafından korunması gerekir. (Ağacınızda birden fazla cihaz varsa tardis.dat dosyasının yalnızca tardis cihazı oluşturulurken 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

Bu dosyalar, geçmiş nedenlerle radyo dosyaları olarak adlandırılır. Cihaz radyosuyla (varsa) hiçbir ilgisi olmayabilir. Bunlar, derleme sisteminin OTA oluşturma araçları tarafından kullanılan hedef dosya .zip'ine kopyaladığı opak veri topaklarıdır. Derleme yaptığınızda tardis.dat, target-files.zip dosyasında RADIO/tardis.dat olarak depolanır. İstediğiniz kadar dosya eklemek için add-radio-file işlevini birden fazla kez çağırabilirsiniz.

Python modülü

Sürüm araçlarını genişletmek için, varsa araçların ç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şlev tarafından ele alınır. Bu örnekte, tardis.dat dosyasının iki derleme arasında değiştiği durumlarda tardis'i 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şturmanın başlangıcına yakın bir zamanda çağrılır. Bu, cihazın mevcut durumuyla ilgili iddialar belirtmek için iyi bir yerdir. Cihaz üzerinde değişiklik yapan komut dosyası komutları göndermeyin.
FullOTA_InstallBegin()
Cihaz durumuyla ilgili tüm iddialar geçtikten sonra ancak herhangi bir değişiklik yapılmadan önce çağrılır. Cihazdaki başka bir şey değiştirilmeden önce çalıştırılması gereken cihaza özgü güncellemeler için komutlar gönderebilirsiniz.
FullOTA_InstallEnd()
Komut dosyası oluşturma işleminin sonunda, önyükleme ve sistem bölümlerinin güncellenmesine dair komut dosyası gönderildikten sonra çağrılır. Cihazlara özgü güncellemeler için ek komutlar da gönderebilirsiniz.
IncrementalOTA_Assertions()
FullOTA_Assertions()'e benzer ancak artımlı güncelleme paketi oluşturulurken çağrılır.
IncrementalOTA_VerifyBegin()
Cihaz durumuyla ilgili tüm iddialar geçtikten sonra ancak herhangi bir değişiklik yapılmadan önce çağrılır. Cihazdaki başka bir şey değiştirilmeden önce çalıştırılması gereken cihaza özgü güncellemeler için komutlar gönderebilirsiniz.
IncrementalOTA_VerifyEnd()
Doğrulama aşamasının sonunda, komut dosyası dokunacağı dosyaların beklenen başlangıç içeriğine sahip olduğunu doğrulamayı tamamladığında çağrılır. Bu aşamada cihazda hiçbir değişiklik yapılmamıştır. Ayrıca cihaza özgü ek doğrulamalar için kod da yayınlayabilirsiniz.
IncrementalOTA_InstallBegin()
Düzeltilecek dosyaların beklenen ön durumda olduğu doğrulandıktan sonra ancak herhangi bir değişiklik yapılmadan önce çağrılır. Cihazdaki başka bir şey değiştirilmeden önce çalıştırılması gereken cihaza özgü güncellemeler için komutlar gönderebilirsiniz.
IncrementalOTA_InstallEnd()
Tam OTA paketi muadili gibi, bu da komut dosyası oluşturmanın sonunda, önyükleme ve sistem bölümlerinin güncellenmesine yönelik komut dosyası komutları gönderildikten sonra çağrılır. Cihazlara özgü güncellemeler için ek komutlar da yayınlayabilirsiniz.

Not: Cihazın gücü kesilirse OTA yükleme işlemi baştan başlatılabilir. Bu komutların tam veya kısmen çalıştırıldığı cihazlarla başa çıkmaya hazır olun.

Bilgi nesnelerine işlev aktarma

Ç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 dosyasının zipfile.ZipFile nesnesi.
  • info.source_zip. (Yalnızca artımlı OTA'lar) Kaynak hedef dosya .zip dosyasının zipfile.ZipFile nesnesi (artımlı paket yüklenirken cihazda bulunan derleme).
  • info.target_zip. (Yalnızca artımlı OTA'lar) Hedef hedef-dosyalar .zip dosyasına (artımlı paketin cihaza yüklediği derleme) yönelik zipfile.ZipFile nesnesi.
  • info.output_zip. Paket oluşturuluyor; yazmak için bir zipfile.ZipFile nesnesi açıldı. Pakete dosya eklemek için common.ZipWriteStr(info.output_zip, dosya adı, veri) işlevini kullanın.
  • info.script. Komut ekleyebileceğiniz komut dosyası nesnesi. Komut dosyasına metin yazdırmak için info.script.AppendExtra(script_text) işlevini çağırın. Çıkış metninin, daha sonra yayınlanan komutlarla karşılaşmaması için noktalı virgülle bittiğinden emin olun.

Bilgi nesnesi hakkında ayrıntılı bilgi için ZIP arşivleri ile ilgili Python Software Foundation dokümanlarına bakın.

Modül konumunu belirtme

Cihazınızın releasetools.py komut dosyasının konumunu BoardConfig.mk dosyanızda belirtin:

device/yoyodyne/tardis/BoardConfig.mk
 [...]

TARGET_RELEASETOOLS_EXTENSIONS := device/yoyodyne/tardis

TARGET_RELEASETOOLS_EXTENSIONS ayarlanmazsa 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ımlamak en iyisidir. Tardis cihazı derlenirken releasetools.py komut dosyası, hedef-dosyalar .zip dosyasına (META/releasetools.py ) eklenir.

Sürüm araçlarını (img_from_target_files veya ota_from_target_files) çalıştırdığınızda, hedef dosyalar.zip dosyasında varsa Android kaynak ağacındaki releasetools .py komut dosyası tercih edilir. Ayrıca, -s (veya --device_specific) seçeneğiyle cihaza özgü uzantıların yolunu açıkça belirtebilirsiniz. Bu seçenek en yüksek önceliğe sahiptir. Bu sayede, hataları düzeltebilir, releasetools uzantılarında değişiklik yapabilir ve bu değişiklikleri eski hedef dosyalara uygulayabilirsiniz.

Artık ota_from_target_files'ü çalıştırdığınızda, target_files .zip dosyasından cihaza özgü modülü otomatik olarak alır ve OTA paketleri oluştururken kullanı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'yi çalıştırırken cihaza özgü 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 build/make/tools/releasetools/ota_from_target_files göz atın.

Başka cihazdan yükleme mekanizması

Kurtarma, ana sistem tarafından kablosuz olarak indirmeden güncelleme paketini manuel olarak yüklemek için bir yandan yükleme mekanizmasına sahiptir. Yandan yükleme, ana sistemin başlatılamadığı cihazlarda hata ayıklama veya değişiklik yapma için yararlıdır.

Yandan yükleme işlemi geçmişte paketlerin cihazın SD kartına yüklenmesi şeklinde yapılıyordu. Başlamayan 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 işlemi, başka cihazdan yükleme için iki ek mekanizmayı destekler: paketleri önbellek bölümünden yükleme ve adb'yi kullanarak USB üzerinden yükleme.

Cihazınızın Device::InvokeMenuItem() yöntemi, her bir yan yükleme mekanizmasını çağırmak için aşağıdaki BuiltinAction değerlerini döndürebilir:

  • APPLY_EXT. Harici depolama alanından ( /sdcard dizin) güncelleme paketini başka bir cihazdan yükleme recovery.fstab dosyanızda /sdcard bağlama noktası tanımlanmalıdır. Bu yöntem, /data (veya benzer bir mekanizma) için sembolik bağlantı içeren bir 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 bir menüsü gösterilir ve kullanıcının bir dosya seçmesine olanak tanınır.
  • APPLY_CACHE. /sdcard'ten paket yüklemeye benzer. Bununla birlikte, 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 önyükleme yapamıyorsa /cache dizinine hiç yazılamaz (bu da bu mekanizmanın sınırlı bir işleve sahip olmasını sağlar).
  • APPLY_ADB_SIDELOAD. Kullanıcının USB kablosu ve adb geliştirme aracı aracılığıyla cihaza paket göndermesine izin verir. Bu mekanizma çağrıldığında kurtarma, bağlı ana bilgisayardaki adb'nin kendisiyle iletişim kurmasına izin vermek için adbd daemon'ın 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 makineden cihaza gönderilir. Cihaz, dosyayı yerel depolama alanındaymış gibi doğrular ve yükler.

Dikkat edilmesi gereken birkaç nokta:

  • Yalnızca USB aktarımı desteklenir.
  • Kurtarma modunuz adbd'yi normal şekilde çalıştırıyorsa (genellikle userdebug ve eng derlemeleri için geçerlidir) bu mod, cihaz adb yan yükleme modundayken kapatılır ve adb yan yükleme bir paketi almayı tamamladığında yeniden başlatılır. adb yan yükleme modundayken sideload dışındaki hiçbir adb komutu çalışmaz ( logcat, reboot, push, pull, shell vb. komutlar çalışmaz).
  • Cihazdaki adb yan yükleme modundan çıkamazsınız. İşlemi iptal etmek için paket olarak /dev/null (veya geçerli bir paket olmayan başka bir şey) gönderebilirsiniz. Bu durumda cihaz, paketi doğrulayamaz ve yükleme işlemini durdurur. RecoveryUI uygulamasını kullanan CheckKey() yöntemi, tuş basışları için çağrılmaya devam eder. Böylece, cihazı yeniden başlatan ve adb yan yükleme modunda çalışan bir tuş sırası sağlayabilirsiniz.