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

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

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

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

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

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

قيود الواجهة غير المتوفرة في حزمة تطوير البرامج (SDK)

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

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

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

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

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

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

لجعل تطبيقك متوافقًا مع التنقل بالإيماءات، ستحتاج إلى توسيع محتوى التطبيق من الحافة إلى الحافة، والتعامل مع الإيماءات المتعارضة بشكل مناسب. للحصول على معلومات، راجع وثائق التنقل بالإيماءات.

العُقدة (NDK)

يتضمّن Android 10 التغييرات التالية على NDK.

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

Android 6.0 (المستوى 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 إلى تطبيقك.

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

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

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

الأمان

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

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

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

  • لا يمكن تخصيص مجموعات رموز طبقة النقل الآمنة (TLS) الإصدار 1.3. دائمًا ما يتم تفعيل مجموعات تشفير بروتوكول أمان طبقة النقل (TLS) الإصدار 1.3 عند تفعيل الإصدار 1.3. ويتم تجاهل أي محاولة لإيقافها من خلال طلب setEnabledCipherSuites().
  • عند التفاوض من الإصدار 1.3 من بروتوكول أمان طبقة النقل (TLS)، يتم استدعاء كائنات HandshakeCompletedListener قبل إضافة الجلسات إلى ذاكرة التخزين المؤقت للجلسة. (في بروتوكول أمان طبقة النقل (TLS) الإصدار 1.2 والإصدارات السابقة الأخرى، يتم استدعاء هذه الكائنات بعد إضافة الجلسات إلى ذاكرة التخزين المؤقت للجلسة).
  • في بعض الحالات التي تعرض فيها مثيلات 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 أو الإصدارات الأحدث لاستيراد المفاتيح أو شهادات CA إلى عنصر KeyChain.

التغييرات الأخرى المتعلّقة ببروتوكول أمان طبقة النقل والتشفير

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

  • يعرض رموز AES/GCM/NoPadding وChaCha20/Poly1305/NoPadding أحجامًا أكثر دقة للمخزن المؤقت من getOutputSize().
  • يتم حذف مجموعة ترميز TLS_FALLBACK_SCSV من محاولات الاتصال باستخدام بروتوكول أمان طبقة النقل (TLS) 1.2 أو أعلى. لا ننصح بتجربة الإجراء الاحتياطي الخارجي لبروتوكول أمان طبقة النقل (TLS)، وذلك بسبب التحسينات التي تم إجراؤها في عمليات تنفيذ خادم بروتوكول أمان طبقة النقل (TLS). بدلاً من ذلك، ننصحك بالاعتماد على التفاوض على إصدار بروتوكول أمان طبقة النقل (TLS).
  • ChaCha20-Poly1305 هو اسم مستعار لـ ChaCha20/Poly1305/NoPadding.
  • لا تُعتبَر أسماء المضيفين التي تتضمّن نقاطًا لاحقة أسماء مضيفين صالحة لإشارة اسم الخادم (SNI).
  • يجب الالتزام بالإضافة المدعومة_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 ومنفذ الخادم. كان يجب في السابق إرسال ذلك خارج النطاق، مثلاً عن طريق استخدام إرسال BT أو Wi-Fi Aware من الطبقة 2، أو رصده في النطاق باستخدام بروتوكولات أخرى، مثل 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 ذات الذاكرة المنخفضة.

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

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

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

وتحذّر الأجهزة التي تعمل بنظام التشغيل Android 10 أو الإصدارات الأحدث المستخدمين في المرة الأولى التي تشغِّل فيها أي تطبيق يستهدف Android 5.1 (المستوى 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 تغييرات السلوك التالية المتعلّقة باستخدام التطبيق:

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

  • تدرّج الرمادي حسب التطبيق - ضبط إعدادات Android

  • حالة الإلهاء حسب التطبيق -

  • التعليق والتشغيل -

تغييرات في اتصال 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 بدلاً من ذلك.

ملف Zip

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

مصدر البيانات ZipوثStream

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

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

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

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

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

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

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

إيقاف ميزة "شعاع Android" نهائيًا

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

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

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

التغييرات في سلوك java.util.regex.Matcher والأنماط

تم تغيير نتيجة 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.

أصبحت الزاوية التلقائية لـ GRadentDrawable الآن TOP_BOTTOM

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

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

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

بدءًا من Android 7.0 (المستوى 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. إذا كنت بحاجة إلى السلوك القديم، فيجب عليك استخدام التعليمات البرمجية الأصلية.