التغييرات على الإصدار 6.0 من Android

بالإضافة إلى الميزات والإمكانات الجديدة، يتضمّن الإصدار 6.0 من نظام التشغيل Android (المستوى 23 من واجهة برمجة التطبيقات) مجموعة متنوعة من التغييرات في النظام وسلوك واجهة برمجة التطبيقات. يسلط هذا المستند الضوء على بعض التغييرات الرئيسية التي يجب أن تفهمها وتراعيها في تطبيقاتك.

إذا سبق لك نشر تطبيق لنظام التشغيل Android، يُرجى العِلم أنّ هذه التغييرات في النظام الأساسي تؤثر في تطبيقك.

أذونات وقت التشغيل

يقدّم هذا الإصدار نموذجًا جديدًا للأذونات، حيث يمكن للمستخدمين الآن إدارة أذونات التطبيقات مباشرةً في وقت التشغيل. يمنح هذا النموذج المستخدمين إمكانية وصول أفضل والتحكم في الأذونات، مع تبسيط عمليات التثبيت والتحديث التلقائي لمطوّري التطبيقات. يمكن للمستخدمين منح الأذونات أو إبطالها بشكل فردي للتطبيقات المثبَّتة.

في تطبيقاتك التي تستهدف الإصدار 6.0 من نظام التشغيل Android (المستوى 23 من واجهة برمجة التطبيقات) أو الإصدارات الأحدث، احرص على التحقّق من الأذونات وطلبها في وقت التشغيل. لتحديد ما إذا تم منح تطبيقك إذنًا، يمكنك استدعاء المحاولة الجديدة checkSelfPermission(). لطلب إذن، يمكنك استدعاء الأسلوب الجديد requestPermissions(). حتى إذا كان تطبيقك لا يستهدف الإصدار 6.0 من نظام التشغيل Android (المستوى 23 من واجهة برمجة التطبيقات)، عليك اختبار تطبيقك ضمن نموذج الأذونات الجديد.

للحصول على تفاصيل عن توافق تطبيقك مع نموذج الأذونات الجديد، يُرجى الاطّلاع على مقالة العمل مع أذونات النظام. للحصول على نصائح حول كيفية تقييم التأثير في تطبيقك، راجِع ملاحظات حول استخدام الأذونات.

وضع "الاستراحة" و"وضع الاستعداد للتطبيقات"

يقدّم هذا الإصدار تحسينات جديدة لتوفير الطاقة في الأجهزة والتطبيقات التي لا تعمل. تؤثر هذه الميزات في جميع التطبيقات، لذا احرص على اختبار تطبيقاتك في هذه الأوضاع الجديدة.

  • القيلولة: إذا فصل المستخدم جهازًا وتركه ثابتًا مع إطفاء شاشته لفترة من الوقت، ينتقل الجهاز إلى وضع القيلولة حيث يحاول إبقاء النظام في حالة السكون. في هذا الوضع، تستأنف الأجهزة بشكل دوري العمليات العادية لفترات زمنية قصيرة حتى تحدث مزامنة التطبيقات ويتمكّن النظام من تنفيذ أي عمليات معلّقة.
  • وضع "التطبيقات في وضع الاستعداد": يتيح هذا الوضع للنظام تحديد أنّ التطبيق في وضع عدم النشاط عندما لا يستخدمه المستخدم بشكل نشط. يتّخذ النظام هذا القرار عندما لا يتفاعل المستخدم مع التطبيق لفترة زمنية معيّنة. في حال فصل الجهاز عن مصدر الطاقة، يوقف النظام إمكانية الوصول إلى الشبكة ويوقف عمليات المزامنة والمهام للتطبيقات التي يرى أنّها غير نشطة.

لمزيد من المعلومات عن هذه التغييرات التي توفّر الطاقة، يُرجى الاطّلاع على مقالة تحسين وضعَي "الاستراحة الذكية" و"الاستعداد للتطبيقات".

إزالة Apache HTTP Client

