हमेशा चालू रहने वाले ऐप्लिकेशन और सिस्टम ऐंबियंट मोड

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

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

खास कॉन्सेप्ट

जब Wear OS ऐप्लिकेशन को फ़ुल स्क्रीन पर दिखाया जाता है, तो वह दो पावर स्टेट में से किसी एक में होता है:

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

ऑपरेटिंग सिस्टम, इन स्थितियों के बीच ट्रांज़िशन को कंट्रोल करता है.

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

जब कोई ऐप्लिकेशन, डिवाइस के कम बैटरी मोड वाले ऐंबियंट मोड में होने पर भी अपना यूज़र इंटरफ़ेस (यूआई) दिखाता रहता है, तो उसे ऐंबियैक्टिव मोड में होना कहा जाता है.

सिस्टम ट्रांज़िशन और डिफ़ॉल्ट बिहेवियर

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

  • टाइम आउट #1: इंटरैक्टिव से ऐंबियंट मोड में स्विच करना: जब उपयोगकर्ता कुछ समय तक डिवाइस का इस्तेमाल नहीं करता है, तब डिवाइस ऐंबियंट मोड में स्विच हो जाता है.
  • टाइमआउट #2: वॉच फ़ेस पर वापस जाना: कुछ समय तक कोई गतिविधि न होने पर, सिस्टम मौजूदा ऐप्लिकेशन को छिपा सकता है और वॉच फ़ेस दिखा सकता है.

सिस्टम के Ambient मोड में जाने के तुरंत बाद, डिफ़ॉल्ट व्यवहार Wear OS के वर्शन और आपके ऐप्लिकेशन के कॉन्फ़िगरेशन पर निर्भर करता है:

  • Wear OS 5 और इससे पहले के वर्शन पर, सिस्टम आपके रोके गए ऐप्लिकेशन का धुंधला स्क्रीनशॉट दिखाता है. इस पर समय की जानकारी भी दिखती है.
  • Wear OS 6 और इसके बाद के वर्शन पर, अगर कोई ऐप्लिकेशन SDK 36 या उसके बाद के वर्शन को टारगेट करता है, तो उसे हमेशा चालू रहने वाला ऐप्लिकेशन माना जाता है. डिसप्ले की रोशनी कम हो जाती है, लेकिन ऐप्लिकेशन चलता रहता है और दिखता रहता है. (अपडेट, हर मिनट में एक बार से ज़्यादा बार नहीं किए जा सकते.)

ऐंबियंट स्टेट के लिए, व्यवहार को पसंद के मुताबिक बनाना

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

AmbientLifecycleObserver का इस्तेमाल करना

ऐंबियंट मोड इवेंट पर प्रतिक्रिया देने के लिए, AmbientLifecycleObserver क्लास का इस्तेमाल करें:

  1. AmbientLifecycleObserver.AmbientLifecycleCallback इंटरफ़ेस लागू करें. बैटरी कम होने पर यूज़र इंटरफ़ेस (यूआई) को अडजस्ट करने के लिए, onEnterAmbient() तरीके का इस्तेमाल करें. साथ ही, यूज़र इंटरफ़ेस (यूआई) को पूरी तरह से इंटरैक्टिव डिसप्ले पर वापस लाने के लिए, onExitAmbient() तरीके का इस्तेमाल करें.

    val ambientCallback = object : AmbientLifecycleObserver.AmbientLifecycleCallback {
        override fun onEnterAmbient(ambientDetails: AmbientLifecycleObserver.AmbientDetails) {
            // ... Called when moving from interactive mode into ambient mode.
            // Adjust UI for low-power state: dim colors, hide non-essential elements.
        }
    
        override fun onExitAmbient() {
            // ... Called when leaving ambient mode, back into interactive mode.
            // Restore full UI.
        }
    
        override fun onUpdateAmbient() {
            // ... Called by the system periodically (typically once per minute)
            // to allow the app to update its display while in ambient mode.
        }
    }
    
  2. एक AmbientLifecycleObserver बनाएं और उसे अपनी गतिविधि या कंपोज़ेबल के लाइफ़साइकल के साथ रजिस्टर करें.

    private val ambientObserver = AmbientLifecycleObserver(activity, ambientCallback)
    
    override fun onCreate(savedInstanceState: Bundle) {
        super.onCreate(savedInstanceState)
        lifecycle.addObserver(ambientObserver)
    
        // ...
    }
    
  3. onDestroy() में ऑब्ज़र्वर को हटाने के लिए, removeObserver() को कॉल करें.

