الممارسات المقترَحة

تطبيقات للأجهزة القابلة للطي والأجهزة المتعددة الشاشات

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

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

تقييد الوصول إلى الشاشات

إذا كان إعداد الجهاز يتطلّب حظر الوصول إلى شاشة عرض واحدة أو أكثر، ننصحك باستخدام العلامة Display#FLAG_PRIVATE لتحديد شاشات العرض هذه على أنّها خاصة. سيؤدي ذلك إلى منع أي مستخدم آخر غير المالك من إضافة محتوى إلى الشاشة. سيؤدي أي محاولة لتشغيل نشاط أو إضافة نافذة من قِبل أي شخص آخر غير المالك إلى ظهور SecurityException. إذا كان النظام يملك شاشة العرض، يمكنه إضافة نوافذ وبدء الأنشطة.

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

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

لمزيد من المعلومات، يرجى الاطّلاع على:

  • ActivityStackSupervisor#isCallerAllowedToLaunchOnDisplay()
  • ActivityDisplay#isUidPresent()
  • DisplayManagerService#isUidPresentOnDisplay()

للتحكّم بشكل مشروط في عمليات بدء الأنشطة، استخدِم LaunchParamsController، الذي يعترض جميع عمليات بدء الأنشطة ويسمح لأحد مكونات النظام بتعديل المَعلمات المستخدَمة في عملية البدء. تتوفّر هذه الميزة في system_server.

ضبط إعدادات عرض النوافذ وزخارف النظام

يمكن ضبط عناصر واجهة النظام لكل شاشة عرض في DisplayWindowSettings. يمكن أن يوفّر تنفيذ الجهاز إعدادات تلقائية في /data/system/display_settings.xml.

تحدّد هذه القيمة ما إذا كانت عناصر تزيين النظام (مشغّل التطبيقات والخلفية وشريط التنقّل ونوافذ التزيين الأخرى) وأداة IME ستظهر على الشاشة. لمزيد من التفاصيل، يُرجى الاطّلاع على DisplayWindowSettings#shouldShowSystemDecorsLocked() وDisplayWindowSettings#shouldShowImeLocked().

لتحديد الشاشة، استخدِم إما معرّفًا فريدًا (يستخدم هذا الإعداد التلقائي DisplayInfo#uniqueId) أو معرّف منفذ مادي لشاشات الأجهزة (راجِع DisplayInfo#address).

على سبيل المثال، يتيح نموذج إعدادات العرض التالي عناصر تزيين النظام وأداة IME على شاشة محاكاة:

<?xml version='1.0' encoding='utf-8' standalone='yes' ?>
<display-settings>
<config identifier="0" />
<display
  name="overlay:1"
  shouldShowSystemDecors="true"
  shouldShowIme="true" />
</display-settings>

في المثال أعلاه، يتم استخدام uniqueId لتحديد العرض في سمة الاسم، والتي تكون overlay:1 بالنسبة إلى العرض المحاكى. بالنسبة إلى شاشة العرض المضمّنة، قد تكون قيمة العيّنة "local:45354385242535243453". يمكنك أيضًا استخدام معلومات منفذ الجهاز وتعيين identifier="1" ليتوافق مع DisplayWindowSettings#IDENTIFIER_PORT، ثم تعديل الاسم لاستخدام التنسيق "port:<port_id>":

<?xmlversion='1.0' encoding='utf-8' standalone='yes' ?>
<display-settings>
<config identifier="1" />
<display
  name="port:12345"
  shouldShowSystemDecors="true"
  shouldShowIme="true" />
</display-settings>

لمزيد من التفاصيل، اطّلِع على معرّفات العرض الثابتة.

لمزيد من المعلومات، يرجى الاطّلاع على:

التبديل بين عرض الشاشة ومشاركة المهام

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

عند توفّر FLAG_ALLOWS_CONTENT_MODE_SWITCH، يراقب DisplayManager إعداد الأمان android.provider.Settings.Secure.MIRROR_BUILT_IN_DISPLAY لتحديد ما إذا كان سيتم عرض المحتوى على شاشة أخرى أو استضافة المهام. على الرغم من أنّ هذا هو المنطق التلقائي، يمكن لمصنّعي المعدات الأصلية تخصيص هذا السلوك.

عرض الطوبولوجيا وحركة المؤشر

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

يقرّر WindowManager تضمين شاشة في التصميم ويطلب DisplayManagerInternal.onDisplayBelongToTopologyChanged. تتحقّق الفئة DisplayManager من DisplayTopologyCoordinator.isDisplayAllowedInTopology قبل إضافة الشاشة. بشكلٍ تلقائي، إذا كانت الشاشات المحلية يمكنها استضافة المهام، يضيفها النظام.

إذا كانت هناك شاشات عرض عامة متعددة يمكنها استضافة المهام، يتم اتخاذ قرار تضمين شاشة العرض التلقائية من خلال موفّر القيمة المنطقية shouldIncludeDefaultDisplayInTopology الذي يتم تمريره إلى DisplayTopologyCoordinator. إذا كانت الشاشة التلقائية هي الشاشة العامة الوحيدة التي يمكنها استضافة المهام، ستكون دائمًا في المخطط. في AOSP، لا يعرض موفّر القيم المنطقية القيمة true إلا إذا كانت الشاشة التلقائية تتيح ميزة "العرض في نافذة" أو إذا كان الإعداد الآمن Settings.Secure.INCLUDE_DEFAULT_DISPLAY_IN_TOPOLOGY مضبوطًا على true.

تستعلم التطبيقات عن البنية الحالية باستخدام DisplayManager.getDisplayTopology وتتفاعل مع التغييرات التي تطرأ على البنية من خلال تسجيل أداة معالجة باستخدام DisplayManager.registerTopologyListener.