يزيل إصدار Android 6.0 دعم عميل Apache HTTP. إذا كان تطبيقك يستخدم هذا البرنامج ويستهدف الإصدار 2.3 (المستوى 9 من واجهة برمجة التطبيقات) أو الإصدارات الأحدث، استخدِم الفئة HttpURLConnection بدلاً من ذلك. وتعدّ هذه الواجهة أكثر فعالية لأنّها تقلّل من استخدام الشبكة من خلال الضغط الشفاف والتخزين المؤقت للردّ، كما تقلّل من استهلاك الطاقة. لمواصلة استخدام واجهات برمجة التطبيقات Apache HTTP، عليك أولاً تحديد التبعية التالية في وقت الترجمة في ملف build.gradle:

android {
    useLibrary 'org.apache.http.legacy'
}

BoringSSL

ينتقل Android من مكتبة OpenSSL إلى مكتبة BoringSSL. إذا كنت تستخدم حزمة Android NDK في تطبيقك، لا تربطها بمكتبات التشفير التي لا تشكّل جزءًا من واجهة برمجة التطبيقات NDK، مثل libcrypto.so وlibssl.so. هذه المكتبات ليست واجهات برمجة تطبيقات علنية، وقد تتغيّر أو تتعذّر استخدامها بدون إشعار على جميع الإصدارات والأجهزة. بالإضافة إلى ذلك، قد تتعرض نفسك لثغرات أمنية. بدلاً من ذلك، عدِّل الرمز البرمجي الأصلي لاستدعاء واجهات برمجة تطبيقات التشفير في Java من خلال واجهة JNI أو للربط بشكل ثابت بمكتبة تشفير من اختيارك.

الوصول إلى معرّف الجهاز

لتوفير حماية أكبر للبيانات للمستخدمين، بدءًا من هذا الإصدار، يزيل نظام التشغيل Android إمكانية الوصول الآلي إلى معرّف الجهاز المحلي للتطبيقات التي تستخدم واجهات برمجة التطبيقات Wi-Fi وBluetooth. تُرجِع الآن الطريقتان WifiInfo.getMacAddress() و BluetoothAdapter.getAddress() قيمة ثابتة تبلغ 02:00:00:00:00:00.

للوصول إلى معرّفات الأجهزة الخارجية المجاورة من خلال عمليات البحث عن الأجهزة عبر البلوتوث وWi-Fi، يجب أن يكون لدى تطبيقك الآن إذنَي ACCESS_FINE_LOCATION أو ACCESS_COARSE_LOCATION:

ملاحظة: عندما يبدأ جهاز يعمل بالإصدار 6.0 من Android (المستوى 23 من واجهة برمجة التطبيقات) في إجراء عملية تفتيش في شبكة Wi-Fi أو البلوتوث في الخلفية، تظهر العملية للأجهزة الخارجية على أنّها ناتجة عن عنوان MAC عشوائي.

الإشعارات

يزيل هذا الإصدار طريقة Notification.setLatestEventInfo(). استخدِم فئة Notification.Builder بدلاً من ذلك لإنشاء الإشعارات. لتعديل إعلام بشكل متكرّر، أعِد استخدام مثيل Notification.Builder. استخدِم build() للحصول على مثيلات Notification معدَّلة.

لن يطبع الأمر adb shell dumpsys notification نص الإشعار بعد ذلك. استخدِم الأمر adb shell dumpsys notification --noredact بدلاً من ذلك لطباعة النص في عنصر إشعار.

التغييرات في "مدير الصوت"

لم يعُد من الممكن ضبط مستوى الصوت مباشرةً أو كتم صوت أحداث بث معيّنة من خلال فئة AudioManager. تم إيقاف طريقة setStreamSolo() نهائيًا، وعليك استدعاء الأسلوب requestAudioFocus() بدلاً من ذلك. وبالمثل، تمّت إيقاف الطريقة setStreamMute() نهائيًا. بدلاً من ذلك، يمكنك استدعاء الطريقة adjustStreamVolume() وإدخال قيمة الاتجاه ADJUST_MUTE أو ADJUST_UNMUTE.

تحديد النص

شاشة تعرض ميزات جديدة لاختيار النص ضمن شريط أدوات عائم

عندما يحدّد المستخدمون نصًا في تطبيقك، يمكنك الآن عرض إجراءات اختيار النص، مثل القص والنسخ واللصق في شريط أدوات عائم. يشبه تنفيذ تفاعل المستخدم تنفيذ شريط الإجراءات السياقية، كما هو موضّح في مقالة تفعيل وضع الإجراءات السياقية لطرق العرض الفردية.

