تغييرات السلوك: جميع التطبيقات

يتضمّن الإصدار 10 من نظام التشغيل Android تغييرات في السلوك قد تؤثّر في تطبيقك. تسري التغييرات المدرَجة في هذه الصفحة على تطبيقك عند تشغيله على الإصدار 10 من نظام التشغيل Android، بغض النظر عن targetSdkVersion للتطبيق. عليك اختبار تطبيقك وتعديله حسب الحاجة ليتوافق مع هذه التغييرات بشكل صحيح.

إذا كان targetSdkVersion لتطبيقك هو 29 أو أعلى، عليك أيضًا توفير الدعم للتغييرات الإضافية. يُرجى الاطّلاع على التغييرات في السلوك بالنسبة إلى التطبيقات التي تستهدف الإصدار 29 للحصول على التفاصيل.

ملاحظة: بالإضافة إلى التغييرات الواردة في هذه الصفحة، يقدّم نظام التشغيل Android 10 عددًا كبيرًا من التغييرات والقيود المستندة إلى الخصوصية، بما في ذلك ما يلي:

  • الوصول إلى الموقع الجغرافي للجهاز في الخلفية
  • بدء النشاط في الخلفية
  • معلومات الاهتمامات المشتركة لجهات الاتصال
  • اختيار عنوان MAC بشكل عشوائي
  • البيانات الوصفية للكاميرا
  • نموذج الأذونات

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

قيود الواجهات غير المتوفّرة في حزمة SDK

للمساعدة في ضمان ثبات التطبيق وتوافقه، بدأت المنصة في فرض قيود على واجهات برمجة التطبيقات غير التابعة لحزمة SDK التي يمكن لتطبيقك استخدامها في Android 9 (المستوى 28 من واجهة برمجة التطبيقات). يتضمّن نظام التشغيل Android 10 قوائم معدَّلة بواجهات غير حِزمات SDK المحظورة استنادًا إلى التعاون مع مطوّري تطبيقات Android وأحدث الاختبارات الداخلية. هدفنا هو التأكّد من توفّر بدائل عامة قبل أن نحظر الواجهات غير المتوفّرة في حزمة SDK.

إذا كنت لا تستهدف الإصدار 10 من نظام التشغيل Android (المستوى 29 من واجهة برمجة التطبيقات)، قد لا تؤثر بعض هذه التغييرات فيك على الفور. ومع ذلك، على الرغم من أنّه يمكنك حاليًا استخدام بعض الواجهات غير التابعة لحزمة SDK (حسب مستوى واجهة برمجة التطبيقات المستهدَف في تطبيقك)، فإنّ استخدام أي طريقة أو حقل غير تابع لحزمة SDK ينطوي دائمًا على خطر كبير بتعطُّل تطبيقك.

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

لمزيد من المعلومات، اطّلِع على التعديلات على القيود المفروضة على الواجهات غير المتوفّرة في حزمة SDK في نظام التشغيل Android 10 والقيود المفروضة على الواجهات غير المتوفّرة في حزمة SDK.

التنقُّل بالإيماءات

بدءًا من Android 10، يمكن للمستخدمين تفعيل ميزة "التنقّل بالإيماءات" على مستوى الجهاز. إذا فعّل المستخدم ميزة "التنقّل بالإيماءات"، سيؤثر ذلك في جميع التطبيقات على الجهاز، سواء كان التطبيق يستهدف المستوى 29 من واجهة برمجة التطبيقات أم لا. على سبيل المثال، إذا مرّر المستخدم سريعًا من حافة الشاشة، سيفسّر النظام هذه الإيماءة على أنّها إيماءة رجوع، ما لم يتجاهل أحد التطبيقات هذه الإيماءة تحديدًا في أجزاء من الشاشة.

لجعل تطبيقك متوافقًا مع ميزة "التنقّل بالإيماءات"، عليك توسيع نطاق محتوى التطبيق من الحافة إلى الحافة، والتعامل مع الإيماءات المتعارضة بشكل مناسب. لمزيد من المعلومات، يُرجى الاطّلاع على مستندات التنقّل بالإيماءات.

NDK

يتضمّن نظام التشغيل Android 10 تغييرات NDK التالية.