Jetpack Compose का इस्तेमाल करने वाले डेवलपर के लिए, Horologist लाइब्रेरी एक काम की सुविधा उपलब्ध कराती है. यह AmbientAware कंपोज़ेबल है, जो इस पैटर्न को लागू करने की प्रोसेस को आसान बनाती है.

आस-पास की आवाज़ के हिसाब से टाइम टेक्स्ट

Wear OS 6 पर, TimeText विजेट को कस्टम ऑब्ज़र्वर की ज़रूरत नहीं होती. यह विजेट, परिवेश के हिसाब से काम करता है. जब डिवाइस ऐम्बिएंट मोड में होता है, तब यह हर मिनट में एक बार अपने-आप अपडेट होता है. इसके लिए, किसी अतिरिक्त कोड की ज़रूरत नहीं होती.

स्क्रीन चालू रहने की अवधि को कंट्रोल करना

यहां दिए गए सेक्शन में, यह मैनेज करने का तरीका बताया गया है कि आपका ऐप्लिकेशन स्क्रीन पर कितनी देर तक दिखे.

'चल रही गतिविधि' सुविधा का इस्तेमाल करके, स्मार्टवॉच की होम स्क्रीन पर वापस आने से रोकना

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

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

इसे लागू करने के लिए, चालू सूचना के टच इंटेंट को आपकी हमेशा चालू रहने वाली गतिविधि की ओर ले जाना चाहिए. जैसा कि यहां दिए गए कोड स्निपेट में दिखाया गया है:

private fun createNotification(): Notification {
    val activityIntent =
        Intent(this, AlwaysOnActivity::class.java).apply {
            flags = Intent.FLAG_ACTIVITY_SINGLE_TOP
        }

    val pendingIntent =
        PendingIntent.getActivity(
            this,
            0,
            activityIntent,
            PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE,
        )

    val notificationBuilder =
        NotificationCompat.Builder(this, CHANNEL_ID)
            // ...
            // ...
            .setOngoing(true)

    // ...

    val ongoingActivity =
        OngoingActivity.Builder(applicationContext, NOTIFICATION_ID, notificationBuilder)
            // ...
            // ...
            .setTouchIntent(pendingIntent)
            .build()

    ongoingActivity.apply(applicationContext)

    return notificationBuilder.build()
}

स्क्रीन को चालू रखें और ऐंबियंट स्टेट को रोकें

कुछ मामलों में, आपको डिवाइस को ऐंबियंट मोड में जाने से पूरी तरह रोकना पड़ सकता है. इसका मतलब है कि टाइम आउट #1 से बचने के लिए. इसके लिए, FLAG_KEEP_SCREEN_ON विंडो फ़्लैग का इस्तेमाल किया जा सकता है. यह वेक लॉक के तौर पर काम करता है. इससे डिवाइस इंटरैक्टिव मोड में रहता है. इस सुविधा का इस्तेमाल बहुत सावधानी से करें, क्योंकि इससे बैटरी लाइफ़ पर काफ़ी असर पड़ता है.

ऐंबियंट मोड के लिए सुझाव