لتنفيذ شريط أدوات عائم لاختيار النص، عليك إجراء التغييرات التالية في تطبيقاتك الحالية:

  1. في عنصر View أو Activity، غيِّر ActionMode المكالمات من startActionMode(Callback) إلى startActionMode(Callback, ActionMode.TYPE_FLOATING).
  2. استخدِم آلية التنفيذ الحالية لـ ActionMode.Callback واجعلها تمتد لتشمل ActionMode.Callback2 بدلاً من ذلك.
  3. يمكنك إلغاء طريقة onGetContentRect() لتوفير إحداثيات المحتوى Rect (مثل مستطيل تحديد النص) في طريقة العرض.
  4. إذا لم يعُد تحديد موضع المستطيل صالحًا، وكان هذا هو العنصر الوحيد الذي تم إلغاء صلاحيته، يمكنك استدعاء طريقة invalidateContentRect().

إذا كنت تستخدم الإصدار 22.2 من مكتبة Android Support Library، يُرجى العِلم أنّ أشرطة الأدوات العائمة ليست متوافقة مع الإصدارات القديمة، وتتحكّم مكتبة appcompat في عناصر ActionMode بشكلٍ تلقائي. يؤدي ذلك إلى منع عرض أشرطة الأدوات العائمة. لتفعيل استخدام ActionMode في AppCompatActivity، استخدِم دالة getDelegate()، ثم استخدِم دالة setHandleNativeActionModesEnabled() على عنصر AppCompatDelegate الذي تم إرجاعه واضبط مَعلمة input على false. يعيد هذا الاستدعاء التحكّم في كائنات ActionMode إلى إطار العمل. في الأجهزة التي تعمل بالإصدار Android 6.0 (المستوى 23 من واجهة برمجة التطبيقات)، الذي يتيح لإطار العمل إمكانية استخدام ActionBar أو أوضاع شريط الأدوات العائمة، بينما على الأجهزة التي تعمل بالإصدار 5.1 من نظام التشغيل Android (المستوى 22 من واجهة برمجة التطبيقات) أو الإصدارات الأقدم، تتوفّر أوضاع ActionBar فقط.

تغييرات الإشارات المرجعية في المتصفّح

يزيل هذا الإصدار إمكانية استخدام الإشارات المرجعية الشاملة. تمت الآن إزالة الطريقتين android.provider.Browser.getAllBookmarks() وandroid.provider.Browser.saveBookmark(). وبالمثل، تتم إزالة إذنَي READ_HISTORY_BOOKMARKS وWRITE_HISTORY_BOOKMARKS. إذا كان تطبيقك يستهدف الإصدار 6.0 من نظام التشغيل Android (المستوى 23 من واجهة برمجة التطبيقات) أو الإصدارات الأحدث، يجب عدم الوصول إلى bookmarkedbookmarks من مقدّم الخدمة العام أو استخدام أذونات الإشارات المرجعية. بدلاً من ذلك، يجب أن يخزن تطبيقك بيانات الإشارات المرجعية داخليًا.

التغييرات في ملف تخزين مفاتيح Android

مع هذا الإصدار، لم يعُد موفِّر "متجر مفاتيح Android" يتوافق مع التشفير غير المتماثل. لا تزال ECDSA متاحة.

إنّ المفاتيح التي لا تتطلب تشفيرًا غير نشِطة لن يتم حذفها بعد الآن عند إيقاف شاشة القفل الآمنة أو إعادة ضبطها (على سبيل المثال، من قِبل المستخدم أو مشرف الجهاز). وسيتم حذف المفاتيح التي تتطلّب التشفير في وضع عدم الاتّصال بالإنترنت أثناء هذه الأحداث.

تغييرات Wi-Fi والشبكات

