Android 8.0 में, Settings ऐप्लिकेशन के लिए एक नया इन्फ़ॉर्मेशन आर्किटेक्चर पेश किया गया था. इससे सेटिंग को व्यवस्थित करने का तरीका आसान हो गया. साथ ही, उपयोगकर्ताओं के लिए अपने Android डिवाइसों को पसंद के मुताबिक बनाने के लिए, सेटिंग को तुरंत ढूंढना आसान हो गया. Android 9 में, सेटिंग से जुड़ी ज़्यादा सुविधाएं देने और उन्हें आसानी से लागू करने के लिए, कुछ सुधार किए गए हैं.
उदाहरण और सोर्स
सेटिंग के ज़्यादातर पेजों पर, फ़िलहाल नए फ़्रेमवर्क का इस्तेमाल किया जा रहा है. इसका एक अच्छा उदाहरण DisplaySettings है:
packages/apps/Settings/src/com/android/settings/DisplaySettings.java
अहम कॉम्पोनेंट के लिए फ़ाइल पाथ यहां दिए गए हैं:
- CategoryKey:
packages/SettingsLib/src/com/android/settingslib/drawer/CategoryKey.java - DashboardFragmentRegistry:
packages/apps/Settings/src/com/android/settings/dashboard/DashboardFragmentRegistry.java - DashboardFragment:
packages/apps/Settings/src/com/android/settings/dashboard/DashboardFragment.java - AbstractPreferenceController:
frameworks/base/packages/SettingsLib/src/com/android/settingslib/core/AbstractPreferenceController.java - BasePreferenceController (Android 9 में पेश किया गया):
packages/apps/Settings/src/com/android/settings/core/BasePreferenceController.java
लागू करना
डिवाइस बनाने वाली कंपनियों को सलाह दी जाती है कि वे मौजूदा सेटिंग की जानकारी के आर्किटेक्चर को अपनाएं. साथ ही, पार्टनर के हिसाब से सुविधाओं को शामिल करने के लिए, ज़रूरत के मुताबिक सेटिंग के अतिरिक्त पेज डालें. लेगसी पेज (SettingsPreferencePage के तौर पर लागू किया गया) से नई सेटिंग को नए पेज (DashboardFragment का इस्तेमाल करके लागू किया गया) पर ले जाना मुश्किल हो सकता है. ऐसा हो सकता है कि लेगसी पेज की प्राथमिकता को PreferenceController के साथ लागू न किया गया हो.
इसलिए, किसी लेगसी पेज से नई पेज पर कोई सेटिंग ट्रांसफ़र करते समय, आपको PreferenceController बनाना होगा. साथ ही, कोड को कंट्रोलर में ले जाना होगा. इसके बाद, उसे नए DashboardFragment में इंस्टैंशिएट करना होगा. जिन एपीआई की ज़रूरत होती है उनके बारे में उनके नाम में बताया गया है. साथ ही, Javadoc में उनके बारे में जानकारी दी गई है.PreferenceController
हमारा सुझाव है कि हर PreferenceController के लिए यूनिट टेस्ट जोड़ें.
अगर बदलाव को AOSP में सबमिट किया जाता है, तो यूनिट टेस्ट करना ज़रूरी है.
Robolectric पर आधारित टेस्ट लिखने के तरीके के बारे में ज़्यादा जानकारी पाने के लिए, readme फ़ाइल packages/apps/Settings/tests/robotests/README.md देखें.
प्लगिन-स्टाइल वाला इन्फ़ॉर्मेशन आर्किटेक्चर
सेटिंग के हर आइटम को Preference के तौर पर लागू किया जाता है. प्राथमिकता को एक पेज से दूसरे पेज पर आसानी से ले जाया जा सकता है.
Android 8.0 में, प्लगिन-स्टाइल वाला होस्ट फ़्रैगमेंट पेश किया गया है. इसमें सेटिंग के आइटम शामिल होते हैं, ताकि कई सेटिंग को आसानी से एक जगह से दूसरी जगह ले जाया जा सके. सेटिंग आइटम को प्लगिन-स्टाइल कंट्रोलर के तौर पर मॉडल किया जाता है. इसलिए, सेटिंग पेज को एक होस्ट फ़्रैगमेंट और कई सेटिंग कंट्रोलर से बनाया जाता है.
DashboardFragment
DashboardFragment, प्लगिन-स्टाइल वाले प्रेफ़रंस कंट्रोलर का होस्ट है.
फ़्रैगमेंट, PreferenceFragment से इनहेरिट करता है. इसमें स्टैटिक और डाइनैमिक, दोनों तरह की प्राथमिकता वाली सूचियों को बड़ा करने और अपडेट करने के लिए हुक होते हैं.
स्टैटिक प्राथमिकताएं
स्टैटिक प्राथमिकता सूची को एक्सएमएल में <Preference> टैग का इस्तेमाल करके तय किया जाता है. DashboardFragment लागू करने के लिए, getPreferenceScreenResId() तरीके का इस्तेमाल किया जाता है. इससे यह तय किया जाता है कि किस एक्सएमएल फ़ाइल में, दिखाने के लिए प्राथमिकताओं की स्टैटिक सूची मौजूद है.
डाइनैमिक प्राथमिकताएं
डाइनैमिक आइटम, इंटेंट वाली टाइल को दिखाता है. इससे बाहरी या अंदरूनी ऐक्टिविटी पर पहुंचा जा सकता है. आम तौर पर, इंटेंट से सेटिंग के किसी दूसरे पेज पर रीडायरेक्ट किया जाता है. उदाहरण के लिए, सेटिंग के होम पेज पर मौजूद "Google" सेटिंग आइटम, डाइनैमिक आइटम है. डाइनैमिक आइटम, AndroidManifest में तय किए जाते हैं. इनके बारे में यहां बताया गया है. इन्हें FeatureProvider के ज़रिए लोड किया जाता है. इसे
DashboardFeatureProvider के तौर पर तय किया जाता है.
डाइनैमिक सेटिंग, स्टैटिक तौर पर कॉन्फ़िगर की गई सेटिंग की तुलना में ज़्यादा मेमोरी लेती हैं. इसलिए, आम तौर पर डेवलपर को सेटिंग को स्टैटिक सेटिंग के तौर पर लागू करना चाहिए. हालांकि, डाइनैमिक सेटिंग तब काम आ सकती है, जब इनमें से कोई भी स्थिति सही हो:
- सेटिंग को सीधे तौर पर Settings ऐप्लिकेशन में लागू नहीं किया जाता है. जैसे, ओईएम/कैरियर ऐप्लिकेशन की ओर से लागू की गई सेटिंग को इंजेक्ट करना.
- यह सेटिंग, सेटिंग के होम पेज पर दिखनी चाहिए.
- आपके पास सेटिंग के लिए पहले से ही कोई गतिविधि है और आपको अतिरिक्त स्टैटिक कॉन्फ़िगरेशन लागू नहीं करना है.
किसी गतिविधि को डाइनैमिक सेटिंग के तौर पर कॉन्फ़िगर करने के लिए, यह तरीका अपनाएं:
- गतिविधि को डाइनैमिक सेटिंग के तौर पर मार्क करें. इसके लिए, गतिविधि में इंटेंट-फ़िल्टर जोड़ें.
- सेटिंग ऐप्लिकेशन को बताएं कि यह किस कैटगरी से जुड़ा है. कैटगरी एक कॉन्स्टेंट है, जिसे
CategoryKeyमें तय किया गया है. - ज़रूरी नहीं: सेटिंग दिखने पर खास जानकारी वाला टेक्स्ट जोड़ें.
यहां DisplaySettings के लिए, सेटिंग ऐप्लिकेशन से लिया गया एक उदाहरण दिया गया है.
<activity android:name="Settings$DisplaySettingsActivity" android:label="@string/display_settings" android:icon="@drawable/ic_settings_display"> <!-- Mark the activity as a dynamic setting --> <intent-filter> <action android:name="com.android.settings.action.IA_SETTINGS" /> </intent-filter> <!-- Tell Settings app which category it belongs to --> <meta-data android:name="com.android.settings.category" android:value="com.android.settings.category.ia.homepage" /> <!-- Add a summary text when the setting is displayed --> <meta-data android:name="com.android.settings.summary" android:resource="@string/display_dashboard_summary"/> </activity>
रेंडर करने के समय, फ़्रैगमेंट स्टैटिक एक्सएमएल और AndroidManifest में तय की गई डाइनैमिक सेटिंग, दोनों से प्राथमिकताओं की सूची मांगेगा. PreferenceController को Java कोड या XML में तय किया गया है. DashboardFragment, PreferenceController के ज़रिए हर सेटिंग के हैंडलिंग लॉजिक को मैनेज करता है. इसके बारे में यहां बताया गया है. इसके बाद, उन्हें यूज़र इंटरफ़ेस (यूआई) में एक साथ दिखाया जाता है.
PreferenceController
Android 9 और Android 8.x में PreferenceController लागू करने के तरीके में अंतर है. इसके बारे में इस सेक्शन में बताया गया है.
Android 9 में PreferenceController
PreferenceController में, प्राथमिकता के साथ इंटरैक्ट करने के लिए सभी लॉजिक शामिल होते हैं. जैसे, प्राथमिकता दिखाना, अपडेट करना, खोज इंडेक्सिंग करना वगैरह.
PreferenceController का इंटरफ़ेस BasePreferenceController के तौर पर तय किया गया है. उदाहरण के लिए, packages/apps/Settings/src/com/android/settings/core/
BasePreferenceController.java में दिया गया कोड देखें
BasePreferenceController की कई सबक्लास हैं. हर सबक्लास, यूज़र इंटरफ़ेस (यूआई) की किसी खास स्टाइल से मैप होती है. Settings ऐप्लिकेशन, डिफ़ॉल्ट रूप से इस स्टाइल के साथ काम करता है. उदाहरण के लिए, TogglePreferenceController के पास एक एपीआई है, जो सीधे तौर पर यह तय करता है कि उपयोगकर्ता को टॉगल-आधारित सेटिंग वाले यूज़र इंटरफ़ेस (यूआई) के साथ कैसे इंटरैक्ट करना चाहिए.
BasePreferenceController में getAvailabilityStatus(), displayPreference(), handlePreferenceTreeClicked(), जैसे एपीआई हैं. हर एपीआई के बारे में ज़्यादा जानकारी देने वाला दस्तावेज़, इंटरफ़ेस क्लास में मौजूद है.
BasePreferenceController (और इसकी सबक्लास, जैसे कि TogglePreferenceController) को लागू करने पर यह पाबंदी है कि कंस्ट्रक्टर सिग्नेचर, इनमें से किसी एक से मेल खाना चाहिए:
public MyController(Context context, String key) {}public MyController(Context context) {}
फ़्रैगमेंट में कोई प्राथमिकता इंस्टॉल करते समय, डैशबोर्ड PreferenceController को डिसप्ले टाइम से पहले अटैच करने का तरीका उपलब्ध कराता है. इंस्टॉल करने के समय, कंट्रोलर को फ़्रैगमेंट से कनेक्ट किया जाता है, ताकि आने वाले समय में होने वाले सभी ज़रूरी इवेंट कंट्रोलर को भेजे जा सकें.
DashboardFragment, स्क्रीन पर मौजूद PreferenceController की सूची को सेव करता है. फ़्रैगमेंट के onCreate() पर, सभी कंट्रोलर को getAvailabilityStatus() तरीके के लिए शुरू किया जाता है. अगर यह सही वैल्यू दिखाता है, तो डिसप्ले लॉजिक को प्रोसेस करने के लिए displayPreference() को शुरू किया जाता है.
getAvailabilityStatus() यह भी ज़रूरी है कि सेटिंग फ़्रेमवर्क को यह बताया जाए कि खोज के दौरान कौनसे आइटम उपलब्ध हैं.
Android 8.x रिलीज़ में PreferenceController
PreferenceController में, प्राथमिकताओं के साथ इंटरैक्ट करने का पूरा लॉजिक शामिल होता है. जैसे, प्राथमिकताएं दिखाना, उन्हें अपडेट करना, और खोज के लिए इंडेक्स करना वगैरह.
पसंद के हिसाब से इंटरैक्शन के लिए,
PreferenceController के इंटरफ़ेस में isAvailable(),
displayPreference(), handlePreferenceTreeClicked() वगैरह एपीआई होते हैं.
हर एपीआई के बारे में ज़्यादा जानकारी देने वाला दस्तावेज़, इंटरफ़ेस क्लास में देखा जा सकता है.
फ़्रैगमेंट में कोई प्राथमिकता इंस्टॉल करते समय, डैशबोर्ड PreferenceController को डिसप्ले टाइम से पहले अटैच करने का तरीका उपलब्ध कराता है. इंस्टॉल करने के समय, कंट्रोलर को फ़्रैगमेंट से कनेक्ट किया जाता है, ताकि आने वाले समय में होने वाले सभी ज़रूरी इवेंट कंट्रोलर को भेजे जा सकें.
DashboardFragment, स्क्रीन पर PreferenceControllers
की सूची दिखाता है. फ़्रैगमेंट के onCreate() पर, isAvailable() तरीके के लिए सभी कंट्रोलर को शुरू किया जाता है. अगर यह सही वैल्यू दिखाता है, तो डिसप्ले लॉजिक को प्रोसेस करने के लिए displayPreference() को शुरू किया जाता है.
DashboardFragment का इस्तेमाल करना
प्राथमिकता को पेज A से B पर ले जाना
अगर प्राथमिकता, ओरिजनल पेज की प्राथमिकता वाली एक्सएमएल फ़ाइल में स्टैटिक तौर पर लिस्ट की गई है, तो Android के वर्शन के हिसाब से, नीचे दिए गए स्टैटिक मूव करने का तरीका अपनाएं. अगर ऐसा नहीं है, तो Android रिलीज़ के लिए, डाइनैमिक तरीके से ऐप्लिकेशन को एक ट्रैक से दूसरे ट्रैक में ले जाने की प्रक्रिया अपनाएं.
Android 9 में स्टैटिक मूव
- मूल पेज और डेस्टिनेशन पेज के लिए, प्राथमिकता वाली एक्सएमएल फ़ाइलें ढूंढें. यह जानकारी, पेज के
getPreferenceScreenResId()तरीके से देखी जा सकती है. - ओरिजनल पेज के एक्सएमएल से प्राथमिकता हटाएं.
- डेस्टिनेशन पेज के एक्सएमएल में प्राथमिकता जोड़ें.
- इस प्राथमिकता के लिए
PreferenceControllerको ओरिजनल पेज के Java कोड से हटाएं. आम तौर पर, यहcreatePreferenceControllers()में होता है. कंट्रोलर को सीधे तौर पर एक्सएमएल में भी सेट किया जा सकता है.ध्यान दें: ऐसा हो सकता है कि प्राथमिकता में
PreferenceControllerन हो. - डेस्टिनेशन पेज के
createPreferenceControllers()मेंPreferenceControllerको इंस्टैंशिएट करें. अगर पुराने पेज के एक्सएमएल मेंPreferenceControllerको तय किया गया है, तो नए पेज के एक्सएमएल में भी इसे तय करें.
Android 9 में डाइनैमिक मूव
- पता लगाएं कि ओरिजनल और डेस्टिनेशन पेज किस कैटगरी में होस्ट किए जाते हैं. यह जानकारी
DashboardFragmentRegistryमें देखी जा सकती है. - वह
AndroidManifest.xmlफ़ाइल खोलें जिसमें वह सेटिंग मौजूद है जिसे आपको ट्रांसफ़र करना है. इसके बाद, इस सेटिंग को दिखाने वाली गतिविधि की एंट्री ढूंढें. com.android.settings.categoryके लिए गतिविधि के मेटाडेटा की वैल्यू को नए पेज की कैटगरी की कुंजी पर सेट करें.
Android 8.x के वर्शन में स्टैटिक मूव
- मूल पेज और डेस्टिनेशन पेज के लिए, प्राथमिकता वाली एक्सएमएल फ़ाइलें ढूंढें. यह जानकारी, पेज के
- ओरिजनल पेज के एक्सएमएल से प्राथमिकता हटाएं.
- डेस्टिनेशन पेज के एक्सएमएल में प्राथमिकता जोड़ें.
- मूल पेज के Java कोड में, इस प्राथमिकता के लिए
PreferenceControllerहटाएं. आम तौर पर, यहgetPreferenceControllers()में होता है. - डेस्टिनेशन पेज के
getPreferenceControllers()मेंPreferenceControllerको इंस्टैंशिएट करें.
getPreferenceScreenResId()
तरीके से देखी जा सकती है.
ध्यान दें: ऐसा हो सकता है कि प्राथमिकता में PreferenceController न हो.
Android 8.x के वर्शन में डाइनैमिक मूव
- पता लगाएं कि ओरिजनल और डेस्टिनेशन पेज किस कैटगरी में होस्ट किए जाते हैं. यह जानकारी
DashboardFragmentRegistryमें देखी जा सकती है. - वह
AndroidManifest.xmlफ़ाइल खोलें जिसमें वह सेटिंग मौजूद है जिसे आपको ट्रांसफ़र करना है. इसके बाद, इस सेटिंग को दिखाने वाली गतिविधि की एंट्री ढूंढें. com.android.settings.categoryके लिए गतिविधि के मेटाडेटा की वैल्यू बदलें. साथ ही, वैल्यू पॉइंट को नए पेज की कैटगरी की कुंजी पर सेट करें.
किसी पेज में नई प्राथमिकता बनाना
अगर प्राथमिकता, ओरिजनल पेज की प्राथमिकता वाली एक्सएमएल फ़ाइल में स्टैटिक तौर पर लिस्ट की गई है, तो यहां दिया गया स्टैटिक तरीका अपनाएं. अगर ऐसा नहीं है, तो डाइनैमिक तरीका अपनाएं.
स्टैटिक प्राथमिकता बनाना
- पेज के लिए, प्राथमिकता वाली एक्सएमएल फ़ाइलें ढूंढें. यह जानकारी, पेज के getPreferenceScreenResId() तरीके से मिलती है.
- एक्सएमएल में नया Preference आइटम जोड़ें. पक्का करें कि इसमें यूनीक
android:keyहो. -
पेज के
getPreferenceControllers()तरीके में, इस प्राथमिकता के लिएPreferenceControllerतय करें.- Android 8.x और Android 9 में, इस सेटिंग के लिए
PreferenceControllerको पेज केcreatePreferenceControllers()तरीके में इंस्टैंटिएट करें.अगर यह सेटिंग पहले से ही किसी दूसरी जगह पर मौजूद है, तो हो सकता है कि इसके लिए
PreferenceControllerपहले से मौजूद हो. नयाPreferenceControllerबनाए बिना, इसका फिर से इस्तेमाल किया जा सकता है. -
Android 9 से,
PreferenceControllerको प्राथमिकता के बगल में मौजूद एक्सएमएल में एलान करने का विकल्प चुना जा सकता है. उदाहरण के लिए:<Preference android:key="reset_dashboard" android:title="@string/reset_dashboard_title" settings:controller="com.android.settings.system.ResetPreferenceController"/>
- Android 8.x और Android 9 में, इस सेटिंग के लिए
डाइनैमिक प्राथमिकता बनाना
- पता लगाएं कि ओरिजनल और डेस्टिनेशन पेज किस कैटगरी में होस्ट किए जाते हैं. यह जानकारी
DashboardFragmentRegistryमें देखी जा सकती है. AndroidManifestमें नई गतिविधि बनाना- सेटिंग तय करने के लिए, नई गतिविधि में ज़रूरी मेटाडेटा जोड़ें.
com.android.settings.categoryके लिए मेटाडेटा वैल्यू को वही वैल्यू सेट करें जो पहले चरण में तय की गई थी.
एक नया पेज बनाएं
DashboardFragmentसे इनहेरिट करने वाला नया फ़्रैगमेंट बनाएं.DashboardFragmentRegistryमें इसकी कैटगरी तय करें.ध्यान दें: यह चरण ज़रूरी नहीं है. अगर आपको इस पेज पर किसी डाइनैमिक सेटिंग की ज़रूरत नहीं है, तो आपको कैटगरी की कुंजी देने की ज़रूरत नहीं है.
- इस पेज के लिए ज़रूरी सेटिंग जोड़ने का तरीका अपनाएं. ज़्यादा जानकारी के लिए, लागू करना सेक्शन देखें.
Validation
- सेटिंग में जाकर, Robolectric टेस्ट चलाएँ. सभी मौजूदा और नए टेस्ट पास होने चाहिए.
- सेटिंग बनाएं और इंस्टॉल करें. इसके बाद, जिस पेज में बदलाव किया जा रहा है उसे मैन्युअल तरीके से खोलें. पेज तुरंत अपडेट होना चाहिए.