उपयोगकर्ताओं को बेहतरीन अनुभव देने और ऐंबियंट मोड में बैटरी की बचत करने के लिए, डिज़ाइन से जुड़े इन दिशा-निर्देशों का पालन करें. इन सुझावों में, लोगों को बेहतर अनुभव देने को प्राथमिकता दी जाती है. इसके लिए, गुमराह करने वाली जानकारी को रोका जाता है और विज़ुअल क्लटर को कम किया जाता है. साथ ही, डिसप्ले पावर को ऑप्टिमाइज़ किया जाता है.

  • विज़ुअल क्लटर कम करें और डिसप्ले पावर बढ़ाएं. साफ़ और कम से कम यूज़र इंटरफ़ेस (यूआई) से उपयोगकर्ता को यह पता चलता है कि ऐप्लिकेशन कम बैटरी इस्तेमाल कर रहा है. साथ ही, चमकदार पिक्सल को सीमित करके, बैटरी को काफ़ी हद तक बचाया जा सकता है.
    • स्क्रीन के कम से कम 85% हिस्से को काला रखें.
    • सिर्फ़ सबसे ज़रूरी जानकारी दिखाएं. साथ ही, अन्य जानकारी को इंटरैक्टिव डिसप्ले पर ले जाएं.
    • बड़े आइकॉन या बटन के लिए, सॉलिड फ़िल के बजाय आउटलाइन का इस्तेमाल करें.
    • एक ही रंग के बड़े ब्लॉक और काम न करने वाली ब्रैंडिंग या बैकग्राउंड इमेज का इस्तेमाल न करें.
  • पुराने डाइनैमिक डेटा को मैनेज करना
    • onUpdateAmbient() कॉलबैक को सिर्फ़ समय-समय पर शुरू किया जाता है. आम तौर पर, इसे हर मिनट में एक बार शुरू किया जाता है, ताकि बैटरी की बचत हो सके. इस सीमा की वजह से, ऐसा डेटा जो बार-बार बदलता है वह अपडेट के बीच पुराना हो जाता है. जैसे, स्टॉपवॉच, धड़कन की दर या कसरत की दूरी. गुमराह करने वाली और गलत जानकारी दिखाने से बचने के लिए, onEnterAmbient कॉलबैक सुनें. इसके बाद, लाइव वैल्यू को स्टैटिक प्लेसहोल्डर कॉन्टेंट से बदलें. जैसे, --.
  • एक जैसा लेआउट बनाए रखें
    • स्मूद ट्रांज़िशन बनाने के लिए, इंटरैक्टिव और ऐम्बिएंट मोड में एलिमेंट को एक ही जगह पर रखें.
    • समय हमेशा दिखे.
  • कॉन्टेक्स्ट के बारे में जानकारी देना
    • अगर डिवाइस के ऐंबियंट मोड में आने के दौरान उपयोगकर्ता सेटिंग या कॉन्फ़िगरेशन स्क्रीन पर था, तो सेटिंग व्यू के बजाय अपने ऐप्लिकेशन से ज़्यादा काम की स्क्रीन दिखाएं.
  • डिवाइस के हिसाब से ज़रूरी शर्तों को पूरा करना
    • onEnterAmbient() को पास किए गए AmbientDetails ऑब्जेक्ट में:
      • अगर deviceHasLowBitAmbient true है, तो जहां हो सके वहां ऐंटी-एलियासिंग बंद करें.
      • अगर burnInProtectionRequired true है, तो स्क्रीन बर्न-इन से बचने के लिए, यूज़र इंटरफ़ेस (यूआई) के एलिमेंट को समय-समय पर थोड़ा-बहुत बदलें. साथ ही, पूरी तरह से सफ़ेद एरिया से बचें.

डीबग करना और जांच करना

डिवाइस के ऐंबियंट मोड में होने पर, आपका ऐप्लिकेशन कैसा काम करता है, यह डेवलप या टेस्ट करते समय, adb निर्देश काम आ सकते हैं:

# put device in ambient mode if the always on display is enabled in settings
# (and not disabled by other settings, such as theatre mode)
$ adb shell input keyevent KEYCODE_SLEEP

# put device in interactive mode
$ adb shell input keyevent KEYCODE_WAKEUP

उदाहरण: वर्कआउट करने में मदद करने वाला ऐप्लिकेशन

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

इसके लिए, डेवलपर को यह काम करना होगा:

  1. इंटरैक्टिव और ऐम्बिएंट मोड के बीच यूज़र इंटरफ़ेस (यूआई) में होने वाले बदलावों को मैनेज करने के लिए, AmbientLifecycleObserver लागू करें. जैसे, स्क्रीन की रोशनी कम करना और गैर-ज़रूरी डेटा हटाना.
  2. ऐम्बिएंट मोड के लिए, कम बैटरी इस्तेमाल करने वाला नया लेआउट बनाएं. इसके लिए, सबसे सही तरीकों का पालन करें.
  3. कसरत के दौरान, Ongoing Activity API का इस्तेमाल करें, ताकि सिस्टम को स्मार्टवॉच की होम स्क्रीन पर वापस जाने से रोका जा सके.

इसे पूरी तरह से लागू करने के लिए, GitHub पर एक्सरसाइज़ का Compose पर आधारित सैंपल देखें. इस सैंपल में, Compose में ऐंबियंट मोड को आसानी से हैंडल करने के लिए, Horologist लाइब्रेरी से AmbientAware कंपोज़ेबल का इस्तेमाल करने का तरीका भी दिखाया गया है.