يقدّم هذا الإصدار التغييرات التالية في السلوك على واجهات برمجة تطبيقات Wi-Fi والشبكات.

  • يمكن لتطبيقاتك الآن تغيير حالة عناصر WifiConfiguration فقط إذا أنشأت هذه العناصر. لا يُسمح لك بتعديل أو حذف WifiConfiguration العناصر التي أنشأها المستخدم أو التطبيقات الأخرى.
  • في السابق، إذا فرض تطبيق على الجهاز الاتصال بشبكة Wi-Fi معيّنة باستخدام enableNetwork() مع الإعداد disableAllOthers=true، كان يتم فصل الجهاز عن الشبكات الأخرى، مثل شبكة data. cellular في هذا الإصدار، لم يعُد الجهاز ينقطع عن هذه الشبكات الأخرى. إذا كانtargetSdkVersion تطبيقك هو “20” أو أقل، سيتم تثبيته على شبكة Wi-Fi المحدّدة. إذا كان targetSdkVersion لتطبيقك هو “21” أو إصدار أحدث، استخدِم واجهات برمجة التطبيقات المخصّصة للشبكات المتعددة (مثل openConnection() و bindSocket() وطريقة bindProcessToNetwork() الجديدة) لضمان إرسال عدد زيارات الشبكة على الشبكة المحدّدة.

التغييرات في خدمة الكاميرا

في هذا الإصدار، تم تغيير نموذج الوصول إلى الموارد المشتركة في خدمة الكاميرا من نموذج الوصول السابق "الأولوية لمن يأتي أولاً" إلى نموذج وصول يمنح الأولوية لعمليات الأولوية العالية. تشمل التغييرات في سلوك الخدمة ما يلي:

  • يتم منح إذن الوصول إلى موارد النظام الفرعي للكاميرا، بما في ذلك فتح جهاز الكاميرا وضبطه، استنادًا إلى "الأولوية" لمعالجة تطبيق العميل. بشكل عام، تُمنح الأولوية الأعلى لعمليات التطبيقات التي تشمل أنشطة مرئية للمستخدم أو أنشطة تعمل في المقدّمة، ما يجعل عملية الحصول على موارد الكاميرا واستخدامها أكثر موثوقية.
  • قد يتم "إخلاء" عملاء الكاميرا النشطين للتطبيقات ذات الأولوية الأقل عندما يحاول تطبيق ذو أولوية أعلى استخدام الكاميرا. في واجهة برمجة التطبيقات Camera التي سيتم إيقافها نهائيًا، يؤدي ذلك إلى onError() الاستدعاء للعميل الذي تمّت إزالته. في واجهة برمجة تطبيقات Camera2، يتم طلب onDisconnected() إلى العميل الذي تم استبعاده.
  • على الأجهزة التي تتضمّن أجهزة الكاميرا المناسبة، يمكن لعمليات التطبيقات المنفصلة فتح أجهزة كاميرا منفصلة واستخدامها بشكل مستقل في الوقت نفسه. ومع ذلك، فإنّ خدمة الكاميرا ترصد الآن حالات استخدام المهام المتعددة التي تؤدي إلى تدهور كبير في أداء أو إمكانات أي من أجهزة الكاميرا المفتوحة عند الوصول إليها في الوقت نفسه، وتمنعها. قد يؤدي هذا التغيير إلى "إغلاق" التطبيقات ذات الأولوية الأقل حتى في حال عدم محاولة أي تطبيق آخر الوصول مباشرةً إلى جهاز الكاميرا نفسه.
  • يؤدي تغيير المستخدم الحالي إلى استبعاد برامج الكاميرا النشطة في التطبيقات التي يملكها حساب المستخدم السابق. يقتصر الوصول إلى الكاميرا على الملفات الشخصية للمستخدمين التي يملكها مستخدم الجهاز الحالي. من الناحية العملية، يعني ذلك أنّ حساب "ضيف"، على سبيل المثال، لن يتمكّن من الخروج من العمليات التي تستخدم المنظومة الفرعية للكاميرا عندما ينتقل المستخدم إلى حساب مختلف.

وقت التشغيل

ينفِّذ وقت تشغيل ART الآن قواعد الوصول إلى الأسلوب newInstance() بشكل صحيح. يعالج هذا التغيير مشكلة كانت تؤدي إلى فحص Dalvik لقواعد الوصول بشكل غير صحيح في الإصدارات السابقة. إذا كان تطبيقك يستخدِم طريقة newInstance() وأردت إلغاء عمليات التحقّق من إمكانية الوصول، يمكنك استدعاء طريقة setAccessible() مع ضبط معلَمة الإدخال على true. إذا كان تطبيقك يستخدم مكتبة appcompat‏ v7 أو مكتبة recyclerview‏ v7، عليك تحديث تطبيقك لاستخدام أحدث إصدارات من هذه المكتبات. وبخلاف ذلك، احرص على تعديل أي فئات مخصَّصة مُشار إليها من XML بحيث يمكن الوصول إلى منصات إنشاء الفئات الخاصة بها.

