एक आसान विजेट बनाएं

ऐप्लिकेशन विजेट, ऐप्लिकेशन के छोटे-छोटे व्यू होते हैं. इन्हें होम स्क्रीन जैसे दूसरे ऐप्लिकेशन में जोड़ा जा सकता है और समय-समय पर अपडेट मिलते रहते हैं. इन व्यू को यूज़र इंटरफ़ेस में विजेट कहा जाता है. साथ ही, ऐप्लिकेशन विजेट की सेवा देने वाली कंपनी (या विजेट की सेवा देने वाली कंपनी) की मदद से, इनमें से किसी एक को पब्लिश किया जा सकता है. जिस ऐप्लिकेशन कॉम्पोनेंट में दूसरे विजेट होते हैं उसे ऐप्लिकेशन विजेट होस्ट (या विजेट होस्ट) कहा जाता है. पहली इमेज में, संगीत विजेट का सैंपल दिखाया गया है:

संगीत के विजेट का उदाहरण
पहला डायग्राम. संगीत के विजेट का उदाहरण.

इस दस्तावेज़ में, विजेट की सेवा देने वाली कंपनी का इस्तेमाल करके विजेट पब्लिश करने का तरीका बताया गया है. ऐप्लिकेशन विजेट होस्ट करने के लिए, अपना AppWidgetHost बनाने के बारे में जानकारी पाने के लिए, विजेट होस्ट बनाएं लेख पढ़ें.

विजेट को डिज़ाइन करने के तरीके के बारे में जानने के लिए, ऐप्लिकेशन विजेट की खास जानकारी देखें.

विजेट के कॉम्पोनेंट

विजेट बनाने के लिए, आपको इन बुनियादी कॉम्पोनेंट की ज़रूरत होगी:

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

दूसरे चित्र में दिखाया गया है कि ये कॉम्पोनेंट, ऐप्लिकेशन विजेट को प्रोसेस करने के पूरे फ़्लो में कैसे फ़िट होते हैं.

ऐप्लिकेशन विजेट को प्रोसेस करने का फ़्लो
दूसरी इमेज. ऐप्लिकेशन विजेट को प्रोसेस करने का फ़्लो.

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

हम इन सुधारों का भी सुझाव देते हैं: विजेट के लेआउट में बदलाव करने की सुविधा, अन्य सुधार, ऐडवांस विजेट, कलेक्शन विजेट, और विजेट होस्ट बनाने की सुविधा.

AppWidgetProviderInfo एक्सएमएल का एलान करना

AppWidgetProviderInfo ऑब्जेक्ट, विजेट की ज़रूरी विशेषताओं के बारे में बताता है. किसी एक <appwidget-provider> एलिमेंट का इस्तेमाल करके, एक्सएमएल रिसॉर्स फ़ाइल में AppWidgetProviderInfo ऑब्जेक्ट तय करें और उसे प्रोजेक्ट के res/xml/ फ़ोल्डर में सेव करें.

यह नीचे दिए गए उदाहरण में दिखाया गया है:

<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
    android:minWidth="40dp"
    android:minHeight="40dp"
    android:targetCellWidth="1"
    android:targetCellHeight="1"
    android:maxResizeWidth="250dp"
    android:maxResizeHeight="120dp"
    android:updatePeriodMillis="86400000"
    android:description="@string/example_appwidget_description"
    android:previewLayout="@layout/example_appwidget_preview"
    android:initialLayout="@layout/example_loading_appwidget"
    android:configure="com.example.android.ExampleAppWidgetConfigurationActivity"
    android:resizeMode="horizontal|vertical"
    android:widgetCategory="home_screen"
    android:widgetFeatures="reconfigurable|configuration_optional">
</appwidget-provider>

विजेट के साइज़ से जुड़े एट्रिब्यूट

डिफ़ॉल्ट होम स्क्रीन, सेल के ग्रिड के आधार पर अपनी विंडो में विजेट को जगह पर सेट करती है. इनकी ऊंचाई और चौड़ाई तय होती है. ज़्यादातर होम स्क्रीन पर विजेट को सिर्फ़ ग्रिड सेल के पूर्णांक गुणज के तौर पर इस्तेमाल किया जाता है—उदाहरण के लिए, दो सेल हॉरिज़ॉन्टल तौर पर तीन सेल वर्टिकल तौर पर.

विजेट के साइज़ से जुड़े एट्रिब्यूट की मदद से, विजेट का डिफ़ॉल्ट साइज़ तय किया जा सकता है. साथ ही, विजेट के साइज़ की कम से कम और ज़्यादा से ज़्यादा वैल्यू भी दी जा सकती है. इस संदर्भ में, विजेट का डिफ़ॉल्ट साइज़ वह साइज़ होता है जो होम स्क्रीन पर पहली बार जोड़े जाने पर विजेट का होता है.

