يشتمل نظام الاسترداد على عدة خطافات لإدخال الرمز الخاص بالجهاز بحيث يمكن الوصول عبر الهواء ويمكن أن تؤدي التحديثات أيضًا إلى تحديث أجزاء من الجهاز غير نظام Android (مثل النطاق الأساسي). أو معالج لاسلكي).
تخصِّص الأقسام والأمثلة التالية جهاز tardis الذي تم إنتاجه من قِبل مورّد yoyodyne
خريطة التقسيم
بدءًا من الإصدار Android 2.3، سيتوافق النظام الأساسي مع أجهزة فلاش eMMc ونظام ملفات ext4 الذي يتم تشغيله. على تلك الأجهزة. وهو يتوافق أيضًا مع أجهزة الفلاش لجهاز تكنولوجيا الذاكرة (MTD) وyaffs2 من الإصدارات القديمة.
يتم تحديد ملف خريطة التقسيم بواسطة TARGET_RECOVERY_FSTAB؛ يتم استخدام هذا الملف من خلال البرنامج الثنائي للاسترداد وأدوات إنشاء الحزم. يمكنك تحديد اسم ملف الخريطة في TARGET_RECOVERY_FSTAB في BoardConfig.mk.
قد يظهر نموذج ملف خريطة التقسيم كما يلي:
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
باستثناء /sdcard
، الاختيارية، جميع نقاط التثبيت في
مثال (قد تضيف الأجهزة أيضًا أقسامًا إضافية). هناك خمسة تقارير متاحة
أنواع أنظمة الملفات:
- يافع
-
نظام ملفات yaffs2 أعلى جهاز فلاش MTD. "الجهاز" أن يكون باسم قسم MTD
ويجب أن تظهر في
/proc/mtd
. - هدف
-
جزء MTD الأولي، يُستخدم في الأقسام القابلة للتشغيل، مثل التشغيل والاسترداد. لا يشمل هذا الشهر
إذا كان قد تم تثبيته بالفعل، ولكن يتم استخدام نقطة التثبيت كمفتاح لتحديد موقع القسم. "الجهاز"
يجب أن يكون اسمًا لقسم MTD في
/proc/mtd
. - ext4
- يشير ذلك المصطلح إلى نظام ملفات ext4 أعلى جهاز فلاش eMMc. "الجهاز" يجب أن يكون مسار جهاز الحظر.
- الإرسال عبر البريد الإلكتروني
- جهاز أولي لكتلة eMMc، يُستخدم في الأقسام القابلة للتشغيل، مثل "التشغيل والاسترداد". مشابه لـ نوع mtd، لا يتم تثبيت eMMc أبدًا، ولكن تُستخدم سلسلة نقطة التثبيت لتحديد موقع الجهاز الموجود في الجدول.
- ملف vfat
-
نظام ملفات FAT أعلى جهاز كتلي، وعادةً ما يكون مخزنًا خارجيًا مثل بطاقة SD تشير رسالة الأشكال البيانية
الجهاز هو جهاز التخزين الكتلي؛ الجهاز 2 هو جهاز من النوع الثاني يحاول النظام تثبيته إذا
تعذُّر تثبيت الجهاز الأساسي (للتوافق مع بطاقات SD التي قد يتعذر أو لا يتم ذلك
بتنسيق جدول تقسيم).
يجب تثبيت كل الأقسام في الدليل الجذر (أي يجب أن تكون قيمة نقطة التثبيت تبدأ بشرطة مائلة ولا تحتوي على أي شرطة مائلة أخرى). لا ينطبق هذا القيد إلا على التثبيت. وأنظمة الملفات في عملية الاسترداد؛ فإن النظام الرئيسي مجاني لتثبيتها في أي مكان. الأدلة يجب أن تكون
/boot
و/recovery
و/misc
أنواعًا أولية. (mtd أو emmc)، بينما تضم الأدلة/system
و/data
/cache
و/sdcard
(إذا كان ذلك متاحًا) يجب أن يكونا نوعي نظام ملفات (yaffs2 أو ext4 أو vfat).
بدءًا من الإصدار Android 3.0، سيحصل ملفrecovery.fstab على حقل اختياري إضافي، الخيارات. الخيار الوحيد المحدد حاليًا هو length ، الذي يتيح لك لتحديد طول القسم. تُستخدَم هذه المدة عند إعادة تنسيق القسم. (على سبيل المثال، لقسم userdata أثناء عملية حجب البيانات/إعادة الضبط على الإعدادات الأصلية، أو جزء النظام أثناء تثبيت حزمة OTA كاملة). إذا كانت قيمة الطول سالبة، ثم يتم تحديد الحجم المطلوب تنسيقه بإضافة قيمة الطول إلى حجم القسم الحقيقي. بالنسبة مثال، تعيين "length=-16384" يعني أن آخر 16 ألف ثانية من هذا القسم لن تكون يتم استبداله عند إعادة تنسيق هذا القسم. ويدعم ذلك ميزات مثل تشفير قسم userdata (حيث يتم تخزين بيانات التشفير في نهاية القسم ).
ملاحظة: إنّ حقلَي device2 وoptions اختياريَين، ما يؤدي إلى إنشاء والغموض في التحليل. إذا كان الإدخال في الحقل الرابع على السطر يبدأ بـ "/" فسيتم اعتباره إدخال device2 ؛ إذا لم يبدأ الإدخال بـ "/" الحرف، فإنه يعتبر حقل خيارات.
الرسوم المتحركة عند بدء التشغيل
يمكن للشركات المصنّعة للأجهزة تخصيص الصور المتحركة التي تظهر عندما يستخدم جهاز Android قيد التشغيل. للقيام بذلك، قم بإنشاء ملف .zip منظمًا وموقعًا وفقًا المواصفات في تنسيق التمهيد:
بالنسبة أجهزة Android Things، يمكنك تحميل الملف المضغوط في وحدة تحكم Android Things لتضمين الصور في المنتج المحدد.
ملاحظة: يجب أن تستوفي هذه الصور إرشادات وضع العلامة التجارية على Android. بالنسبة إلى إرشادات العلامة التجارية، يُرجى الرجوع إلى قسم Android شركاء التسويق المحتوى الرئيسي.
واجهة المستخدم المخصصة لاسترداد الحساب
للتوافق مع الأجهزة التي تتوفّر بها معدّات مختلفة (الأزرار المادية ومصابيح LED والشاشات وما إلى ذلك)، يمكنك تخصيص واجهة الاسترداد لعرض الحالة والوصول إلى واجهة برمجة التطبيقات التي يتم تشغيلها يدويًا الميزات المخفية لكل جهاز.
ويتمثل هدفك في إنشاء مكتبة ثابتة صغيرة تحتوي على كائنات C++ لتوفير
بوظيفة خاصة بالجهاز. الملف
يتم استخدام bootable/recovery/default_device.cpp
بشكل تلقائي، ويحقق أداءً جيدًا
نقطة البداية لنسخها عند كتابة نسخة من هذا الملف لجهازك.
ملاحظة: قد تظهر لك رسالة مفادها عدم الطلب هنا. للإيقاف/التفعيل نص، اضغط مع الاستمرار على زر التشغيل أثناء الضغط على زر رفع الصوت. وإذا لم تكن أجهزتك مثبّتة كلا الزرين، اضغط مع الاستمرار على أي زر لتبديل النص.
device/yoyodyne/tardis/recovery/recovery_ui.cpp
#include <linux/input.h> #include "common.h" #include "device.h" #include "screen_ui.h"
وظيفتا العناوين والعناصر
تتطلّب فئة الجهاز دوال لعرض العناوين والعناصر التي تظهر في مجموعة العناوين المخفية. قائمة الاسترداد. تصف العناوين كيفية تشغيل القائمة (أي عناصر التحكم لتغيير/تحديد العنصر المحدد).
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 };
ملاحظة: يتم اقتطاع الأسطر الطويلة (غير الملتفة)، لذا حافظ على عرض شاشة الجهاز في الاعتبار.
تخصيص مفتاح التحقّق
بعد ذلك، حدد تنفيذ RecoveryUI جهازك. يفترض هذا المثال أن
tardis فيه شاشة، لذلك يمكنك اكتساب نسخ من الأجهزة
تنفيذ واجهة مستخدم استرداد الشاشة (يُرجى الاطّلاع على التعليمات بشأن
الأجهزة التي لا تحتوي على شاشة). إن الدالة الوحيدة
بتخصيص من ScreenRecoveryUI هي CheckKey()
، والذي يقوم
معالجة المفاتيح غير المتزامنة:
class TardisUI : public ScreenRecoveryUI { public: virtual KeyAction CheckKey(int key) { if (key == KEY_HOME) { return TOGGLE; } return ENQUEUE; } };
الثوابت الرئيسية
يتم تحديد ثوابت KEY_* في linux/input.h
. CheckKey()
هو
بغض النظر عما يحدث في بقية عملية الاسترداد: عندما يتم إيقاف القائمة، وعندما
كان قيد التشغيل أو أثناء تثبيت الحزمة أو أثناء مسح بيانات المستخدم أو ما إلى ذلك. يمكن أن يعرض أحد الخيارات الأربعة
الثوابت:
- التبديل. التبديل بين تشغيل أو إيقاف عرض القائمة و/أو سجلّ النص
- إعادة التشغيل. إعادة تشغيل الجهاز فورًا
- تجاهل. تجاهل الضغط على المفتاح هذا
- طلب. ضع الضغط على المفتاح هذا في قائمة انتظار ليتم استخدامه بشكل متزامن (أي من خلال عملية الاسترداد). نظام القائمة إذا كانت الشاشة مُفعَّلة)
يتم استدعاء CheckKey()
في كل مرة يتبعها حدث مفتاح لأسفل بعد حدث رئيسي
نفس المفتاح. (ينتج عن تسلسل الأحداث A-down B-down B-up A-up فقط في
يتم طلب CheckKey(B)
). بإمكان "CheckKey()
" الاتصال
IsKeyPressed()
، لمعرفة ما إذا تم الضغط باستمرار على مفاتيح أخرى. (في ما سبق
تسلسل الأحداث الرئيسية، إذا استدعى CheckKey(B)
IsKeyPressed(A)
كانت ستكون صحيحة).
بإمكان CheckKey()
الحفاظ على الحالة في فئتها. يمكن أن يكون هذا مفيدًا لاكتشاف
وتسلسلات من المفاتيح. يوضح هذا المثال إعدادًا أكثر تعقيدًا: يتم تبديل الشاشة من خلال
الضغط باستمرار على الطاقة والضغط على رفع مستوى الصوت، ويمكن إعادة تشغيل الجهاز على الفور عن طريق
الضغط على زر التشغيل خمس مرات على التوالي (بدون مفاتيح متداخلة أخرى):
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، يمكنك ضبط المتغيّر animation_fps
للتحكّم في السرعة
لقطات في الثانية من الصور المتحركة.
ملاحظة: يسمح لك نص interlace-frames.py
البرمجي الحالي بما يلي:
تخزين معلومات animation_fps
في الصورة نفسها في الإصدارات السابقة من
كان على Android ضبط animation_fps
بنفسك.
لضبط المتغيّر animation_fps
، عليك إلغاء
ScreenRecoveryUI::Init()
في فئتك الفرعية. اضبط القيمة، ثم استدعِ
parent Init()
لإكمال الإعداد. القيمة التلقائية (20 لقطة في الثانية)
مع صور الاسترداد الافتراضية؛ فعند استخدام هذه الصور، لن تحتاج إلى تقديمها
دالة Init()
. للحصول على تفاصيل حول الصور، راجِع
صور واجهة المستخدم المخصّصة لاسترداد الحساب:
فئة الجهاز
بعد الحصول على تنفيذ RecoveryUI، حدد فئة جهازك (المصنفة الفرعية من
فئة الجهاز المدمجة). يُفترض أن ينشئ مثيلاً واحدًا لفئة واجهة المستخدم ويعرض
من الدالة GetUI()
:
class TardisDevice : public Device { private: TardisUI* ui; public: TardisDevice() : ui(new TardisUI) { } RecoveryUI* GetUI() { return ui; }
بدء الاسترداد
يتم استدعاء طريقة StartRecovery()
في بداية عملية الاسترداد، بعد أن تتضمن واجهة المستخدم
وبعد تحليل الوسيطات، ولكن قبل اتخاذ أي إجراء
تم التقاطها. لا يفعل التنفيذ التلقائي أي تأثير، لذلك لن تحتاج إلى ذكره في
إذا لم يكن عليك اتخاذ أي إجراء:
void StartRecovery() { // ... do something tardis-specific here, if needed .... }
توفير قائمة استرداد الحساب وإدارتها
يستدعي النظام طريقتين للحصول على قائمة أسطر العنوان وقائمة العناصر. في هذه الدورة، تُرجع الصفائف الثابتة المحددة في أعلى الملف:
const char* const* GetMenuHeaders() { return HEADERS; } const char* const* GetMenuItems() { return ITEMS; }
مفتاح القائمة المقبض
بعد ذلك، قم بتوفير الدالة HandleMenuKey()
، والتي تتطلب الضغط على مفتاح (ضغط)
مستوى ظهور القائمة، وتحديد الإجراء الذي يجب اتخاذه:
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; }
تأخذ الطريقة رمزًا رئيسيًا (تمت معالجته وإدراجه سابقًا في قائمة الانتظار بواسطة
CheckKey()
لكائن واجهة المستخدم)، والحالة الحالية للقائمة/سجل النص
مستوى الرؤية. تكون القيمة المعروضة عددًا صحيحًا. وإذا كانت القيمة 0 أو أعلى، فسيتم اعتبارها
موضع عنصر في القائمة، والذي يتم استدعاؤه على الفور (راجع
طريقة واحدة (InvokeMenuItem()
) أدناه). بخلاف ذلك، يمكن أن يكون أحد الأسباب التالية:
الثوابت المحددة مسبقًا:
- khighlightUp: نقل تمييز القائمة إلى العنصر السابق
- khighlightDown: نقل تمييز القائمة إلى العنصر التالي
- kInvokeItem. استدعاء العنصر الذي تم تمييزه حاليًا
- kNoAction: عدم اتخاذ أي إجراء عند الضغط على مفتاح
وفقًا لما تشير إليه الوسيطة المرئية، يتم استدعاء HandleMenuKey()
حتى إذا كانت القائمة
غير مرئية. على عكس CheckKey()
، لا يتم استدعاؤه أثناء تنفيذ عملية الاسترداد
شيء مثل مسح البيانات أو تثبيت حزمة — لا يتم طلبه إلا عندما يكون الاسترداد في وضع الخمول
وفي انتظار المدخلات.
آليات كرة التعقّب
إذا كان جهازك يحتوي على آلية إدخال تشبه كرة التعقب (يتم إنشاء أحداث إدخال بالنوع EV_REL
والرمز REL_Y)، فإن عملية الاسترداد تجمع بين المفتاحين KEY_UP وKEY_DOWN عند الضغط على
جهاز إدخال يشبه كرة التعقب يبلغ عن الحركة في المحور ص. كل ما عليك فعله هو تعيين KEY_UP
KEY_DOWN إلى إجراءات القائمة. لا يحدث هذا التعيين مع
CheckKey()
، لذلك لا يمكنك استخدام حركات كرة التعقب كعوامل تشغيل لإعادة التشغيل أو
تبديل الشاشة.
مفاتيح التعديل
للتحقّق من المفاتيح التي يتم الضغط مع الاستمرار عليها كمفاتيح تعديل، يمكنك طلب الطريقة IsKeyPressed()
.
لكائن واجهة المستخدم الخاص بك. على سبيل المثال، في بعض الأجهزة، قد يؤدي الضغط على Alt-W في عملية الاسترداد إلى بدء
مسح البيانات سواء كانت القائمة مرئية أم لا. يمكنك تنفيذ ما يلي:
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 } ... }
ملاحظة: إذا كانت قيمة visible خاطئة، فلا معنى إرجاع القيمة الخاصة. القيم التي تعالج القائمة (نقل التمييز واستدعاء العنصر المميّز) بما أنّ المستخدم لا يمكنه مشاهدة التمييز. ومع ذلك، يمكنك عرض القيم إذا أردت.
استدعاء عناصر القائمة
بعد ذلك، قدِّم الطريقة InvokeMenuItem()
التي تحدّد مواضع الأعداد الصحيحة في الصفيف.
من العناصر التي تم إرجاعها بواسطة GetMenuItems()
إلى الإجراءات. بالنسبة لصفيف العناصر في
مثال tardis، استخدم:
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; } }
يمكن أن تؤدي هذه الطريقة إلى إرجاع أي عضو في تعداد BuiltinAction لإخبار النظام باتخاذ هذا الإجراء. إجراء (أو عضو NO_ACTION إذا كنت تريد أن يتخذ النظام أي إجراء). هذا هو المكان توفير وظائف استرداد إضافية غير الميزات المتوفرة في النظام: يمكنك إضافة عنصر إلى القائمة، ويمكنك تنفيذها هنا عند استدعاء عنصر القائمة هذا، وعرض NO_ACTION حتى يتمكن النظام لا يفعل أي شيء آخر.
يحتوي BuiltinAction على القيم التالية:
- NO_ACTION. عدم اتّخاذ أي إجراء:
- إعادة التشغيل. اخرج من وضع الاسترداد وأعِد تشغيل الجهاز بشكل طبيعي.
- APPLY_EXT وAPPLY_CACHE وAPPLY_ADB_SIDELOAD. تثبيت حزمة تحديثات من تطبيقات متنوعة مكانًا. ولمعرفة التفاصيل، يُرجى الاطّلاع على مقالة التحميل من مصدر غير معروف.
- WIPE_CACHE. أعِد تنسيق قسم ذاكرة التخزين المؤقت فقط. ليس هناك تأكيد مطلوب لأنّ ذلك غير ضارة نسبيًا.
- WIPE_DATA: إعادة تنسيق أقسام بيانات المستخدم وذاكرة التخزين المؤقت، والمعروفة أيضًا باسم بيانات المصنع إعادة تعيين. يُطلب من المستخدم تأكيد هذا الإجراء قبل المتابعة.
الطريقة الأخيرة، WipeData()
، هي اختيارية ويتم طلبها عند حجب بيانات البيانات.
(إما من الاسترداد عبر القائمة أو عندما يختار المستخدم إجراء
إعادة الضبط على الإعدادات الأصلية من النظام الرئيسي). يتم استدعاء هذه الطريقة قبل بيانات المستخدم وذاكرة التخزين المؤقت
يتم مسح الأقسام. إذا كان جهازك يخزِّن بيانات المستخدمين في أي مكان آخر بخلاف هذين الاثنين
الأقسام، فيجب محوها هنا. يجب عليك إرجاع 0 للإشارة إلى النجاح
للإخفاق، على الرغم من أنه يتم حاليًا تجاهل القيمة المعروضة. بيانات المستخدم وذاكرة التخزين المؤقت
تُحسَب البيانات سواء نجح الأمر أم فشلت.
int WipeData() { // ... do something tardis-specific here, if needed .... return 0; }
صنع جهاز
أخيرًا، ضمِّن بعض النصوص النموذجية في نهاية ملفrecovery_ui.cpp في
make_device()
التي تنشئ مثيلاً لفئة الجهاز وتعرضه:
class TardisDevice : public Device { // ... all the above methods ... }; Device* make_device() { return new TardisDevice(); }
إنشاء استرداد الجهاز وربطه
بعد إكمال ملفrecovery_ui.cpp، تم إنشاؤه وربطه بالاسترداد على جهازك. ضِمن Android.mk، أنشِئ مكتبة ثابتة تحتوي على ملف C++ هذا فقط:
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)
ثم، في تهيئة اللوحة لهذا الجهاز، حدد مكتبتك الثابتة كقيمة TARGET_RECOVERY_UI_LIB.
device/yoyodyne/tardis/BoardConfig.mk [...] # device-specific extensions to the recovery UI TARGET_RECOVERY_UI_LIB := librecovery_ui_tardis
صور واجهة المستخدم المخصّصة لاسترداد الحساب
تتكوّن واجهة مستخدم الاسترداد من صور. من الناحية المثالية، لا يتفاعل المستخدمون مطلقًا مع واجهة المستخدم: وأثناء التحديث العادي، يبدأ الهاتف في تشغيل الاسترداد، ويملأ شريط تقدم التثبيت، ثم يعود إلى النظام الجديد بدون تدخل من المستخدم. في حالة تشغيل النظام في التحديث، فإن الإجراء الوحيد الذي يمكن للمستخدم اتخاذه هو الاتصال بخدمة العملاء.
إنّ استخدام واجهة تتضمّن صورًا فقط تغنيك عن الحاجة إلى الأقلمة. ومع ذلك، اعتبارًا من الإصدار Android 5.0، يمكن أن يعرض "تحديث" سلسلة من النصوص (مثلاً "جارٍ تثبيت تحديث النظام...") مع الصورة. لمعرفة التفاصيل، يُرجى الاطّلاع على نص الاسترداد المترجَم.
Android 5.0 والإصدارات الأحدث
تستخدم واجهة المستخدم المخصصة لاسترداد الحساب على الإصدار 5.0 من نظام التشغيل Android والإصدارات الأحدث صورتَين رئيسيتَين: صورة الخطأ. وحركة التركيب.
ويتم تمثيل الرسم المتحرك لتثبيت الصورة كصورة PNG واحدة بإطارات مختلفة من
رسم متحرك متداخل مع الصف (وهذا هو سبب ظهور الشكل 2 مضغوط). على سبيل المثال، بالنسبة إلى
رسم متحرك يتكون من سبعة إطارات مقاس 200×200، قم بإنشاء صورة واحدة بحجم 200×1400 حيث يكون الإطار الأول هو الصفوف 0 و7
14، 21، ...؛ الإطار الثاني هو الصفوف 1، 8، 15، 22، ...؛ وما إلى ذلك. تتضمن الصورة المدمجة
مقطع نصي يشير إلى عدد إطارات الرسوم المتحركة وعدد الإطارات في الثانية
(لقطات في الثانية). تأخذ أداة bootable/recovery/interlace-frames.py
مجموعة من إطارات الإدخال
وتدمجها في الصورة المُركبة اللازمة التي يستخدمها الاسترداد.
تتوفر الصور التلقائية بكثافة مختلفة وتقع في
bootable/recovery/res-$DENSITY/images
(مثال:
bootable/recovery/res-hdpi/images
). لاستخدام صورة ثابتة أثناء التركيب،
فأنت تحتاج فقط إلى تقديم صورة icon_installing.png وتعيين عدد الإطارات في
الحركة إلى 0 (رمز الخطأ ليس متحركًا؛ إنه دائمًا صورة ثابتة).
Android 4.x والإصدارات الأقدم
تستخدم واجهة المستخدم المخصصة لاسترداد الحسابات الإصدار 4.x من نظام التشغيل Android والإصدارات الأقدم صورة الخطأ (الموضحة أعلاه) رسم متحرك لتثبيت الصورة المتحركة إلى جانب عدة صور متراكبة:
أثناء التثبيت، يتم إنشاء الشاشة على الشاشة عن طريق الرسم icon_installing.png ثم رسم أحد إطارات التراكب فوقها بالإزاحة المناسبة. هنا، أحمر لإبراز مكان وضع التراكب أعلى الصورة الأساسية:
يتم عرض الإطارات اللاحقة عن طريق رسم الصورة التالية المركّبة فقط فوق موجودة بالفعل؛ عدم إعادة رسم الصورة الأساسية.
عدد الإطارات في الرسوم المتحركة، والسرعة المطلوبة، والإزاحة x وy للتراكب
بالنسبة إلى القاعدة بواسطة متغيرات الأعضاء في فئة ScreenRecoveryUI. عند استخدام
صور مخصصة بدلاً من الصور التلقائية، يمكنك إلغاء طريقة Init()
في
فئة فرعية لتغيير هذه القيم لصورك المخصصة (للحصول على التفاصيل، راجع
ScreenRecoveryUI). النص
يمكن أن يساعد تطبيق bootable/recovery/make-overlay.py
في تحويل مجموعة من إطارات الصور.
إلى "الصورة الأساسية + صور التراكب" الذي يتطلبه الاسترداد، بما في ذلك احتساب
الاعتمادات اللازمة.
تتوفّر الصور التلقائية في bootable/recovery/res/images
. لاستخدام صورة ثابتة
أثناء التثبيت، ما عليك سوى تقديم صورة icon_installing.png وتعيين عدد
الإطارات في الرسوم المتحركة إلى 0 (رمز الخطأ ليس متحركًا؛ إنه دائمًا صورة ثابتة).
نص الاسترداد المترجَم
يعرض الإصدار Android 5.x سلسلة من النصوص (مثل "جارٍ تثبيت تحديث النظام...") إلى جانب . عندما يبدأ النظام الرئيسي في عملية الاسترداد، يمرر اللغة الحالية للمستخدم سطر الأوامر لاسترداد البيانات. لكي يتم عرض كل رسالة، يتضمن الاسترداد ثانية واحدة صورة مركبة مع سلاسل نصية معروضة مسبقًا لهذه الرسالة بكل لغة.
صورة نموذج لسلاسل نصية لاسترداد الحساب:
يمكن أن يعرض نص الاسترداد الرسائل التالية:
- جارٍ تثبيت تحديث النظام...
- خطأ!
- جارٍ محو البيانات... (عند إجراء مسح بيانات/إعادة تعيين على الإعدادات الأصلية)
- عدم توفُّر أمر (عند تشغيل المستخدم لعملية الاسترداد يدويًا)
يعرض تطبيق Android في bootable/recovery/tools/recovery_l10n/
باللغات المحلية
من الرسالة وينشئ الصورة المركبة. للحصول على تفاصيل عن استخدام هذا التطبيق، يُرجى الرجوع إلى
التعليقات في
bootable/recovery/tools/recovery_l10n/src/com/android/recovery_l10n/Main.java
عندما يبدأ المستخدم عملية الاسترداد يدويًا، قد لا تكون اللغة متاحة أو لا يتوفر نص المعروضة. لا تجعل الرسائل النصية بالغة الأهمية لعملية الاسترداد.
ملاحظة: الواجهة المخفية التي تعرض رسائل السجل وتسمح للمستخدم وأن الإجراءات المحددة من القائمة متاحة باللغة الإنجليزية فقط.
أشرطة التقدم
وقد تظهر أشرطة التقدّم تحت الصورة الرئيسية (أو الصورة المتحركة). يتم إنشاء شريط التقدم بواسطة الجمع بين صورتَين للإدخال، على أن تكونا بالحجم نفسه:
يتم عرض الطرف الأيسر لصورة الملء بجوار الطرف الأيمن من صورة فارغة لإظهار شريط التقدم. موضع الحدود بين الاثنين الصور للإشارة إلى التقدم. على سبيل المثال، باستخدام أزواج صور الإدخال المذكورة أعلاه، العرض:
يمكنك تقديم نُسخ خاصة بكل جهاز من هذه الصور عن طريق وضعها في (في هذا
مثال) device/yoyodyne/tardis/recovery/res/images
. يجب أن تتطابق أسماء الملفات مع الأسماء الواردة أعلاه. عند العثور على ملف في هذا الدليل،
نظام التصميم هذا أفضل من الصورة الافتراضية المقابلة. تنسيقات PNG فقط بنموذج أحمر أخضر أزرق أو
ويتوفّر التنسيق RGBA مع عمق ألوان 8 بت.
ملاحظة: في الإصدار Android 5.x، إذا كانت اللغة معروفة بالاسترداد من اليمين إلى اليسار (العربية والعبرية وغيرها)، يتم ملء شريط التقدّم من اليمين إلى غادر.
الأجهزة التي لا تحتوي على شاشات
لا تحتوي جميع أجهزة Android على شاشات. إذا كان الجهاز بلا واجهة مستخدم رسومية أو كان يتضمّن التي تعمل بالصوت فقط، قد تحتاج إلى إجراء تخصيص أكثر شمولاً لواجهة المستخدم المخصصة لاسترداد الحساب. بدلاً من ذلك من إنشاء فئة فرعية من ScreenRecoveryUI، فصنفها الرئيسي RecoveryUI مباشرة
تتضمن RecoveryUI طرقًا للتعامل مع عمليات واجهة المستخدم ذات المستوى الأدنى مثل "تبديل العرض"
"تحديث شريط التقدم" و"عرض القائمة" و"تغيير تحديد القائمة" وما إلى ذلك. يمكنك تجاوز
هذه لتوفير واجهة مناسبة لجهازك. ربما يحتوي جهازك على مصابيح LED حيث
يمكنك استخدام ألوان أو أنماط وامضة مختلفة للإشارة إلى الحالة، أو ربما يمكنك لعب
الصوت. (ربما لا تريد دعم قائمة أو وضع "عرض النص" على الإطلاق؛ يمكنك
منع الوصول إليها باستخدام CheckKey()
عمليات تنفيذ HandleMenuKey()
التي لا تؤدي مطلقًا إلى تشغيل الشاشة أو اختيار قائمة
عنصر واحد. في هذه الحالة، فإن العديد من طرق RecoveryUI التي تحتاج إلى توفيرها يمكن أن تكون فارغة
العود).
يمكنك الانتقال إلى bootable/recovery/ui.h
للاطّلاع على بيان RecoveryUI لمعرفة الطرق
التي يجب عليك دعمها. تُعد RecoveryUI مجرّدة بعض الطرق التي تكون افتراضية بالكامل ويجب توفيرها من خلال
— لكنها تحتوي على التعليمات البرمجية للقيام بمعالجة المدخلات الرئيسية. يمكنك إلغاء ذلك
أيضًا، إذا لم يكن جهازك يحتوي على مفاتيح أو كنت تريد معالجتها بشكل مختلف.
محدّث
يمكنك استخدام رمز خاص بالجهاز في تثبيت حزمة التحديث من خلال تقديم دوال الإضافات التي يمكن استدعاؤها من داخل النص البرمجي لأداة التحديث. إليك عيّنة لوظيفة جهاز tardis:
device/yoyodyne/tardis/recovery/recovery_updater.c
#include <stdlib.h> #include <string.h> #include "edify/expr.h"
لكل دالة من وظائف الإضافات التوقيع نفسه. الوسيطات هي الاسم الذي
التي تم استدعاء الدالة، ملف تعريف ارتباط State*
، وعدد الوسيطات الواردة،
مصفوفة من مؤشرات Expr*
تمثل الوسيطات. والقيمة الناتجة هي
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); }
لم يتم تقييم الوسيطات في وقت استدعاء الدالة، وهي دالة
المنطق الذي يتم تقييمه وعدد المرات التي يتم تقييمها. وبالتالي، يمكنك استخدام إضافة
الدوال لتنفيذ هياكل التحكم الخاصة بك. Call Evaluate()
للتقييم
وسيطة Expr*
، مع عرض Value*
. إذا Evaluate()
القيمة "NULL"، يجب عليك تحرير أي موارد تمتلكها وإرجاع "NULL" (فارغ) على الفور
يلغي مكدس edify). بخلاف ذلك، ستحصل على ملكية القيمة التي تم إرجاعها
مسئولين عن استدعاء
FreeValue()
عليه.
لنفترض أنّ الدالة تحتاج إلى وسيطتَين: مفتاح يتضمّن قيمة سلسلة وثنائي القيمة. الصورة. يمكنك قراءة وسيطات مثل هذه:
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" (فارغ) وتحرير الوسيطات التي تم تقييمها سابقًا أمرًا مملاً لعدة
الوسيطة. ويمكن استخدام الدالة ReadValueArgs()
لتسهيل هذه المهمة. بدلاً من الرمز البرمجي
أعلاه، يمكنك كتابة هذا:
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()
"، لذا عليك إجراء ذلك هنا. إنّه أكثر
إجراء ذلك باستخدام عبارة if واحدة مقابل إنتاج نتيجة أقل
رسالة خطأ محددة عند إخفاقها. لكن ReadValueArgs()
تتولى مهمة التقييم
كل وسيطة وتحرير جميع الوسيطات التي تم تقييمها مسبقًا (بالإضافة إلى تعيين
) في حالة فشل أي من التقييمات. يمكنك استخدام
دالة الملاءمة ReadValueVarArgs()
لتقييم عدد متغير من
الوسائط (تعرض صفيفًا من Value*
).
بعد تقييم الوسيطات، قم بعمل الدالة:
// 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 ...
يجب أن تكون القيمة المعروضة كائن Value*
. تنتقل ملكية هذا الكائن إلى
المتصل. يحصل المتصل على ملكية أي بيانات يُشير إليها هذا.
Value*
- عضو البيانات تحديدًا.
في هذه الحالة، تريد إرجاع قيمة صواب أو خطأ للإشارة إلى النجاح. تذكر
بأن السلسلة الفارغة هي false وجميع السلاسل الأخرى هي true. إِنْتَ
يجب أن لإنشاء كائن قيمة مع نسخة اختبارية للسلسلة الثابتة المراد عرضها،
سيُجري المتصل free()
على الاثنين. تذكُّر الاتصال بـ FreeValue()
على
الكائنات التي حصلت عليها من خلال تقييم حججك!
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()
إلى التفاف سلسلة في كائن "قيمة" جديد.
استخدمها لكتابة التعليمة البرمجية أعلاه بإيجاز أكثر:
FreeValue(key); FreeValue(image); return StringValue(strdup(successful ? "t" : "")); }
لجذب الدوال إلى أداة الترجمة الفورية، قدِّم الدالة
Register_foo
حيث يكون foo هو اسم المكتبة الثابتة التي تحتوي على
هذا الرمز. يمكنك طلب RegisterFunction()
لتسجيل كل وظيفة من وظائف الإضافات. من
اصطلاح، قم بتسمية الدوال الخاصة بالجهاز device.whatever
المراد تجنبها
مع الدوال المضمنة المستقبلية المضافة.
void Register_librecovery_updater_tardis() { RegisterFunction("tardis.reprogram", ReprogramTardisFn); }
يمكنك الآن تهيئة ملف makefile لإنشاء مكتبة ثابتة باستخدام التعليمة البرمجية. (وهذا هو نفسه makefile المستخدَم لتخصيص واجهة مستخدم الاسترداد في القسم السابق؛ قد يحتوي جهازك على المكتبات الثابتة المحددة هنا).
device/yoyodyne/tardis/recovery/Android.mk
include $(CLEAR_VARS) LOCAL_SRC_FILES := recovery_updater.c LOCAL_C_INCLUDES += bootable/recovery
يجب أن يتطابق اسم المكتبة الثابتة مع اسم المكتبة
Register_libname
المضمنة فيها.
LOCAL_MODULE := librecovery_updater_tardis include $(BUILD_STATIC_LIBRARY)
وأخيرًا، يمكنك إعداد إصدار الاسترداد لدمج مكتبتك. إضافة مكتبتك إلى
TARGET_RECOVERY_UPDATER_LIBS (التي قد تحتوي على مكتبات متعددة؛ يتم تسجيلها جميعًا).
إذا كانت التعليمة البرمجية تعتمد على مكتبات ثابتة أخرى لا تتضمن هي نفسها الإضافات الراسخة (أي
لا تحتوي على دالة Register_libname
)، فيمكنك إدراجها في
TARGET_RECOVERY_UPDATER_EXTRA_LIBS لربطها بجهة التحديث بدون طلب
(غير موجودة). على سبيل المثال، إذا أراد الرمز الخاص بجهازك استخدام
zlib لفك ضغط البيانات، فيمكنك تضمين libz هنا.
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 استدعاء الدالة مثل أي دالة أخرى. لإعادة برمجته
جهاز tardis، قد يحتوي النص البرمجي للتحديث على:
tardis.reprogram("the-key", package_extract_file("tardis-image.dat"))
هذا يستخدم
نسخة وسيطة واحدة من الدالة المضمنة package_extract_file()
،
الذي يُرجع محتويات الملف المستخرَج من حزمة التحديث ككائن ثنائي كبير (blob) لإنتاج
الوسيطة الثانية إلى دالة الإضافة الجديدة.
إنشاء حزمة عبر اتصال لاسلكي
يتمثل المكون الأخير في الحصول على أدوات إنشاء حزمة OTA للتعرف على البيانات الخاصة بالجهاز والنصوص البرمجية لأداة التحديث التي تتضمن استدعاءات لدوال الإضافات.
أولاً، عليك تعريف نظام التصميم على كائن ثنائي كبير من البيانات خاص بالجهاز. لنفترض أن بياناتك
في الملف device/yoyodyne/tardis/tardis.dat
، يُرجى توضيح ما يلي في
AndroidBoard.mk للجهاز:
device/yoyodyne/tardis/AndroidBoard.mk
[...] $(call add-radio-file,tardis.dat)
يمكنك أيضًا وضعه في Android.mk بدلاً من ذلك، ولكن بعد ذلك يجب أن يحماه أحد الأجهزة. فحص، لأنه يتم تحميل جميع ملفات Android.mk في الشجرة بغض النظر عن الجهاز المستخدم بُنيت. (إذا كانت شجرتك تضم أجهزة متعددة، فأنت تريد فقط إضافة ملف tardis.dat عند إنشاء جهاز tardis).
device/yoyodyne/tardis/Android.mk
[...] # an alternative to specifying it in AndroidBoard.mk ifeq (($TARGET_DEVICE),tardis) $(call add-radio-file,tardis.dat) endif
وتُعرف هذه الملفات باسم ملفات الراديو لأسباب تاريخية. فقد لا يكون له أي علاقة
راديو للجهاز (إن وجد). إنها ببساطة وحدات ثنائية غير شفافة من البيانات التي ينسخ نظام الإصدار إليها
ملفات zip .المستهدفة التي تستخدمها أدوات إنشاء OTA. عندما تقوم بإنشاء ملف، يكون tardis.dat
المخزنة في target-files.zip باسم RADIO/tardis.dat
. يمكنك الاتصال
add-radio-file
عدة مرات لإضافة أي عدد تريده من الملفات.
وحدة بايثون
لتوسيع أدوات الإصدار، اكتب وحدة بايثون (يجب تسميتها releasetools.py) الأدوات يمكنك الاتصال بها إذا كانت موجودة. مثال:
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"));""")
تتعامل الدالة المنفصلة مع حالة إنشاء حزمة OTA تزايدية. لهذا الغرض لنفترض مثلاً أنك تحتاج إلى إعادة برمجة tardis فقط عندما يتم تغيير ملف tardis.dat بين بنيين.
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"));""")
دوال الوحدة
يمكنك تقديم الدوال التالية في الوحدة (تنفيذ الدوال التي تحتاج إليها فقط).
FullOTA_Assertions()
- يتم استدعاءه بالقرب من بداية إنشاء التحديث عبر الهواء الكامل. هذه فرصة جيدة لإرسال التأكيدات حول الحالة الحالية للجهاز. ولا تصدر أوامر نصوص برمجية تُجري تغييرات على الخاص بك.
FullOTA_InstallBegin()
- يتم طلب هذه البيانات بعد تمرير جميع التأكيدات حول حالة الجهاز، ولكن قبل إجراء أي تغييرات صناعة البرامج. يمكنك إصدار أوامر لتثبيت التحديثات الخاصة بالجهاز والتي يجب تشغيلها قبل تم تغيير أي شيء آخر على الجهاز.
FullOTA_InstallEnd()
- يتم استدعاؤه في نهاية إنشاء النص البرمجي، بعد أوامر النص البرمجي لتحديث نظام التشغيل إصدار أقسام النظام. يمكنك أيضًا إصدار أوامر إضافية التحديثات الخاصة بالجهاز.
IncrementalOTA_Assertions()
-
تشبه السمة
FullOTA_Assertions()
ولكن يتم استدعاؤها عند إنشاء زيادة حزمة التحديث. IncrementalOTA_VerifyBegin()
- يتم طلبه بعد تمرير جميع التأكيدات حول حالة الجهاز، ولكن قبل إجراء أي تغييرات صناعة المحتوى. يمكنك إصدار أوامر لتثبيت التحديثات الخاصة بالجهاز والتي يجب تشغيلها قبل أي إصدار من التطبيق. تم تغيير غير ذلك على الجهاز.
IncrementalOTA_VerifyEnd()
- يتم طلبه في نهاية مرحلة إثبات الملكية، عند انتهاء النص البرمجي من تأكيد الملفات التي سيستلمها تتضمن محتويات البدء المتوقعة. في هذه المرحلة، لا شيء على تم تغيير جهازك. يمكنك أيضًا إصدار رمز برمجي خاص عمليات التحقق من المعلنين.
IncrementalOTA_InstallBegin()
- يتم طلبه بعد التحقق من احتواء الملفات المطلوب تصحيحها على القيمة المتوقعة قبل إجراء أي تغييرات. يمكنك إصدار أوامر تم تغيير التحديثات الخاصة بالجهاز والتي يجب تشغيلها قبل أي شيء آخر على الجهاز.
IncrementalOTA_InstallEnd()
- على غرار نظيرتها الكاملة لحزمة OTA، يسمى هذا في نهاية النص البرمجي بعد تحديث أوامر البرنامج النصي لتحديث أقسام النظام والتشغيل المنبعثة. يمكنك أيضًا إصدار أوامر إضافية للحصول على تحديثات خاصة بالجهاز.
ملاحظة: إذا انقطع مصدر الطاقة عن الجهاز، قد تتم إعادة تشغيل تثبيت الجهاز عبر الهواء من البداية. كن مستعدًا للتعامل مع الأجهزة التي يتم تنفيذ هذه الأوامر عليها بالفعل، كليًا أو جزئيًا.
تمرير الدوال إلى كائنات المعلومات
تمرير الدوال إلى كائن معلومات واحد يحتوي على عناصر مفيدة متنوعة:
-
info.input_zip. (جميع وكالات السفر عبر الإنترنت فقط) الكائن
zipfile.ZipFile
الخاص بـ إدخال ملفات target-files .zip. -
info.source_zip. (عبر الهواء الإضافي فقط) الكائن
zipfile.ZipFile
لـ ملفات المصدر المستهدَفة zip. (الإصدار المتوفّر على الجهاز حاليًا عند تثبيت الحزمة التزايدية قيد التثبيت). -
info.target_zip. (عبر الهواء الإضافي فقط) الكائن
zipfile.ZipFile
لـ ملف target-files .zip (إصدار الحزمة التزايدية الذي تضعه على الجهاز). -
info.output_zip. جارٍ إنشاء الحزمة. تم فتح عنصر
zipfile.ZipFile
. للكتابة. استخدِم شائع.ZipWriteStr(info.output_zip، وfilename، وdata) لإضافة ملف إلى الحزمة. -
info.script. كائن النص البرمجي الذي يمكنك إلحاق الأوامر به. اتصل
info.script.AppendExtra(script_text)
لإخراج نص إلى النص البرمجي. التأكد من انتهاء نص الإخراج بفاصلة منقوطة حتى لا يصل إلى الأوامر الصادرة بعد ذلك.
للحصول على تفاصيل عن عنصر المعلومات، يُرجى الرجوع إلى مستندات Python Software Foundation (مؤسسة برمجيات Python) لأرشيفات ZIP
تحديد موقع الوحدة
حدِّد موقع النص البرمجي releasetools.py لجهازك في ملف BoardConfig.mk:
device/yoyodyne/tardis/BoardConfig.mk
[...] TARGET_RELEASETOOLS_EXTENSIONS := device/yoyodyne/tardis
إذا لم يتم ضبط TARGET_ReleaseTOOLS_extensionS، سيتم ضبطه تلقائيًا على
الدليل $(TARGET_DEVICE_DIR)/../common
(device/yoyodyne/common
في هذا المثال). من الأفضل تحديد مكان النص البرمجي releasetools.py بشكل صريح.
عند إنشاء جهاز tardis، يتم تضمين النص البرمجي releasetools.py في الملفات المستهدفة.
ملف ZIP (META/releasetools.py
).
عند تشغيل أدوات الإصدار (إما img_from_target_files
أو
ota_from_target_files
)، البرنامج النصي releasetools.py في ملف zip .المستهدف، إذا
حاليًا، مفضّلاً على شجرة مصادر Android يمكنك أيضًا
تحديد المسار إلى الإضافات الخاصة بالجهاز باستخدام -s
(أو
--device_specific
)، الذي يحتل الأولوية القصوى. يمكّنك هذا من
وتصحيح الأخطاء وإجراء تغييرات في إضافات Releasetools وتطبيق هذه التغييرات على الإصدار القديم
ملفات الهدف.
والآن، عند تشغيل ota_from_target_files
، يحتفظ تلقائيًا
وحدة خاصة بالجهاز من ملف target_files .zip وتستخدمها عند إنشاء التحديث عبر الهواء
الحزم:
./build/make/tools/releasetools/ota_from_target_files \
-i PREVIOUS-tardis-target_files.zip \
dist_output/tardis-target_files.zip \
incremental_ota_update.zip
وبدلاً من ذلك، يمكنك تحديد إضافات خاصة بالجهاز عند تشغيل
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
ملاحظة: للحصول على قائمة كاملة بالخيارات، يمكنك الرجوع إلى
ota_from_target_files
تعليقات في
build/make/tools/releasetools/ota_from_target_files
آلية التحميل من مصدر غير معروف
تشمل عملية الاسترداد آلية التحميل من مصدر غير معروف لتثبيت حزمة التحديث يدويًا بدون وتنزيله عبر شبكة غير سلكيّة من خلال النظام الرئيسي التحميل من مصدر غير معروف مفيد لتصحيح الأخطاء أو إنشاء التغييرات على الأجهزة التي يتعذر تشغيل النظام الرئيسي عليها.
في السابق، كان يتم التثبيت من مصدر غير معروف من خلال تحميل الحزم خارج بطاقة SD على الجهاز. بوصة في حالة جهاز لا يتم تشغيله، فيمكن وضع الحزمة على بطاقة SD باستخدام أداة الكمبيوتر ثم بطاقة SD التي تم إدخالها في الجهاز. لاستيعاب أجهزة Android التي لا تحتوي وحدة تخزين خارجية قابلة للإزالة، يدعم الاسترداد آليتين إضافيتين للتثبيت من مصدر غير معروف: تحميل الحزم من قسم ذاكرة التخزين المؤقت وتحميلها عبر USB باستخدام adb.
لاستدعاء كل آلية من آليات التحميل من مصدر غير معروف، طريقة Device::InvokeMenuItem()
في جهازك
عرض القيم التالية لـ BuiltinAction:
-
apply_EXT تحميل حزمة تحديث من وحدة تخزين خارجية من مصدر غير معروف (
/sdcard
الدليل). يجب أن يحدّد ملفrecovery.fstab نقطة تثبيت/sdcard
. هذا هو لا يمكن استخدامها على الأجهزة التي تحاكي بطاقة SD ذات رابط رمزي إلى/data
(أو بعض آلية مماثلة). لا يمكن عادةً استرداد الحساب/data
لأنّه أن تكون مشفّرة. تعرض واجهة المستخدم المخصصة لاسترداد الحساب قائمة بملفات .zip في/sdcard
تسمح للمستخدم باختيار واحد منها. -
apply_CACHE. يشبه تحميل حزمة من
/sdcard
باستثناء أنّ يتم استخدام دليل/cache
(متاح دائمًا للاسترداد) بدلاً من ذلك. من النظام العادي، لا يمكن الكتابة من خلال/cache
إلا من خلال المستخدمين الحاصلين على الامتيازات، وإذا لم يكن الجهاز قابلاً للتشغيل، لا يمكن كتابة دليل/cache
إلى على الإطلاق (مما يجعل هذه الآلية ذات فائدة محدودة). -
apply_ADB_SIDELOAD يسمح للمستخدم بإرسال طرد إلى الجهاز عبر كابل USB
أداة تطوير adb. عند استدعاء هذه الآلية، يبدأ الاسترداد في
من البرنامج الخفي لـ adbd للسماح لـ adb على كمبيوتر مضيف متصل بالتحدث إليه. هذه الصورة المصغّرة
يتوافق الإصدار مع أمر واحد فقط:
adb sideload filename
. ويتم إرسال الملف المُسمى من الجهاز المضيف إلى الجهاز، الذي يتأكد بعد ذلك من وتثبّته كما لو كانت على وحدة التخزين المحلية.
بعض المحاذير:
- لا يتم دعم سوى النقل عبر USB.
-
إذا شغَّلت عملية الاسترداد adbd بشكل طبيعي (عادةً ما يكون ذلك صحيحًا في إصدارات userdebug وeng)، فإن ذلك
إيقاف التشغيل عندما يكون الجهاز في وضع التحميل الجانبي من خلال adb، وستتم إعادة تشغيله عند استخدام adb
انتهى التحميل الجانبي من تلقي حزمة. أثناء استخدام وضع التحميل الجانبي لـ adb، لا توجد أوامر adb أخرى
من
sideload
عمل (logcat
،reboot
،push
وpull
وshell
وما إلى ذلك ففشل كل ذلك). -
لا يمكنك الخروج من وضع التثبيت الجانبي من adb على الجهاز. للإلغاء، يمكنك إرسال
/dev/null
(أو أي خدمة أخرى لا تُعدّ حزمة صالحة) على أنّها الحزمة لن يتمكّن الجهاز من التحقّق من ذلك ويوقِف إجراء التثبيت. واجهة RecoveryUI في التنفيذ، سيستمر استدعاء طريقةCheckKey()
الخاصة بعمليات الضغط على المفاتيح، لذا يمكنك توفير تسلسل للمفاتيح يُعيد تشغيل الجهاز ويعمل في وضع التثبيت الجانبي من adb.