يُعدّل هذا الإصدار سلوك أداة الربط الديناميكي. يفهم الرابط الديناميكي الآن الفرق بين soname للمكتبة ومسارها ( الخطأ العام 6670)، ويتم الآن تنفيذ البحث حسب soname. قد يتعذّر تحميل التطبيقات التي كانت تعمل سابقًا والتي تحتوي على إدخالات DT_NEEDED غير صالحة (عادةً مسارات مطلقة في نظام ملفات جهاز الإنشاء).

تم تنفيذ علامة dlopen(3) RTLD_LOCAL بشكل صحيح الآن. يُرجى العلم أنّ RTLD_LOCAL هو الإعداد التلقائي، لذا ستتأثر طلبات dlopen(3) التي لم تستخدم RTLD_LOCAL بشكل صريح (ما لم يستخدم تطبيقك RTLD_GLOBAL بشكل صريح). باستخدام RTLD_LOCAL، لن تتوفّر الرموز للمكتبات التي يتم تحميلها من خلال طلبات لاحقة إلى dlopen(3) (على عكس الإشارة إليها من خلال إدخالات DT_NEEDED).

في الإصدارات السابقة من Android، إذا طلب تطبيقك من النظام تحميل مكتبة مشتركة مع عمليات نقل نصوص، كان النظام يعرض تحذيرًا، ولكنه مع ذلك يسمح بتحميل المكتبة. بدءًا من هذا الإصدار، يرفض النظام هذه المكتبة إذا كان إصدار حزمة تطوير البرامج (SDK) المستهدَف لتطبيقك هو 23 أو إصدار أحدث. لمساعدتك في رصد حالات تعذُّر تحميل مكتبة، يجب أن يسجِّل تطبيقك تعذُّر dlopen(3)، وأن يتضمّن نص وصف المشكلة الذي يعرضه طلب dlerror(3) . لمزيد من المعلومات عن التعامل مع عمليات إعادة وضع النصوص، اطّلِع على هذا الدليل.

التحقق من صحة APK

تُجري المنصة الآن عمليات تحقّق أكثر صرامة من حِزم APK. تُعتبر حزمة APK تالفة إذا تم تحديد ملف في البيان ولم يكن متوفّرًا في حزمة APK نفسها. يجب إعادة توقيع حزمة APK في حال إزالة أي من المحتوى.

اتصال USB

يتم الآن ضبط عمليات توصيل الأجهزة من خلال منفذ USB على وضع الشحن فقط تلقائيًا. للوصول إلى الجهاز ومحتواه عبر اتصال USB، يجب أن يمنح المستخدمون الإذن صراحةً بهذه التفاعلات. إذا كان تطبيقك يتيح للمستخدمين التفاعل مع الجهاز من خلال منفذ USB، يجب مراعاة أن يكون التفاعل مفعّلاً بشكل صريح.

تغييرات Android for Work