नीचे दी गई टेबल में, विजेट के साइज़ से जुड़े <appwidget-provider> एट्रिब्यूट के बारे में बताया गया है:

एट्रिब्यूट और जानकारी
targetCellWidth और targetCellHeight (Android 12), minWidth और minHeight
  • Android 12 में, targetCellWidth और targetCellHeight एट्रिब्यूट, ग्रिड सेल के हिसाब से विजेट के डिफ़ॉल्ट साइज़ की जानकारी देते हैं. Android 11 और इससे पहले के वर्शन वाले डिवाइसों में इन एट्रिब्यूट को अनदेखा किया जाता है. अगर होम स्क्रीन पर ग्रिड पर आधारित लेआउट नहीं है, तो इन्हें अनदेखा किया जा सकता है.
  • minWidth और minHeight एट्रिब्यूट, डिफ़ॉल्ट तौर पर विजेट के डाइमेंशन की जानकारी, dp में देते हैं. अगर किसी विजेट की कम से कम चौड़ाई या ऊंचाई की वैल्यू, सेल के डाइमेंशन से मेल नहीं खाती हैं, तो वैल्यू को सेल के सबसे करीबी साइज़ पर राउंड अप कर दिया जाता है.
हमारा सुझाव है कि आप एट्रिब्यूट के दोनों सेट, targetCellWidth और targetCellHeight, और minWidth और minHeight की जानकारी दें. इससे, अगर उपयोगकर्ता के डिवाइस पर targetCellWidth और targetCellHeight काम नहीं करते, तो आपका ऐप्लिकेशन minWidth और minHeight का इस्तेमाल कर सकता है. अगर ये एट्रिब्यूट इस्तेमाल किए जा सकते हैं, तो targetCellWidth और targetCellHeight एट्रिब्यूट को minWidth और minHeight एट्रिब्यूट के मुकाबले प्राथमिकता दी जाएगी.
minResizeWidth और minResizeHeight विजेट का कम से कम साइज़ बताएं. ये वैल्यू उस साइज़ से जुड़ी होती हैं जिसके तहत बैज को पढ़ा नहीं जा सकता या किसी अन्य तरीके से इसका इस्तेमाल नहीं किया जा सकता. इन एट्रिब्यूट का इस्तेमाल करके, उपयोगकर्ता विजेट का साइज़, डिफ़ॉल्ट विजेट साइज़ से छोटा कर सकता है. अगर minResizeWidth एट्रिब्यूट की वैल्यू minWidth से ज़्यादा है या हॉरिज़ॉन्टल रीसाइज़ करने की सुविधा चालू नहीं है, तो minResizeWidth एट्रिब्यूट को अनदेखा कर दिया जाता है. resizeMode देखें. इसी तरह, अगर minResizeHeight एट्रिब्यूट की वैल्यू minHeight से ज़्यादा है या वर्टिकल रीसाइज़ करने की सुविधा चालू नहीं है, तो minResizeHeight एट्रिब्यूट को अनदेखा कर दिया जाता है.
maxResizeWidth और maxResizeHeight विजेट के लिए सुझाया गया ज़्यादा से ज़्यादा साइज़ बताएं. अगर वैल्यू, ग्रिड सेल डाइमेंशन के कई गुना नहीं हैं, तो उन्हें सेल के सबसे करीबी साइज़ में बदल दिया जाता है. अगर maxResizeWidth एट्रिब्यूट की वैल्यू, minWidth से कम है या हॉरिज़ॉन्टल साइज़ बदलने की सुविधा चालू नहीं है, तो maxResizeWidth एट्रिब्यूट को अनदेखा कर दिया जाता है. resizeMode देखें. इसी तरह, अगर maxResizeHeight एट्रिब्यूट की वैल्यू minHeight से ज़्यादा है या वर्टिकल रीसाइज़ करने की सुविधा चालू नहीं है, तो maxResizeHeight एट्रिब्यूट को अनदेखा कर दिया जाता है. यह सुविधा Android 12 में लॉन्च की गई थी.
resizeMode उन नियमों को तय करता है जिनके हिसाब से विजेट का साइज़ बदला जा सकता है. इस एट्रिब्यूट का इस्तेमाल करके, होम स्क्रीन पर मौजूद विजेट को हॉरिज़ॉन्टल, वर्टिकल या दोनों अक्षों पर, अपनी पसंद के मुताबिक साइज़ में बदला जा सकता है. विजेट का साइज़ बदलने के हैंडल दिखाने के लिए, उपयोगकर्ता उसे दबाकर रखते हैं. इसके बाद, लेआउट ग्रिड पर उसका साइज़ बदलने के लिए, हॉरिज़ॉन्टल या वर्टिकल हैंडल को खींचते और छोड़ते हैं. resizeMode एट्रिब्यूट की वैल्यू में ये शामिल हैं: horizontal, vertical, और none. किसी विजेट को हॉरिज़ॉन्टल और वर्टिकल, दोनों तरह से साइज़ में बदला जा सकता है, यह बताने के लिए horizontal|vertical का इस्तेमाल करें.

