सिस्टम की सजावट से जुड़ी सहायता

डिसप्ले के हिसाब से इन सेटिंग में किए गए अपडेट यहां दिए गए हैं:

सिस्टम की सजावट

Android 10 में, सेकंडरी डिसप्ले को कॉन्फ़िगर करने की सुविधा जोड़ी गई है. इससे, सिस्टम के कुछ डेकोरेशन, जैसे कि वॉलपेपर, नेविगेशन बार, और लॉन्चर दिखाए जा सकते हैं. डिफ़ॉल्ट रूप से, मुख्य डिसप्ले पर सिस्टम के सभी डेकोरेशन दिखते हैं. वहीं, वैकल्पिक तौर पर चालू किए गए डेकोरेशन, सेकंडरी डिसप्ले पर दिखते हैं. इनपुट के तरीके के संपादक (आईएमई) के लिए सहायता को, सिस्टम के अन्य डेकोरेशन से अलग सेट किया जा सकता है.

किसी डिसप्ले पर सिस्टम डेकोरेशन की सुविधा जोड़ने के लिए DisplayWindowSettings#setShouldShowSystemDecorsLocked() का इस्तेमाल करें या /data/system/display_settings.xml में डिफ़ॉल्ट वैल्यू दें. उदाहरण के लिए, डिसप्ले विंडो की सेटिंग देखें.

लागू करना

DisplayWindowSettings#setShouldShowSystemDecorsLocked() को जांच के लिए, WindowManager#setShouldShowSystemDecors() में भी दिखाया जाता है. सिस्टम डेकोर चालू करने के मकसद से इस तरीके को ट्रिगर करने पर, पहले मौजूद न होने वाली डेकोर विंडो नहीं जोड़ी जाती हैं. अगर वे पहले मौजूद थीं, तो उन्हें हटाया भी नहीं जाता. ज़्यादातर मामलों में, डिवाइस को रीबूट करने के बाद ही सिस्टम डेकोरेशन की सुविधा में किया गया बदलाव पूरी तरह से लागू होता है.

WindowManager कोड बेस में सिस्टम डेकोरेशन के काम करने की जांच, आम तौर पर DisplayContent#supportsSystemDecorations() के ज़रिए की जाती है. वहीं, बाहरी सेवाओं की जांच (जैसे, नेविगेशन बार दिखाया जाना चाहिए या नहीं, यह जांचने के लिए सिस्टम यूज़र इंटरफ़ेस) के लिए WindowManager#shouldShowSystemDecors() का इस्तेमाल किया जाता है. यह समझने के लिए कि इस सेटिंग से क्या कंट्रोल किया जाता है, इन तरीकों के कॉल पॉइंट एक्सप्लोर करें.

सिस्टम यूज़र इंटरफ़ेस (यूआई) की सजावट वाली विंडो

Android 10 में, सिस्टम डेकोर विंडो की सुविधा सिर्फ़ नेविगेशन बार के लिए जोड़ी गई है. इसकी वजह यह है कि गतिविधियों और ऐप्लिकेशन के बीच नेविगेट करने के लिए, नेविगेशन बार ज़रूरी है. डिफ़ॉल्ट रूप से, नेविगेशन बार में 'वापस जाएं' और 'होम' सुविधाएं दिखती हैं. इसे सिर्फ़ तब शामिल किया जाता है, जब टारगेट डिसप्ले में सिस्टम डेकोरेशन की सुविधा काम करती हो (DisplayWindowSettings देखें).

स्टेटस बार एक ज़्यादा जटिल सिस्टम विंडो है, क्योंकि इसमें सूचना शेड, क्विक सेटिंग, और लॉक स्क्रीन भी शामिल है. Android 10 में, सेकंडरी डिसप्ले पर स्टेटस बार काम नहीं करता. इसलिए, सूचनाएं, सेटिंग, और पूरा की-गार्ड सिर्फ़ मुख्य डिसप्ले पर उपलब्ध होता है.

खास जानकारी/हाल ही में इस्तेमाल किए गए सिस्टम विंडो, सेकंडरी स्क्रीन पर काम नहीं करती. Android 10 में, AOSP सिर्फ़ डिफ़ॉल्ट डिसप्ले पर हाल ही की गतिविधियां दिखाता है. साथ ही, इसमें सभी डिसप्ले की गतिविधियां शामिल होती हैं. हाल ही में इस्तेमाल किए गए ऐप्लिकेशन से किसी ऐप्लिकेशन को लॉन्च करने पर, सेकंडरी डिसप्ले पर मौजूद गतिविधि को डिफ़ॉल्ट रूप से उस डिसप्ले पर आगे लाया जाता है. इस तरीके से कुछ समस्याएं आती हैं. जैसे, ऐप्लिकेशन दूसरी स्क्रीन पर दिखने पर, तुरंत अपडेट न होना.

लागू करना

सिस्टम यूज़र इंटरफ़ेस (यूआई) की अन्य सुविधाओं को लागू करने के लिए, डिवाइस बनाने वाली कंपनियों को एक ही सिस्टम यूज़र इंटरफ़ेस कॉम्पोनेंट का इस्तेमाल करना चाहिए. यह कॉम्पोनेंट, डिसप्ले जोड़ने/हटाने के लिए सुनता है और सही कॉन्टेंट दिखाता है.

मल्टी-डिसप्ले (एमडी) की सुविधा के साथ काम करने वाले सिस्टम यूज़र इंटरफ़ेस (यूआई) कॉम्पोनेंट को इन मामलों में काम करना चाहिए:

  • डिवाइस के चालू होने पर, एक से ज़्यादा डिसप्ले को शुरू करना
  • रनटाइम के दौरान जोड़ा गया डिसप्ले
  • रनटाइम के दौरान डिसप्ले हटाना

जब System UI, WindowManager से पहले किसी डिसप्ले के जुड़ने का पता लगाता है, तो यह रेस कंडीशन बनाता है. डिसप्ले जोड़ने पर, DisplayManager.DisplayListener इवेंट की सदस्यता लेने के बजाय, WindowManager से सिस्टम यूज़र इंटरफ़ेस (यूआई) में कस्टम कॉलबैक लागू करके, इस समस्या से बचा जा सकता है. लागू करने के बारे में रेफ़रंस के लिए, नेविगेशन बार के लिए CommandQueue.Callbacks#onDisplayReady और वॉलपेपर के लिए WallpaperManagerInternal#onDisplayReady देखें.

इसके अलावा, Android 10 में ये अपडेट भी शामिल हैं:

  • NavigationBarController क्लास, नेविगेशन बार से जुड़ी सभी सुविधाओं को कंट्रोल करती है.
  • पसंद के मुताबिक बनाया गया नेविगेशन बार देखने के लिए, CarStatusBar देखें.
  • TYPE_NAVIGATION_BAR अब सिर्फ़ एक उदाहरण तक सीमित नहीं है और इसका इस्तेमाल हर डिसप्ले के लिए किया जा सकता है.
  • IWindowManager#hasNavigationBar() को अपडेट किया गया है, ताकि सिर्फ़ सिस्टम यूज़र इंटरफ़ेस (यूआई) के लिए displayId पैरामीटर शामिल किया जा सके.

लॉन्चर

Android 10 में, सिस्टम डेकोरेशन के साथ काम करने के लिए कॉन्फ़िगर किए गए हर डिसप्ले में, डिफ़ॉल्ट रूप से WindowConfiguration#ACTIVITY_TYPE_HOME टाइप के लॉन्चर गतिविधियों के लिए एक खास होम स्टैक होता है. हर डिसप्ले, लॉन्चर गतिविधि के अलग इंस्टेंस का इस्तेमाल करता है.

पहली इमेज. platform/development/samples/MultiDisplay के लिए मल्टी-डिसप्ले लॉन्चर का उदाहरण

ज़्यादातर मौजूदा लॉन्चर, एक से ज़्यादा इंस्टेंस के साथ काम नहीं करते. साथ ही, ये बड़ी स्क्रीन के साइज़ के लिए ऑप्टिमाइज़ नहीं किए गए हैं. साथ ही, सेकंडरी/बाहरी डिसप्ले पर अक्सर अलग तरह का अनुभव मिलता है. सेकंडरी स्क्रीन के लिए खास गतिविधि उपलब्ध कराने के लिए, Android 10 में इंटेंट फ़िल्टर में SECONDARY_HOME कैटगरी को शामिल किया गया है. इस गतिविधि के इंस्टेंस का इस्तेमाल, सिस्टम के डिसप्ले पर सजावट की सुविधा के साथ काम करने वाले सभी डिसप्ले पर किया जाता है. हर डिसप्ले पर एक इंस्टेंस.