يتضمّن هذا الإصدار التغييرات التالية في السلوك في برنامج "Android للعمل":

  • جهات اتصال العمل في السياقات الشخصية: يعرض سجلّ المكالمات في "أداة الاتصال من Google" الآن جهات اتصال العمل عندما يعرض المستخدم المكالمات السابقة. يؤدي ضبط setCrossProfileCallerIdDisabled() على true إلى إخفاء جهات اتصال ملف العمل في سجلّ مكالمات Google Dialer. لا يمكن عرض جهات اتصال العمل مع جهات الاتصال الشخصية على الأجهزة عبر البلوتوث إلا إذا ضبطت الخيار setBluetoothContactSharingDisabled() على false. ويتم ضبطها تلقائيًا على true.
  • إزالة إعدادات Wi-Fi: تتم الآن إزالة إعدادات Wi-Fi التي أضافها مالك الملف الشخصي (على سبيل المثال، من خلال طلبات إلى الأسلوب addNetwork()) في حال حذف ملف العمل هذا.
  • قفل إعدادات Wi-Fi: لا يمكن للمستخدم تعديل أو حذف أي إعدادات Wi-Fi أنشأها مالك جهاز نشط إذا كان قيمة WIFI_DEVICE_OWNER_CONFIGS_LOCKDOWN غير صفرية. وسيظل بإمكان المستخدم إنشاء إعدادات Wi-Fi الخاصة به وتعديلها. الجهاز النشط يتمتع المالكون بامتياز تعديل أو إزالة أي إعدادات لشبكة Wi-Fi، بما في ذلك الإعدادات التي لم ينشئوها بأنفسهم.
  • تنزيل "وحدة التحكّم بسياسة الجهاز" من خلال إضافة حساب Google: عند إضافة حساب Google يتطلب إدارة من خلال تطبيق وحدة التحكّم بسياسة الجهاز (DPC) إلى أحد الأجهزة خارج سياق مُدار، يطلب مسار إضافة الحساب من المستخدم الآن تثبيت خدمة WPC المناسبة. ينطبق هذا السلوك أيضًا على الحسابات التي تمت إضافتها من خلال الإعدادات > الحسابات وفي معالج الإعداد الأولي للجهاز.
  • تغييرات في سلوكيات معيّنة لواجهة برمجة التطبيقات DevicePolicyManager:
    • لا يؤثّر استدعاء الأسلوب setCameraDisabled() في الكاميرا إلا للمستخدم المُتصل فقط، ولا يؤثّر استدعاؤه من الملف الشخصي المُدار في تطبيقات الكاميرا التي تعمل على حساب المستخدم الأساسي.
    • بالإضافة إلى ذلك، تتوفر الطريقة setKeyguardDisabledFeatures() الآن لمالكي الملفات الشخصية ولمالكي الأجهزة.
    • يمكن لمالك الملف الشخصي ضبط القيود التالية على شاشة القفل:
    • تم إيقاف الطريقتَين DevicePolicyManager.createAndInitializeUser() وDevicePolicyManager.createUser() نهائيًا.
    • تحظر الطريقة setScreenCaptureDisabled() الآن أيضًا بنية المساعدة عندما يكون تطبيق المستخدم المحدّد في المقدّمة.
    • EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_CHECKSUM أصبحت الآن القيمة التلقائية هي SHA-256. لا يزال معيار SHA-1 متاحًا للتوافق مع الأنظمة القديمة، ولكن ستتم إزالته في المستقبل. EXTRA_PROVISIONING_DEVICE_ADMIN_SIGNATURE_CHECKSUM لا يقبل الآن سوى SHA-256.
    • تمّت الآن إزالة واجهات برمجة التطبيقات لبرنامج إعداد الجهاز التي كانت متوفّرة في الإصدار 6.0 من نظام التشغيل Android (المستوى 23 من واجهة برمجة التطبيقات).
    • تمت إزالة EXTRA_PROVISIONING_RESET_PROTECTION_PARAMETERS لكي لا يتمكّن الإعداد باستخدام تقنية الربط المزود بتقنية NFC من فتح قفل جهاز محمي بميزة "إعادة الضبط على الإعدادات الأصلية" آليًا.
    • يمكنك الآن استخدام EXTRA_PROVISIONING_ADMIN_EXTRAS_BUNDLE extra لنقل البيانات إلى تطبيق مالك الجهاز أثناء إعداد الجهاز المُدار باستخدام NFC.
    • تم تحسين واجهات برمجة تطبيقات Android for Work من أجل أذونات التشغيل M، بما في ذلك ملفات العمل وطبقة المساعدة وغيرها. لا تؤثر واجهات برمجة التطبيقات الجديدة لأذونات DevicePolicyManager في التطبيقات التي تعمل بإصدارات أقدم من Android 10.
    • عندما يتراجع المستخدمون عن الجزء المتزامن من عملية الإعداد التي تمّ بدؤها من خلال نية ACTION_PROVISION_MANAGED_PROFILE أو ACTION_PROVISION_MANAGED_DEVICE، يعرض النظام الآن رمز النتيجة RESULT_CANCELED.
  • التغييرات على واجهات برمجة التطبيقات الأخرى:
    • استخدام البيانات: تمت إعادة تسمية فئة android.app.usage.NetworkUsageStats NetworkStats.
  • التغييرات في الإعدادات العامة: