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

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

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

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

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

लागू करना

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

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

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

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

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

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

लागू करना

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

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

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

जब 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() और उससे जुड़ा संसाधन एट्रिब्यूट जोड़ा गया है, ताकि ऐप्लिकेशन डेवलपर यह बता सकें कि कौनसे वॉलपेपर कई स्क्रीन के लिए तैयार हैं.

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

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