لا يمكن أن تحتوي الكائنات المشتركة على عمليات نقل نصية

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

يفرض SELinux هذا القيد على التطبيقات التي تستهدف الإصدار 10 من نظام التشغيل Android أو الإصدارات الأحدث. إذا استمرت هذه التطبيقات في استخدام عناصر مشترَكة تحتوي على عمليات نقل نصية، ستكون عرضة بشكل كبير للتوقّف عن العمل.

التغييرات على مكتبات Bionic ومسارات الرابط الديناميكي

اعتبارًا من نظام التشغيل Android 10، أصبحت العديد من المسارات عبارة عن روابط رمزية بدلاً من ملفات عادية. قد تتعطّل التطبيقات التي تعتمد على أن تكون المسارات ملفات عادية، وذلك للأسباب التالية:

  • /system/lib/libc.so -> /apex/com.android.runtime/lib/bionic/libc.so
  • /system/lib/libm.so -> /apex/com.android.runtime/lib/bionic/libm.so
  • /system/lib/libdl.so -> /apex/com.android.runtime/lib/bionic/libdl.so
  • /system/bin/linker -> /apex/com.android.runtime/bin/linker

تنطبق هذه التغييرات أيضًا على صيغ الملفات التي تعمل بنظام 64 بت، مع استبدال lib/ بـ lib64/.

لضمان التوافق، يتم توفير الروابط الرمزية في المسارات القديمة. على سبيل المثال، /system/lib/libc.so هو رابط رمزي إلى /apex/com.android.runtime/lib/bionic/libc.so. وبالتالي، سيستمر عمل dlopen(“/system/lib/libc.so”)، ولكن ستلاحظ التطبيقات الفرق عندما تحاول فحص المكتبات المحمَّلة من خلال قراءة /proc/self/maps أو ما شابه ذلك، وهو أمر غير معتاد، ولكن تبيّن لنا أنّ بعض التطبيقات تفعل ذلك كجزء من عملية مكافحة الاختراق. في هذه الحالة، يجب إضافة مسارات /apex/… كمسارات صالحة لملفات Bionic.

ملفات النظام الثنائية/مكتبات النظام التي تم ربطها بذاكرة التنفيذ فقط

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

يمكنك تحديد ما إذا كان هذا السلوك قد تسبّب في حدوث عُطل من خلال فحص ملف شواهد القبور ذي الصلة في /data/tombstones/. يحتوي عطل مرتبط بالتنفيذ فقط على رسالة الإيقاف التالية:

Cause: execute-only (no-read) memory access error; likely due to data in .text.

لحلّ هذه المشكلة وإجراء عمليات مثل فحص الذاكرة، يمكنك وضع علامة "قراءة+تنفيذ" على الأقسام التي يمكن تنفيذها فقط من خلال استدعاء mprotect(). ومع ذلك، ننصحك بشدة بإعادة ضبطه على execute-only بعد ذلك، لأنّ إعداد إذن الوصول هذا يوفّر حماية أفضل لتطبيقك ومستخدميه.

الأمان

يتضمّن نظام التشغيل Android 10 تغييرات الأمان التالية.

تفعيل الإصدار 1.3 من بروتوكول أمان طبقة النقل (TLS) تلقائيًا

في نظام التشغيل Android 10 والإصدارات الأحدث، يتم تفعيل بروتوكول TLS 1.3 تلقائيًا لجميع اتصالات TLS. في ما يلي بعض التفاصيل المهمة حول تنفيذنا لبروتوكول TLS 1.3:

  • لا يمكن تخصيص مجموعات رموز خوارزمية الترميز في بروتوكول أمان طبقة النقل (TLS) الإصدار 1.3. يتم دائمًا تفعيل مجموعات رموز خوارزمية الترميز المتوافقة مع الإصدار 1.3 من بروتوكول أمان طبقة النقل (TLS) عند تفعيل هذا الإصدار. ويتم تجاهل أي محاولة لإيقافها من خلال استدعاء setEnabledCipherSuites().
  • عند التفاوض على الإصدار 1.3 من بروتوكول أمان طبقة النقل (TLS)، يتم استدعاء عناصر HandshakeCompletedListener قبل إضافة الجلسات إلى ذاكرة التخزين المؤقت للجلسات. (في الإصدار 1.2 من بروتوكول TLS والإصدارات السابقة الأخرى، تُسمّى هذه العناصر بعد إضافة الجلسات إلى ذاكرة التخزين المؤقت للجلسات).
  • في بعض الحالات التي تعرض فيها مثيلات SSLEngine الخطأ SSLHandshakeException على إصدارات Android السابقة، تعرض هذه المثيلات الخطأ SSLProtocolException بدلاً من ذلك على نظام التشغيل Android 10 والإصدارات الأحدث.
  • وضع 0-RTT غير متاح.