उदाहरण

यह समझाने के लिए कि पिछली टेबल में दिए गए एट्रिब्यूट, विजेट के साइज़ पर कैसे असर डालते हैं, नीचे दी गई जानकारी मान लें:

  • ग्रिड सेल की चौड़ाई 30 dp और ऊंचाई 50 dp है.
  • इस एट्रिब्यूट की खास जानकारी यहां दी गई है:
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
    android:minWidth="80dp"
    android:minHeight="80dp"
    android:targetCellWidth="2"
    android:targetCellHeight="2"
    android:minResizeWidth="40dp"
    android:minResizeHeight="40dp"
    android:maxResizeWidth="120dp"
    android:maxResizeHeight="120dp"
    android:resizeMode="horizontal|vertical" />

Android 12 से:

विजेट के डिफ़ॉल्ट साइज़ के तौर पर, targetCellWidth और targetCellHeight एट्रिब्यूट का इस्तेमाल करें.

विजेट का साइज़ डिफ़ॉल्ट रूप से 2x2 होता है. विजेट का आकार बदलकर 2x1 या 4x3 तक किया जा सकता है.

Android 11 और उससे पहले के वर्शन के लिए:

विजेट के डिफ़ॉल्ट साइज़ का हिसाब लगाने के लिए, minWidth और minHeight एट्रिब्यूट का इस्तेमाल करें.

डिफ़ॉल्ट चौड़ाई = Math.ceil(80 / 30) = 3

डिफ़ॉल्ट ऊंचाई = Math.ceil(80 / 50) = 2

विजेट का साइज़, डिफ़ॉल्ट रूप से 3x2 होता है. विजेट का साइज़ 2x1 तक छोटा या फ़ुल स्क्रीन तक बड़ा किया जा सकता है.

विजेट के अन्य एट्रिब्यूट

नीचे दी गई टेबल में, विजेट के साइज़ के अलावा अन्य एट्रिब्यूट के बारे में बताया गया है.<appwidget-provider>

एट्रिब्यूट और जानकारी
updatePeriodMillis इससे यह तय होता है कि विजेट फ़्रेमवर्क, onUpdate() कॉलबैक तरीके को कॉल करके, AppWidgetProvider से अपडेट का अनुरोध कितनी बार करता है. इस वैल्यू के हिसाब से, अपडेट ठीक समय पर होने की गारंटी नहीं है. हमारा सुझाव है कि बैटरी बचाने के लिए, अपडेट को कम से कम अपडेट करें. एक घंटे में एक से ज़्यादा बार अपडेट न करें. अपडेट की सही अवधि चुनने के लिए, ध्यान में रखने वाली सभी बातों की पूरी सूची के लिए, विजेट के कॉन्टेंट को अपडेट करने के लिए ऑप्टिमाइज़ेशन देखें.
initialLayout यह उस लेआउट रिसॉर्स को दिखाता है जो विजेट लेआउट तय करता है.
configure यह उस गतिविधि के बारे में बताता है जो उपयोगकर्ता के विजेट जोड़ने पर शुरू होती है. इससे, उपयोगकर्ता को विजेट प्रॉपर्टी कॉन्फ़िगर करने की सुविधा मिलती है. देखें कि उपयोगकर्ताओं को विजेट कॉन्फ़िगर करने की अनुमति कैसे दें. Android 12 से, आपका ऐप्लिकेशन शुरुआती कॉन्फ़िगरेशन को छोड़ सकता है. ज़्यादा जानकारी के लिए, विजेट के डिफ़ॉल्ट कॉन्फ़िगरेशन का इस्तेमाल करने का तरीका देखें.
description इससे विजेट पिकर के ब्यौरे का पता चलता है, जो आपके विजेट के लिए दिखता है. यह सुविधा Android 12 में लॉन्च की गई थी.
previewLayout (Android 12) और previewImage (Android 11 और उससे पहले के वर्शन)
  • Android 12 की शुरुआत से, previewLayout एट्रिब्यूट का इस्तेमाल करके झलक को बढ़ाया जा सकता है. इसे ऐसे एक्सएमएल लेआउट के तौर पर उपलब्ध कराया जाता है जो विजेट के डिफ़ॉल्ट साइज़ पर सेट होता है. आम तौर पर, इस एट्रिब्यूट के तौर पर बताए गए लेआउट एक्सएमएल और असली विजेट का लेआउट एक्सएमएल एक ही होता है. साथ ही, दोनों में डिफ़ॉल्ट वैल्यू भी एक जैसी होती हैं.
  • Android 11 या उससे पहले के वर्शन में, previewImage एट्रिब्यूट से यह पता चलता है कि कॉन्फ़िगर किए जाने के बाद विजेट कैसा दिखता है. यह झलक, ऐप्लिकेशन विजेट चुनते समय उपयोगकर्ता को दिखती है. अगर यह जानकारी नहीं दी जाती है, तो उपयोगकर्ता को आपके ऐप्लिकेशन का लॉन्चर आइकॉन दिखता है. यह फ़ील्ड, AndroidManifest.xml फ़ाइल में <receiver> एलिमेंट के android:previewImage एट्रिब्यूट से जुड़ा होता है.