<activity>
    ...
    <intent-filter>
        <category android:name="android.intent.category.SECONDARY_HOME" />
        ...
    </intent-filter>
</activity>

गतिविधि का लॉन्च मोड ऐसा होना चाहिए जो एक से ज़्यादा इंस्टेंस को रोके और अलग-अलग स्क्रीन साइज़ के हिसाब से अडजस्ट हो सके. लॉन्च मोड singleInstance या singleTask नहीं हो सकता.

लागू करना

Android 10 में, RootActivityContainer#startHomeOnDisplay() होम स्क्रीन को लॉन्च करने वाले डिसप्ले के हिसाब से, मनचाहा कॉम्पोनेंट और इंटेंट अपने-आप चुनता है. RootActivityContainer#resolveSecondaryHomeActivity() में, लॉन्चर ऐक्टिविटी कॉम्पोनेंट को देखने का लॉजिक होता है. यह लॉजिक, फ़िलहाल चुने गए लॉन्चर के आधार पर काम करता है. साथ ही, ज़रूरत पड़ने पर सिस्टम के डिफ़ॉल्ट लॉन्चर का इस्तेमाल कर सकता है (ActivityTaskManagerService#getSecondaryHomeIntent() देखें).

सुरक्षा से जुड़ी पाबंदियां

सेकंडरी डिसप्ले पर की जाने वाली गतिविधियों पर लागू होने वाली पाबंदियों के अलावा, लॉन्चर सिर्फ़ उन वर्चुअल डिसप्ले पर दिखता है जिनका मालिकाना हक सिस्टम के पास होता है. ऐसा इसलिए किया जाता है, ताकि कोई नुकसान पहुंचाने वाला ऐप्लिकेशन, सिस्टम डेकोरेशन की सुविधा चालू करके वर्चुअल डिसप्ले न बना पाए और उस पर उपयोगकर्ता की संवेदनशील जानकारी न पढ़ पाए. लॉन्चर, सिस्टम के अलावा किसी दूसरे वर्चुअल डिसप्ले पर कॉन्टेंट नहीं दिखाता.

वॉलपेपर बदलने के लिए ऐप्लिकेशन

Android 10 और उसके बाद के वर्शन में, सेकंडरी डिसप्ले पर वॉलपेपर इस्तेमाल किए जा सकते हैं:

दूसरी इमेज. डिवाइस के अंदर (ऊपर) और बाहर (नीचे) मौजूद डिसप्ले पर लाइव वॉलपेपर

डेवलपर, वॉलपेपर की सुविधा के साथ काम करने की जानकारी दे सकते हैं. इसके लिए, उन्हें WallpaperInfo एक्सएमएल डेफ़िनिशन में android:supportsMultipleDisplays="true" देना होगा. वॉलपेपर डेवलपर को भी WallpaperService.Engine#getDisplayContext() में डिसप्ले कॉन्टेक्स्ट का इस्तेमाल करके ऐसेट लोड करनी चाहिए.

फ़्रेमवर्क, हर डिसप्ले के लिए एक WallpaperService.Engine इंस्टेंस बनाता है. इसलिए, हर इंजन का अपना प्लैटफ़ॉर्म और डिसप्ले कॉन्टेक्स्ट होता है. डेवलपर को यह पक्का करना होगा कि हर इंजन, अलग-अलग फ़्रेम रेट पर, VSYNC का पालन करते हुए, अपने-आप ड्रॉ हो सकता है.

अलग-अलग स्क्रीन के लिए वॉलपेपर चुनना

Android 10 में, अलग-अलग स्क्रीन के लिए वॉलपेपर चुनने की सुविधा सीधे तौर पर उपलब्ध नहीं है. ऐसा करने के लिए, हर डिसप्ले के लिए वॉलपेपर की सेटिंग को सेव रखने के लिए, एक स्थिर डिसप्ले आइडेंटिफ़ायर की ज़रूरत होती है. Display#getDisplayId() डाइनैमिक होता है. इसलिए, इस बात की कोई गारंटी नहीं है कि रीबूट करने के बाद, किसी फ़िज़िकल डिसप्ले का आईडी वही रहेगा.

हालांकि, Android 10 में DisplayInfo.mAddress जोड़ा गया है. इसमें फ़िज़िकल डिसप्ले के लिए स्थिर आइडेंटिफ़ायर शामिल हैं. आने वाले समय में, इसका इस्तेमाल पूरी तरह से लागू करने के लिए किया जा सकता है. माफ़ करें, Android 10 के लिए लॉजिक लागू करने का समय निकल चुका है. सुझाया गया समाधान:

  1. वॉलपेपर सेट करने के लिए, WallpaperManager API का इस्तेमाल करें.
  2. WallpaperManager को Context ऑब्जेक्ट से पाया जाता है. साथ ही, हर Context ऑब्जेक्ट में, उससे जुड़े डिसप्ले (Context#getDisplay()/getDisplayId()) के बारे में जानकारी होती है. इसलिए, नए तरीके जोड़े बिना, WallpaperManager इंस्टेंस से displayId पाया जा सकता है.
  3. फ़्रेमवर्क की ओर से, Context ऑब्जेक्ट से मिले displayId का इस्तेमाल करें और उसे किसी स्टैटिक आइडेंटिफ़ायर (जैसे, किसी फ़िज़िकल डिसप्ले का पोर्ट) पर मैप करें. चुने गए वॉलपेपर को सेव करने के लिए, स्टैटिक आइडेंटिफ़ायर का इस्तेमाल करें.

इस तरीके में, वॉलपेपर पिकर के लिए मौजूदा तरीके का इस्तेमाल किया जाता है. अगर इसे किसी डिसप्ले पर खोला गया था और सही संदर्भ का इस्तेमाल किया गया था, तो वॉलपेपर सेट करने का अनुरोध करने पर, सिस्टम डिसप्ले की पहचान अपने-आप कर सकता है.

अगर आपको मौजूदा डिसप्ले के अलावा किसी दूसरे डिसप्ले के लिए वॉलपेपर सेट करना है, तो टारगेट डिसप्ले (Context#createDisplayContext) के लिए नया Context ऑब्जेक्ट बनाएं और उस डिसप्ले से WallpaperManager इंस्टेंस पाएं.

सुरक्षा से जुड़ी पाबंदियां

सिस्टम, वर्चुअल डिसप्ले पर ऐसे वॉलपेपर नहीं दिखाएगा जिनका मालिकाना हक उसके पास नहीं है. ऐसा सुरक्षा से जुड़ी समस्या की वजह से होता है. कोई नुकसान पहुंचाने वाला ऐप्लिकेशन, सिस्टम डेकोरेशन की सुविधा चालू करके वर्चुअल डिसप्ले बना सकता है. साथ ही, डिसप्ले पर मौजूद उपयोगकर्ता की संवेदनशील जानकारी (जैसे, निजी फ़ोटो) पढ़ सकता है.

लागू करना

Android 10 में, IWallpaperConnection#attachEngine() और IWallpaperService#attach() इंटरफ़ेस, हर डिसप्ले के लिए कनेक्शन बनाने के लिए displayId पैरामीटर स्वीकार करते हैं. WallpaperManagerService.DisplayConnector में हर डिसप्ले के लिए वॉलपेपर इंजन और कनेक्शन शामिल होता है. WindowManager में, सभी डिसप्ले के लिए एक WallpaperController के बजाय, हर DisplayContent ऑब्जेक्ट के लिए वॉलपेपर कंट्रोलर बनाए जाते हैं.

WallpaperManager के कुछ सार्वजनिक तरीके (जैसे कि WallpaperManager#getDesiredMinimumWidth()) को अपडेट किया गया था, ताकि उनसे जुड़े डिसप्ले के लिए जानकारी का हिसाब लगाया जा सके और उसे उपलब्ध कराया जा सके. WallpaperInfo#supportsMultipleDisplays() और उससे जुड़ा रिसोर्स एट्रिब्यूट जोड़ा गया है, ताकि ऐप्लिकेशन डेवलपर यह बता सकें कि कौनसे वॉलपेपर एक से ज़्यादा स्क्रीन के लिए उपलब्ध हैं.

अगर डिफ़ॉल्ट डिसप्ले पर दिखाई गई वॉलपेपर सेवा, कई डिसप्ले के साथ काम नहीं करती है, तो सिस्टम सेकंडरी डिसप्ले पर डिफ़ॉल्ट वॉलपेपर दिखाता है.

तीसरा चित्र. सेकंडरी डिसप्ले के लिए वॉलपेपर का फ़ॉलबैक लॉजिक