إذا أردت الحصول على SSLContext تم إيقاف TLS 1.3 فيه، يمكنك الاتصال بالرقم SSLContext.getInstance("TLSv1.2"). يمكنك أيضًا تفعيل إصدارات البروتوكول أو إيقافها على أساس كل اتصال على حدة من خلال استدعاء setEnabledProtocols() على عنصر مناسب.

لا يتم الوثوق بالشهادات الموقَّعة باستخدام SHA-1 في بروتوكول أمان طبقة النقل (TLS)

في نظام التشغيل Android 10، لا يتم الوثوق بالشهادات التي تستخدم خوارزمية التجزئة SHA-1 في اتصالات بروتوكول أمان طبقة النقل (TLS). لم تصدر مراجع التصديق الجذر شهادات من هذا النوع منذ عام 2016، ولم تعُد موضع ثقة في Chrome أو غيره من المتصفحات الرئيسية.

ستفشل أي محاولة اتصال إذا كان الاتصال بموقع إلكتروني يعرض شهادة تستخدم SHA-1.

تغييرات وتحسينات في سلوك KeyChain

تتيح بعض المتصفّحات، مثل Google Chrome، للمستخدمين اختيار شهادة عندما يرسل خادم TLS رسالة طلب شهادة كجزء من تأكيد اتصال TLS. اعتبارًا من Android 10، تلتزم عناصر KeyChain بمعلمات المواصفات الخاصة بالجهات المصدرة والمفاتيح عند استدعاء KeyChain.choosePrivateKeyAlias() لعرض طلب من المستخدمين لاختيار شهادة. على وجه الخصوص، لا يحتوي هذا الطلب على خيارات لا تتوافق مع مواصفات الخادم.

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

بالإضافة إلى ذلك، ليس من الضروري على أجهزة Android 10 أو الإصدارات الأحدث قفل شاشة الجهاز لاستيراد المفاتيح أو شهادات مرجع التصديق إلى عنصر KeyChain.

تغييرات أخرى في بروتوكول أمان طبقة النقل (TLS) والتشفير

أجرينا عدة تغييرات طفيفة في مكتبات TLS والتشفير التي تسري على نظام التشغيل Android 10، وهي:

  • تعرض برامج التشفير AES/GCM/NoPadding وChaCha20/Poly1305/NoPadding أحجامًا أكثر دقة للمخزن المؤقت من getOutputSize().
  • يتم حذف مجموعة التشفير TLS_FALLBACK_SCSV من محاولات الاتصال التي تستخدم بروتوكولاً بحد أقصى 1.2 أو أعلى من TLS. بسبب التحسينات التي تم إجراؤها على عمليات تنفيذ خادم TLS، لا ننصح بمحاولة استخدام TLS الاحتياطي الخارجي. بدلاً من ذلك، ننصحك بالاعتماد على عملية التفاوض بشأن إصدار TLS.
  • ‫ChaCha20-Poly1305 هو اسم مستعار لـ ChaCha20/Poly1305/NoPadding.
  • لا تُعتبر أسماء المضيفين التي تتضمّن نقاطًا لاحقة أسماء مضيفين صالحة لبروتوكول SNI.
  • يتم احترام إضافة supported_signature_algorithms في CertificateRequest عند اختيار مفتاح توقيع لردود الشهادات.
  • يمكن استخدام مفاتيح التوقيع غير الشفافة، مثل تلك الواردة من "مخزن مفاتيح Android"، مع توقيعات RSA-PSS في بروتوكول أمان طبقة النقل (TLS).

عمليات البث عبر اتصال Wi-Fi المباشر

في نظام التشغيل Android 10، لا تكون عمليات البث التالية المرتبطة بخدمة Wi-Fi Direct ثابتة:

إذا كان تطبيقك يعتمد على تلقّي عمليات البث هذه عند التسجيل لأنّها كانت ثابتة، استخدِم طريقة get() المناسبة عند التهيئة للحصول على المعلومات بدلاً من ذلك.

إمكانات Wi-Fi Aware

يضيف نظام التشغيل Android 10 إمكانية تسهيل إنشاء مقبس TCP/UDP باستخدام مسارات بيانات Wi-Fi Aware. لإنشاء مقبس TCP/UDP يتصل بـ ServerSocket، يجب أن يعرف جهاز العميل عنوان IPv6 ومنفذ الخادم. كان يجب سابقًا إرسال هذه المعلومات خارج النطاق، مثلاً باستخدام رسائل الطبقة 2 في BT أو Wi-Fi Aware، أو اكتشافها داخل النطاق باستخدام بروتوكولات أخرى، مثل mDNS. في نظام التشغيل Android 10، يمكن إرسال المعلومات كجزء من عملية إعداد الشبكة.

يمكن للخادم تنفيذ أيّ من الإجراءات التالية:

  • ابدأ ServerSocket واضبط المنفذ الذي سيتم استخدامه أو احصل عليه.
  • حدِّد معلومات المنفذ كجزء من طلب شبكة Wi-Fi Aware.

يوضّح نموذج الرمز البرمجي التالي كيفية تحديد معلومات المنفذ كجزء من طلب الشبكة:

Kotlin

val ss = ServerSocket()
val ns = WifiAwareNetworkSpecifier.Builder(discoverySession, peerHandle)
  .setPskPassphrase("some-password")
  .setPort(ss.localPort)
  .build()

val myNetworkRequest = NetworkRequest.Builder()
  .addTransportType(NetworkCapabilities.TRANSPORT_WIFI_AWARE)
  .setNetworkSpecifier(ns)
  .build()

Java

ServerSocket ss = new ServerSocket();
WifiAwareNetworkSpecifier ns = new WifiAwareNetworkSpecifier
  .Builder(discoverySession, peerHandle)
  .setPskPassphrase(some-password)
  .setPort(ss.getLocalPort())
  .build();

NetworkRequest myNetworkRequest = new NetworkRequest.Builder()
  .addTransportType(NetworkCapabilities.TRANSPORT_WIFI_AWARE)
  .setNetworkSpecifier(ns)
  .build();

بعد ذلك، يرسل العميل طلب شبكة Wi-Fi Aware للحصول على عنوان IPv6 والمنفذ الذي يوفّره الخادم:

Kotlin

val callback = object : ConnectivityManager.NetworkCallback() {
  override fun onAvailable(network: Network) {
    ...
  }
  
  override fun onLinkPropertiesChanged(network: Network,
      linkProperties: LinkProperties) {
    ...
  }

  override fun onCapabilitiesChanged(network: Network,
      networkCapabilities: NetworkCapabilities) {
    ...
    val ti = networkCapabilities.transportInfo
    if (ti is WifiAwareNetworkInfo) {
       val peerAddress = ti.peerIpv6Addr
       val peerPort = ti.port
    }
  }
  override fun onLost(network: Network) {
    ...
  }
};

connMgr.requestNetwork(networkRequest, callback)

Java

callback = new ConnectivityManager.NetworkCallback() {
  @Override
  public void onAvailable(Network network) {
    ...
  }
  @Override
  public void onLinkPropertiesChanged(Network network,
      LinkProperties linkProperties) {
    ...
  }
  @Override
  public void onCapabilitiesChanged(Network network,
      NetworkCapabilities networkCapabilities) {
    ...
    TransportInfo ti = networkCapabilities.getTransportInfo();
    if (ti instanceof WifiAwareNetworkInfo) {
       WifiAwareNetworkInfo info = (WifiAwareNetworkInfo) ti;
       Inet6Address peerAddress = info.getPeerIpv6Addr();
       int peerPort = info.getPort();
    }
  }
  @Override
  public void onLost(Network network) {
    ...
  }
};

connMgr.requestNetwork(networkRequest, callback);

SYSTEM_ALERT_WINDOW على أجهزة Go

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

إذا تلقّى تطبيق يعمل على جهاز Go edition يعمل بالإصدار 9 من نظام التشغيل Android أو إصدار أقدم الإذن SYSTEM_ALERT_WINDOW، يحتفظ التطبيق بالإذن حتى إذا تمت ترقية الجهاز إلى الإصدار 10 من نظام التشغيل Android. ومع ذلك، لا يمكن منح التطبيقات التي لا تملك هذا الإذن بعد ترقية الجهاز.

إذا أرسل تطبيق على جهاز Go غرضًا يتضمّن الإجراء ACTION_MANAGE_OVERLAY_PERMISSION، سيرفض النظام الطلب تلقائيًا، وسينقل المستخدم إلى شاشة الإعدادات التي توضّح أنّه لا يُسمح بمنح الإذن لأنّه يبطئ الجهاز. إذا طلب تطبيق على جهاز Go Settings.canDrawOverlays()، ستعرض الطريقة القيمة "خطأ" دائمًا. مرة أخرى، لا تنطبق هذه القيود على التطبيقات التي حصلت على إذن SYSTEM_ALERT_WINDOW قبل ترقية الجهاز إلى نظام التشغيل Android 10.

تحذيرات بشأن التطبيقات التي تستهدف إصدارات Android القديمة

تعرض الأجهزة التي تعمل بالإصدار 10 من نظام التشغيل Android أو الإصدارات الأحدث تحذيرًا للمستخدمين في المرة الأولى التي يشغّلون فيها أي تطبيق يستهدف الإصدار 5.1 من نظام التشغيل Android (المستوى 22 لواجهة برمجة التطبيقات) أو الإصدارات الأقدم. إذا كان التطبيق يتطلّب من المستخدم منح أذونات، سيُمنح المستخدم أيضًا فرصة لتعديل أذونات التطبيق قبل السماح بتشغيله للمرة الأولى.

بسبب متطلبات مستوى واجهة برمجة التطبيقات المستهدَف في Google Play، لا تظهر هذه التحذيرات للمستخدم إلا عند تشغيل تطبيق لم يتم تحديثه مؤخرًا. بالنسبة إلى التطبيقات التي يتم توزيعها من خلال متاجر أخرى، سيتم تطبيق متطلبات مماثلة لمستوى واجهة برمجة التطبيقات المستهدف خلال عام 2019. لمزيد من المعلومات حول هذه المتطلبات، يُرجى الاطّلاع على مقالة توسيع نطاق متطلبات مستوى واجهة برمجة التطبيقات المستهدَف في 2019.

إزالة مجموعات رموز خوارزمية الترميز SHA-2 CBC

تمت إزالة مجموعات التشفير التالية SHA-2 CBC من المنصة:

  • TLS_RSA_WITH_AES_128_CBC_SHA256
  • TLS_RSA_WITH_AES_256_CBC_SHA256
  • TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256
  • TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384
  • TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256
  • TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384

تكون مجموعات الرموز هذه أقل أمانًا من مجموعات الرموز المشابهة التي تستخدم وضع GCM، ومعظم الخوادم إما تتيح كلا النوعين من مجموعات الرموز هذه (GCM وCBC) أو لا تتيح أيًا منهما.

استخدام التطبيق

يقدّم نظام التشغيل Android 10 تغييرات السلوك التالية المتعلّقة باستخدام التطبيقات:

  • تحسينات على استخدام تطبيق UsageStats: <0x0A بالإضافة إلى ذلك، يتتبّع نظام التشغيل Android 10 استخدام التطبيقات الفورية بشكل صحيح.

  • تدرّج الرمادي لكل تطبيق: <0x

  • حالة عدم الإزعاج لكل تطبيق: يمكن لنظام التشغيل Android 10 ضبط التطبيقات بشكل انتقائي على "حالة عدم الإزعاج"، ما يؤدي إلى إيقاف إشعاراتها وعدم ظهورها كتطبيقات مقترَحة.

  • التعليق والتشغيل: في نظام التشغيل Android 10، لا يمكن للتطبيقات المعلّقة تشغيل الصوت.

تغييرات في الاتصال عبر HTTPS

إذا مرّر تطبيق يعمل بنظام التشغيل Android 10 القيمة null إلى setSSLSocketFactory()، سيحدث IllegalArgumentException. في الإصدارات السابقة، كان تمرير null إلى setSSLSocketFactory() له التأثير نفسه كما هو الحال عند تمرير المصنع الافتراضي الحالي.

تم إيقاف مكتبة android.preference نهائيًا

توقّفنا نهائيًا عن دعم مكتبة android.preference اعتبارًا من نظام التشغيل Android 10. على المطوّرين استخدام مكتبة الإعدادات المفضّلة في AndroidX، وهي جزء من Android Jetpack. للحصول على مراجع إضافية تساعدك في عملية نقل البيانات والتطوير، يمكنك الاطّلاع على دليل الإعدادات المعدَّل بالإضافة إلى تطبيق العيّنة المتاح للجميع والمستندات المرجعية.

التغييرات في مكتبة أدوات ملفات ZIP

يُدخل نظام التشغيل Android 10 التغييرات التالية على الفئات في حزمة java.util.zip التي تتعامل مع ملفات ZIP. تؤدي هذه التغييرات إلى جعل سلوك المكتبة أكثر اتساقًا بين نظام التشغيل Android والأنظمة الأساسية الأخرى التي تستخدم java.util.zip.

المنفاخ

في الإصدارات السابقة، كانت بعض الطرق في الفئة Inflater تعرض الخطأ IllegalStateException إذا تم استدعاؤها بعد استدعاء end(). في نظام التشغيل Android 10، تعرض هاتان الطريقتان الخطأ NullPointerException بدلاً من ذلك.

ZipFile

في نظام التشغيل Android 10 والإصدارات الأحدث، لا يعرض المنشئ الخاص بـ ZipFile الذي يتلقّى وسيطات من النوع File وint وCharset الخطأ ZipException إذا كان ملف ZIP المقدَّم لا يحتوي على أي ملفات.

ZipOutputStream

في نظام التشغيل Android 10 والإصدارات الأحدث، لا يعرض الأسلوب finish() في ZipOutputStream الخطأ ZipException إذا حاول كتابة دفق إخراج لملف ZIP لا يحتوي على أي ملفات.

تغييرات الكاميرا

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

يجب أن تحدّد التطبيقات التي تستهدف المستوى 24 أو أعلى لواجهة برمجة التطبيقات قيمة android:resizeableActivity بشكل صريح وأن توفّر الوظائف اللازمة للتعامل مع تشغيل النوافذ المتعددة.

تتبُّع استخدام البطارية

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

قبل الإصدار 10 من نظام التشغيل Android، كانت تتم إعادة ضبط إحصاءات استخدام البطارية كلما تم فصل الجهاز عن الشاحن، بغض النظر عن مقدار التغيير في مستوى شحن البطارية.

إيقاف ميزة Android Beam

في نظام التشغيل Android 10، سنوقف نهائيًا ميزة Android Beam القديمة التي تتيح بدء مشاركة البيانات بين الأجهزة من خلال تقنية الاتصال القصير المدى (NFC). سنوقف أيضًا نهائيًا العديد من واجهات برمجة التطبيقات ذات الصلة بتكنولوجيا NFC. ستبقى ميزة Android Beam متاحة بشكل اختياري لشركاء مصنّعي الأجهزة الذين يريدون استخدامها، ولكن لم يعُد يتم تطويرها بشكل نشط. سيواصل نظام التشغيل Android توفير إمكانات وواجهات برمجة تطبيقات أخرى خاصة بتقنية NFC، وسيستمر عمل حالات الاستخدام، مثل القراءة من العلامات والدفع، على النحو المتوقّع.

تغيير في سلوك java.math.BigDecimal.stripTrailingZeros()

لم تعُد الدالة BigDecimal.stripTrailingZeros() تحتفظ بالأصفار اللاحقة كحالة خاصة إذا كانت قيمة الإدخال صفرًا.

تغييرات في سلوك java.util.regex.Matcher وPattern

تم تغيير نتيجة split() لكي لا تبدأ بعد الآن بـ String فارغ ("") عندما يكون هناك تطابق بعرض صفر في بداية الإدخال. يؤثّر ذلك أيضًا في String.split(). على سبيل المثال، تعرض السمة "x".split("") الآن القيمة {"x"} بينما كانت تعرض القيمة {"", "x"} في الإصدارات القديمة من Android. تعرض "aardvark".split("(?=a)" الآن {"a", "ardv", "ark"} بدلاً من {"", "a", "ardv", "ark"}.

تم أيضًا تحسين سلوك الاستثناء للوسيطات غير الصالحة:

  • يُظهر appendReplacement(StringBuffer, String) الآن الخطأ IllegalArgumentException بدلاً من IndexOutOfBoundsException إذا انتهى String البديل بشرطة مائلة عكسية منفردة، وهو أمر غير مسموح به. يتم الآن عرض الاستثناء نفسه إذا انتهى النص البديل String بالحرف $. في السابق، لم يكن يتم عرض أي استثناء في هذا السيناريو.
  • لم يعُد replaceFirst(null) يستدعي reset() على Matcher إذا ظهر الخطأ NullPointerException. يتم الآن أيضًا عرض الخطأ NullPointerException عند عدم العثور على تطابق. في السابق، كان يتم عرض هذا الخطأ فقط عند العثور على تطابق.
  • تعرض الآن start(int group) وend(int group) وgroup(int group) الخطأ IndexOutOfBoundsException الأكثر عمومية إذا كان فهرس المجموعة خارج النطاق. في السابق، كانت هذه الطرق تعرض ArrayIndexOutOfBoundsException.

أصبحت الزاوية التلقائية لـ GradientDrawable هي TOP_BOTTOM

في نظام التشغيل Android 10، إذا حدّدت GradientDrawable في XML ولم تقدّم قياس زاوية، سيتم تلقائيًا ضبط اتجاه التدرّج اللوني على TOP_BOTTOM. هذا تغيير عن إصدارات Android السابقة التي كان الخيار التلقائي فيها هو LEFT_RIGHT.

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

تسجيل الكائنات المتسلسلة باستخدام SUID التلقائي

بدءًا من الإصدار 7.0 من نظام التشغيل Android (المستوى 24 لواجهة برمجة التطبيقات)، أجرى النظام الأساسي إصلاحًا للقيمة التلقائية serialVersionUID الخاصة بالكائنات القابلة للتسلسل. لم يؤثّر هذا الإصلاح في التطبيقات التي تستهدف المستوى 23 أو أقل من واجهة برمجة التطبيقات.

اعتبارًا من Android 10، إذا كان التطبيق يستهدف المستوى 23 أو أقل لواجهة برمجة التطبيقات ويعتمد على القيمة التلقائية القديمة وغير الصحيحة serialVersionUID، سيسجّل النظام تحذيرًا ويقترح إصلاحًا للرمز.

على وجه التحديد، يسجّل النظام تحذيرًا في حال استيفاء جميع الشروط التالية:

  • يستهدف التطبيق المستوى 23 أو أقل لواجهة برمجة التطبيقات.
  • يتم تسلسل فئة.
  • تستخدم الفئة المتسلسلة serialVersionUID التلقائية بدلاً من ضبط serialVersionUID بشكل صريح.
  • يختلف الإعداد التلقائي serialVersionUID عن الإعداد serialVersionUID الذي سيتم استخدامه إذا كان التطبيق يستهدف المستوى 24 أو مستوى أحدث لواجهة برمجة التطبيقات.

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

التغييرات في java.io.FileChannel.map()

اعتبارًا من نظام التشغيل Android 10، لن يكون تنسيق FileChannel.map() متاحًا للملفات غير العادية، مثل /dev/zero، التي لا يمكن تغيير حجمها باستخدام truncate(). كانت الإصدارات السابقة من Android تتجاهل رقم الخطأ الذي تعرضه truncate()، ولكن يعرض Android 10 IOException. إذا كنت بحاجة إلى السلوك القديم، عليك استخدام الرمز البرمجي الأصلي.