ध्यान दें: हम आपको previewImage और previewLayout, दोनों एट्रिब्यूट की जानकारी देने का सुझाव देते हैं, ताकि अगर उपयोगकर्ता के डिवाइस पर previewLayout काम नहीं करता है, तो आपका ऐप्लिकेशन previewImage का इस्तेमाल कर सके. ज़्यादा जानकारी के लिए, विजेट की झलक के साथ, पुराने सिस्टम के साथ काम करने की सुविधा देखें.
autoAdvanceViewId विजेट के सबव्यू का व्यू आईडी बताता है, जो विजेट के होस्ट की मदद से अपने-आप बेहतर होता है.
widgetCategory इससे यह तय होता है कि आपका विजेट, होम स्क्रीन (home_screen), लॉक स्क्रीन (keyguard) या दोनों पर दिखेगा. Android 5.0 और उसके बाद के वर्शन के लिए, सिर्फ़ home_screen मान्य है.
widgetFeatures यह बताता है कि विजेट में कौनसी सुविधाएं काम करती हैं. उदाहरण के लिए, अगर आप चाहते हैं कि जब कोई उपयोगकर्ता आपके विजेट को जोड़े, तो वह उसके डिफ़ॉल्ट कॉन्फ़िगरेशन का इस्तेमाल करे, तो configuration_optional और reconfigurable, दोनों फ़्लैग बताएं. इससे, उपयोगकर्ता के विजेट जोड़ने के बाद, कॉन्फ़िगरेशन गतिविधि शुरू होने से बच जाता है. इसके बाद भी, उपयोगकर्ता विजेट को फिर से कॉन्फ़िगर कर सकता है.

विजेट ब्रॉडकास्ट मैनेज करने के लिए, AppWidgetProvider क्लास का इस्तेमाल करें

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

मेनिफ़ेस्ट में विजेट की जानकारी देना

सबसे पहले, अपने ऐप्लिकेशन की AndroidManifest.xml फ़ाइल में AppWidgetProvider क्लास का एलान करें, जैसा कि इस उदाहरण में दिखाया गया है:

<receiver android:name="ExampleAppWidgetProvider"
                 android:exported="false">
    <intent-filter>
        <action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
    </intent-filter>
    <meta-data android:name="android.appwidget.provider"
               android:resource="@xml/example_appwidget_info" />
</receiver>

<receiver> एलिमेंट के लिए android:name एट्रिब्यूट ज़रूरी है. यह एट्रिब्यूट, विजेट के लिए इस्तेमाल किए गए AppWidgetProvider के बारे में बताता है. कॉम्पोनेंट को तब तक एक्सपोर्ट नहीं करना चाहिए, जब तक कि आपके AppWidgetProvider पर किसी अलग प्रोसेस को ब्रॉडकास्ट करने की ज़रूरत न हो. आम तौर पर, ऐसा नहीं होता है.

<intent-filter> एलिमेंट में, android:name एट्रिब्यूट वाला <action> एलिमेंट शामिल होना चाहिए. इस एट्रिब्यूट से पता चलता है कि AppWidgetProvider, ACTION_APPWIDGET_UPDATE ब्रॉडकास्ट को स्वीकार करता है. आपको सिर्फ़ इस ब्रॉडकास्ट के बारे में साफ़ तौर पर बताना होगा. AppWidgetManager, अन्य सभी विजेट ब्रॉडकास्ट को ज़रूरी होने पर AppWidgetProvider पर अपने-आप भेजता है.

<meta-data> एलिमेंट, AppWidgetProviderInfo संसाधन के बारे में बताता है. साथ ही, इसके लिए इन एट्रिब्यूट की ज़रूरत होती है:

  • android:name: मेटाडेटा का नाम बताता है. डेटा को AppWidgetProviderInfo डिस्क्रिप्टर के तौर पर पहचानने के लिए, android.appwidget.provider का इस्तेमाल करें.
  • android:resource: AppWidgetProviderInfo संसाधन की जगह की जानकारी देता है.

AppWidgetProvider क्लास लागू करना

AppWidgetProvider क्लास, BroadcastReceiver को एक सुविधा क्लास के तौर पर इस्तेमाल करती है, ताकि विजेट ब्रॉडकास्ट मैनेज किए जा सके. इससे सिर्फ़ वही इवेंट ब्रॉडकास्ट मिलते हैं जो विजेट के लिए काम के होते हैं. जैसे, विजेट को अपडेट करना, मिटाना, चालू करना, और बंद करना. जब ये ब्रॉडकास्ट इवेंट होते हैं, तब इन AppWidgetProvider तरीकों को कॉल किया जाता है:

onUpdate()
इसे, AppWidgetProviderInfo में updatePeriodMillis एट्रिब्यूट के बताए गए इंटरवल पर अपडेट करने के लिए कहा जाता है. ज़्यादा जानकारी के लिए, इस पेज पर विजेट के अन्य एट्रिब्यूट की जानकारी देने वाली टेबल देखें.
इस तरीके को तब भी कॉल किया जाता है, जब उपयोगकर्ता विजेट जोड़ता है. इससे ज़रूरी सेटअप पूरा होता है. जैसे, View ऑब्जेक्ट के लिए इवेंट हैंडलर तय करना या विजेट में दिखाने के लिए डेटा लोड करने के लिए जॉब शुरू करना. हालांकि, अगर configuration_optional फ़्लैग के बिना कॉन्फ़िगरेशन गतिविधि का एलान किया जाता है, तो उपयोगकर्ता विजेट जोड़ने पर, इस तरीके को नहीं बुलाया जाता. हालांकि, बाद के अपडेट के लिए इसे बुलाया जाता है. कॉन्फ़िगरेशन पूरा होने पर, पहला अपडेट करने की ज़िम्मेदारी कॉन्फ़िगरेशन गतिविधि की होती है. ज़्यादा जानकारी के लिए, उपयोगकर्ताओं को ऐप्लिकेशन विजेट कॉन्फ़िगर करने की सुविधा देना देखें.
सबसे ज़रूरी कॉलबैक onUpdate() है. ज़्यादा जानकारी के लिए, इस पेज पर onUpdate() क्लास की मदद से इवेंट मैनेज करना देखें.
onAppWidgetOptionsChanged()

यह तब ट्रिगर होता है, जब विजेट को पहली बार प्लेस किया जाता है और जब भी विजेट का साइज़ बदला जाता है. विजेट के साइज़ की सीमाओं के आधार पर कॉन्टेंट दिखाने या छिपाने के लिए, इस कॉलबैक का इस्तेमाल करें. getAppWidgetOptions() को कॉल करके, साइज़ की सीमाएं पाएं. साथ ही, Android 12 से, विजेट के इंस्टेंस के संभावित साइज़ की सूची भी पाएं. इससे Bundle मिलता है, जिसमें ये शामिल होते हैं:

  • OPTION_APPWIDGET_MIN_WIDTH: इसमें विजेट के इंस्टेंस की चौड़ाई की निचली सीमा, डीपी यूनिट में होती है.
  • OPTION_APPWIDGET_MIN_HEIGHT: इसमें विजेट इंस्टेंस की ऊंचाई का निचला बाउंड, डीपी यूनिट में होता है.
  • OPTION_APPWIDGET_MAX_WIDTH: इसमें विजेट इंस्टेंस की चौड़ाई की ऊपरी सीमा, डीपी इकाइयों में होती है.
  • OPTION_APPWIDGET_MAX_HEIGHT: इसमें विजेट के इंस्टेंस की ऊंचाई की ऊपरी सीमा, डीपी यूनिट में होती है.
  • OPTION_APPWIDGET_SIZES: इसमें dp इकाइयों में, संभावित साइज़ (List<SizeF>) की सूची होती है. ये ऐसे साइज़ होते हैं जिनमें विजेट का इंस्टेंस हो सकता है. यह सुविधा Android 12 में लॉन्च की गई थी.
onDeleted(Context, int[])

विजेट होस्ट से विजेट मिटाने पर, यह इवेंट ट्रिगर होता है.

onEnabled(Context)

यह तब कॉल किया जाता है, जब विजेट का कोई इंस्टेंस पहली बार बनाया जाता है. उदाहरण के लिए, अगर उपयोगकर्ता आपके विजेट के दो इंस्टेंस जोड़ता है, तो इसे सिर्फ़ पहली बार कहा जाता है. अगर आपको कोई नया डेटाबेस खोलना है या कोई ऐसा सेटअप करना है जिसे सभी विजेट इंस्टेंस के लिए सिर्फ़ एक बार करना है, तो यह इसके लिए सही जगह है.

onDisabled(Context)

यह तब ट्रिगर होता है, जब विजेट होस्ट से आपके विजेट का आखिरी इंस्टेंस मिटाया जाता है. यहां से onEnabled(Context) में किए गए सभी काम मिटाए जा सकते हैं. जैसे, किसी अस्थायी डेटाबेस को मिटाना.

onReceive(Context, Intent)

इसे हर ब्रॉडकास्ट के लिए और पहले के सभी कॉलबैक तरीकों से पहले कॉल किया जाता है. आम तौर पर, आपको यह तरीका लागू करने की ज़रूरत नहीं होती, क्योंकि डिफ़ॉल्ट रूप से AppWidgetProvider लागू करने पर, सभी विजेट ब्रॉडकास्ट फ़िल्टर हो जाते हैं. साथ ही, ज़रूरत के हिसाब से, पहले के तरीकों को कॉल किया जाता है.

आपको AndroidManifest में <receiver> एलिमेंट का इस्तेमाल करके, अपनी AppWidgetProvider क्लास को ब्रॉडकास्ट रिसीवर के तौर पर लागू करने का एलान करना होगा. ज़्यादा जानकारी के लिए, इस पेज पर मेनिफ़ेस्ट में विजेट का एलान करना देखें.

onUpdate() क्लास की मदद से इवेंट मैनेज करना

AppWidgetProvider कॉलबैक में सबसे अहम onUpdate() होता है, क्योंकि जब भी किसी होस्ट में विजेट जोड़ा जाता है, तब इसे कॉल किया जाता है. ऐसा तब तक होता है, जब तक configuration_optional फ़्लैग के बिना कॉन्फ़िगरेशन गतिविधि का इस्तेमाल नहीं किया जाता. अगर आपका विजेट किसी उपयोगकर्ता इंटरैक्शन इवेंट को स्वीकार करता है, तो इस कॉलबैक में इवेंट हैंडलर रजिस्टर करें. अगर आपका विजेट, अस्थायी फ़ाइलें या डेटाबेस नहीं बनाता है या ऐसा कोई काम नहीं करता है जिसके लिए क्लीन-अप की ज़रूरत होती है, तो हो सकता है कि आपको सिर्फ़ onUpdate() कॉलबैक का तरीका तय करना पड़े.

उदाहरण के लिए, अगर आपको ऐसा विजेट चाहिए जिस पर टैप करने से गतिविधि को लॉन्च किया जाता हो, तो AppWidgetProvider को लागू करने का यह तरीका इस्तेमाल किया जा सकता है:

Kotlin

class ExampleAppWidgetProvider : AppWidgetProvider() {

    override fun onUpdate(
            context: Context,
            appWidgetManager: AppWidgetManager,
            appWidgetIds: IntArray
    ) {
        // Perform this loop procedure for each widget that belongs to this
        // provider.
        appWidgetIds.forEach { appWidgetId ->
            // Create an Intent to launch ExampleActivity.
            val pendingIntent: PendingIntent = PendingIntent.getActivity(
                    /* context = */ context,
                    /* requestCode = */  0,
                    /* intent = */ Intent(context, ExampleActivity::class.java),
                    /* flags = */ PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
            )

            // Get the layout for the widget and attach an onClick listener to
            // the button.
            val views: RemoteViews = RemoteViews(
                    context.packageName,
                    R.layout.appwidget_provider_layout
            ).apply {
                setOnClickPendingIntent(R.id.button, pendingIntent)
            }

            // Tell the AppWidgetManager to perform an update on the current
            // widget.
            appWidgetManager.updateAppWidget(appWidgetId, views)
        }
    }
}

Java

public class ExampleAppWidgetProvider extends AppWidgetProvider {

    public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
        // Perform this loop procedure for each widget that belongs to this
        // provider.
        for (int i=0; i < appWidgetIds.length; i++) {
            int appWidgetId = appWidgetIds[i];
            // Create an Intent to launch ExampleActivity
            Intent intent = new Intent(context, ExampleActivity.class);
            PendingIntent pendingIntent = PendingIntent.getActivity(
                /* context = */ context,
                /* requestCode = */ 0,
                /* intent = */ intent,
                /* flags = */ PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE
            );

            // Get the layout for the widget and attach an onClick listener to
            // the button.
            RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.example_appwidget_layout);
            views.setOnClickPendingIntent(R.id.button, pendingIntent);

            // Tell the AppWidgetManager to perform an update on the current app
            // widget.
            appWidgetManager.updateAppWidget(appWidgetId, views);
        }
    }
}

यह AppWidgetProvider सिर्फ़ onUpdate() तरीके को तय करता है. इसका इस्तेमाल करके, PendingIntent बनाया जाता है, जो Activity को लॉन्च करता है और setOnClickPendingIntent(int, PendingIntent) का इस्तेमाल करके, इसे विजेट के बटन से जोड़ता है. इसमें एक लूप शामिल होता है, जो appWidgetIds में मौजूद हर एंट्री को दोहराता है. यह आईडी का एक कलेक्शन होता है, जो इस सेवा देने वाली कंपनी के बनाए गए हर विजेट की पहचान करता है. अगर उपयोगकर्ता विजेट का एक से ज़्यादा इंस्टेंस बनाता है, तो वे सभी एक साथ अपडेट हो जाते हैं. हालांकि, विजेट के सभी इंस्टेंस के लिए सिर्फ़ एक updatePeriodMillis शेड्यूल मैनेज किया जाता है. उदाहरण के लिए, अगर अपडेट के शेड्यूल को हर दो घंटे पर सेट किया गया है और विजेट का दूसरा इंस्टेंस, पहले इंस्टेंस के एक घंटे बाद जोड़ा जाता है, तो दोनों को पहले इंस्टेंस के लिए तय की गई अवधि के हिसाब से अपडेट किया जाता है. साथ ही, अपडेट की दूसरी अवधि को अनदेखा कर दिया जाता है. ये दोनों हर घंटे नहीं, बल्कि हर दो घंटे में अपडेट होते हैं.

ज़्यादा जानकारी के लिए, ExampleAppWidgetProvider.java के सैंपल क्लास को देखें.

विजेट ब्रॉडकास्ट इंटेंट पाना

AppWidgetProvider एक सुविधा क्लास है. अगर आपको विजेट के ब्रॉडकास्ट सीधे तौर पर चाहिए, तो अपना BroadcastReceiver लागू करें या onReceive(Context,Intent) कॉलबैक को बदलें. आपको इन इंटेंट पर ध्यान देने की ज़रूरत है:

विजेट का लेआउट बनाएं

आपको अपने विजेट के लिए, एक्सएमएल में शुरुआती लेआउट तय करना होगा और उसे प्रोजेक्ट की res/layout/ डायरेक्ट्री में सेव करना होगा. ज़्यादा जानकारी के लिए, डिज़ाइन के लिए दिशा-निर्देश देखें.

अगर आपको लेआउट के बारे में पता है, तो विजेट का लेआउट बनाना आसान है. हालांकि, ध्यान रखें कि विजेट के लेआउट RemoteViews पर आधारित होते हैं. यह हर तरह के लेआउट या व्यू विजेट के साथ काम नहीं करता. RemoteViews के साथ काम करने वाले कस्टम व्यू या व्यू के सबक्लास का इस्तेमाल नहीं किया जा सकता.

RemoteViews में ViewStub का भी इस्तेमाल किया जा सकता है. यह एक ऐसा View है जो न दिखता है और इसका साइज़ शून्य होता है. इसका इस्तेमाल, रनटाइम के दौरान लेआउट के संसाधनों को धीरे-धीरे बढ़ाने के लिए किया जा सकता है.

स्टेटफ़ुल व्यवहार के लिए सहायता

Android 12 में, इन मौजूदा कॉम्पोनेंट का इस्तेमाल करके, स्टेटफ़ुल व्यवहार के लिए सहायता जोड़ी गई है:

विजेट अब भी स्टेटलेस है. आपके ऐप्लिकेशन को स्थिति सेव करनी होगी और स्थिति में बदलाव होने वाले इवेंट के लिए रजिस्टर करना होगा.

खरीदारी की सूची के विजेट का उदाहरण, जिसमें स्टेटफ़ुल व्यवहार दिखाया गया है
तीसरी इमेज. स्टेटफ़ुल व्यवहार का उदाहरण.

नीचे दिए गए कोड के उदाहरण में, इन कॉम्पोनेंट को लागू करने का तरीका बताया गया है.

Kotlin

// Check the view.
remoteView.setCompoundButtonChecked(R.id.my_checkbox, true)

// Check a radio group.
remoteView.setRadioGroupChecked(R.id.my_radio_group, R.id.radio_button_2)

// Listen for check changes. The intent has an extra with the key
// EXTRA_CHECKED that specifies the current checked state of the view.
remoteView.setOnCheckedChangeResponse(
        R.id.my_checkbox,
        RemoteViews.RemoteResponse.fromPendingIntent(onCheckedChangePendingIntent)
)

Java

// Check the view.
remoteView.setCompoundButtonChecked(R.id.my_checkbox, true);

// Check a radio group.
remoteView.setRadioGroupChecked(R.id.my_radio_group, R.id.radio_button_2);

// Listen for check changes. The intent has an extra with the key
// EXTRA_CHECKED that specifies the current checked state of the view.
remoteView.setOnCheckedChangeResponse(
    R.id.my_checkbox,
    RemoteViews.RemoteResponse.fromPendingIntent(onCheckedChangePendingIntent));

दो लेआउट उपलब्ध कराएं: पहला, res/layout-v31 में Android 12 या उसके बाद के वर्शन पर काम करने वाले डिवाइसों को टारगेट करने वाला और दूसरा, डिफ़ॉल्ट res/layout फ़ोल्डर में Android 11 या उससे पहले के वर्शन पर काम करने वाले डिवाइसों को टारगेट करने वाला.

गोल कोने लागू करना

Android 12 में, विजेट के गोल कोनों की त्रिज्या सेट करने के लिए, ये सिस्टम पैरामीटर जोड़े गए हैं:

  • system_app_widget_background_radius: विजेट के बैकग्राउंड के कोने का दायरा, जो कभी भी 28 dp से ज़्यादा नहीं होता.

  • system_app_widget_inner_radius: विजेट में मौजूद किसी भी व्यू के कोने का दायरा. यह बैकग्राउंड त्रिज्या से 8 dp कम है, ताकि 8 dp पैडिंग का इस्तेमाल करते समय, आइटम को सही तरीके से अलाइन किया जा सके.

यहां दिए गए उदाहरण में एक विजेट दिखाया गया है, जिसमें विजेट के कोने के लिए system_app_widget_background_radius और विजेट में व्यू के लिए system_app_widget_inner_radius का इस्तेमाल किया गया है.

विजेट के बैकग्राउंड और विजेट में मौजूद व्यू की त्रिज्या दिखाने वाला विजेट
चौथी इमेज. गोल कोने.

1 विजेट का कोना.

2 विजेट में मौजूद व्यू का कोना.

राउंड किए गए कोनों के लिए ज़रूरी बातें

  • तीसरे पक्ष के लॉन्चर और डिवाइस बनाने वाली कंपनियां, system_app_widget_background_radius पैरामीटर को 28 dp से छोटा कर सकती हैं. system_app_widget_inner_radius पैरामीटर हमेशा system_app_widget_background_radius की वैल्यू से 8 डीपी कम होता है.
  • अगर आपका विजेट @android:id/background का इस्तेमाल नहीं करता है या ऐसा बैकग्राउंड तय नहीं करता है जो आउटलाइन के आधार पर अपने कॉन्टेंट को क्लिप करता है, तो लॉन्चर अपने-आप बैकग्राउंड की पहचान करता है और 16 डीपी तक के गोल कोनों वाले रेक्टैंगल का इस्तेमाल करके विजेट को क्लिप करता है. ऐसा तब होता है, जब android:clipToOutline को true पर सेट किया गया हो. पक्का करें कि आपका विजेट, Android 12 के साथ काम करता हो लेख पढ़ें.

Android के पिछले वर्शन के साथ विजेट के काम करने के लिए, हमारा सुझाव है कि आप कस्टम एट्रिब्यूट तय करें. साथ ही, Android 12 के लिए उन्हें बदलने के लिए, कस्टम थीम का इस्तेमाल करें. इस बारे में, यहां दी गई एक्सएमएल फ़ाइलों के सैंपल में बताया गया है:

/values/attrs.xml

<resources>
  <attr name="backgroundRadius" format="dimension" />
</resources>

/values/styles.xml

<resources>
  <style name="MyWidgetTheme">
    <item name="backgroundRadius">@dimen/my_background_radius_dimen</item>
  </style>
</resources>

/values-31/styles.xml

<resources>
  <style name="MyWidgetTheme" parent="@android:style/Theme.DeviceDefault.DayNight">
    <item name="backgroundRadius">@android:dimen/system_app_widget_background_radius</item>
  </style>
</resources>

/drawable/my_widget_background.xml

<shape xmlns:android="http://schemas.android.com/apk/res/android"
  android:shape="rectangle">
  <corners android:radius="?attr/backgroundRadius" />
  ...
</shape>

/layout/my_widget_layout.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  ...
  android:background="@drawable/my_widget_background" />