অ্যাপ্লিকেশান এবং সিস্টেম অ্যাম্বিয়েন্ট মোড সর্বদা চালু থাকে৷

এই নির্দেশিকায় ব্যাখ্যা করা হয়েছে কীভাবে আপনার অ্যাপকে সর্বদা-চালু (always-on) রাখবেন, পাওয়ার স্টেট পরিবর্তনে কীভাবে প্রতিক্রিয়া জানাবেন, এবং ব্যাটারি সাশ্রয়ের পাশাপাশি ব্যবহারকারীকে একটি ভালো অভিজ্ঞতা দেওয়ার জন্য অ্যাপ্লিকেশনের আচরণ কীভাবে পরিচালনা করবেন।

কোনো অ্যাপকে ক্রমাগত দৃশ্যমান রাখলে তা ব্যাটারির আয়ুর ওপর উল্লেখযোগ্য প্রভাব ফেলে, তাই এই ফিচারটি যোগ করার সময় এর বিদ্যুৎ খরচের বিষয়টি বিবেচনা করুন।

মূল ধারণা

যখন একটি Wear OS অ্যাপ পূর্ণ স্ক্রিনে প্রদর্শিত হয়, তখন এটি দুটি পাওয়ার স্টেটের একটিতে থাকে:

  • ইন্টারেক্টিভ : একটি উচ্চ-ক্ষমতাসম্পন্ন অবস্থা যেখানে স্ক্রিনটি সম্পূর্ণ উজ্জ্বলতায় থাকে, যা ব্যবহারকারীকে পূর্ণাঙ্গ মিথস্ক্রিয়ার সুযোগ দেয়।
  • অ্যাম্বিয়েন্ট : একটি স্বল্প-শক্তি অবস্থা যেখানে শক্তি সাশ্রয়ের জন্য ডিসপ্লের আলো কমে যায়। এই অবস্থায়, আপনার অ্যাপের UI পুরো স্ক্রিন জুড়েই থাকে, কিন্তু সিস্টেম এটিকে ব্লার করে বা সময়ের মতো কোনো কন্টেন্ট এর উপর দেখিয়ে এর চেহারা পরিবর্তন করতে পারে। এটিকে অ্যাম্বিয়েন্ট মোডও বলা হয়।

অপারেটিং সিস্টেম এই অবস্থাগুলোর মধ্যে পরিবর্তন নিয়ন্ত্রণ করে।

অলওয়েজ-অন অ্যাপ হলো এমন একটি অ্যাপ্লিকেশন যা ইন্টারেক্টিভ এবং অ্যাম্বিয়েন্ট উভয় অবস্থাতেই কন্টেন্ট প্রদর্শন করে।

যখন ডিভাইসটি লো-পাওয়ার অ্যাম্বিয়েন্ট স্টেটে থাকা অবস্থায় কোনো অলওয়েজ-অন অ্যাপ তার নিজস্ব ইউআই প্রদর্শন করতে থাকে, তখন সেটিকে অ্যাম্বিঅ্যাক্টিভ মোডে থাকা বলা হয়।

সিস্টেম পরিবর্তন এবং ডিফল্ট আচরণ

যখন কোনো অ্যাপ ফোরগ্রাউন্ডে থাকে, তখন সিস্টেম ব্যবহারকারীর নিষ্ক্রিয়তার কারণে সৃষ্ট দুটি টাইমআউটের ওপর ভিত্তি করে পাওয়ার স্টেটের পরিবর্তন পরিচালনা করে।

  • টাইমআউট #১: ইন্টারেক্টিভ থেকে অ্যাম্বিয়েন্ট অবস্থায়: ব্যবহারকারী কিছুক্ষণ নিষ্ক্রিয় থাকার পর, ডিভাইসটি অ্যাম্বিয়েন্ট অবস্থায় প্রবেশ করে।
  • টাইমআউট #২: ওয়াচ ফেসে প্রত্যাবর্তন: আরও কিছুক্ষণ নিষ্ক্রিয় থাকার পর, সিস্টেম বর্তমান অ্যাপটি লুকিয়ে ওয়াচ ফেস প্রদর্শন করতে পারে।

সিস্টেমটি প্রথমবার অ্যাম্বিয়েন্ট স্টেটে প্রবেশ করার ঠিক পরেই, এর ডিফল্ট আচরণ Wear OS ভার্সন এবং আপনার অ্যাপের কনফিগারেশনের উপর নির্ভর করে:

  • Wear OS 5 এবং এর পূর্ববর্তী সংস্করণগুলিতে , সিস্টেম আপনার পজ করা অ্যাপ্লিকেশনের একটি ঝাপসা স্ক্রিনশট প্রদর্শন করে, যার উপরে সময়টি বসানো থাকে। নিম্নলিখিত ফ্লোচার্টে "AOD Lite" নোড দ্বারা এই অবস্থাটি দেখানো হয়েছে।
  • Wear OS 6 এবং এর পরবর্তী সংস্করণগুলিতে , যদি কোনো অ্যাপ SDK 36 বা তার নতুন সংস্করণকে টার্গেট করে, তবে সেটিকে অলওয়েজ-অন (always-on) হিসেবে গণ্য করা হয়। ডিসপ্লেটি অনুজ্জ্বল হয়ে যায়, কিন্তু অ্যাপ্লিকেশনটি চলতে থাকে এবং দৃশ্যমান থাকে। (আপডেটগুলি প্রতি মিনিটে একবারের মতো বিরলও হতে পারে।) এই অবস্থাটি নিম্নলিখিত ফ্লোচার্টে "Global AOD" নোড দ্বারা উপস্থাপিত হয়েছে।

পারিপার্শ্বিক অবস্থার জন্য আচরণ কাস্টমাইজ করুন

সিস্টেমের ডিফল্ট আচরণ নির্বিশেষে, সমস্ত Wear OS সংস্করণে আপনি AmbientLifecycleObserver ব্যবহার করে স্টেট ট্রানজিশনের কলব্যাক শোনার মাধ্যমে অ্যাম্বিয়েন্ট স্টেটে থাকাকালীন আপনার অ্যাপের চেহারা বা আচরণ কাস্টমাইজ করতে পারেন। নিম্নলিখিত ফ্লোচার্টে এই স্টেটটি "Ambiactive Mode" নোড দ্বারা দেখানো হয়েছে।

AmbientLifecycleObserver ব্যবহার করুন

অ্যাম্বিয়েন্ট মোড ইভেন্টগুলিতে প্রতিক্রিয়া জানাতে, AmbientLifecycleObserver ক্লাসটি ব্যবহার করুন:

  1. AmbientLifecycleObserver.AmbientLifecycleCallback ইন্টারফেসটি ইমপ্লিমেন্ট করুন। আপনার UI-কে লো-পাওয়ার স্টেটের জন্য সামঞ্জস্য করতে 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() কল করুন।

    override fun onDestroy() {
        super.onDestroy()
        lifecycle.removeObserver(ambientObserver)
    
        // ...
    }

যেসব ডেভেলপার Jetpack Compose ব্যবহার করেন, তাদের জন্য Horologist লাইব্রেরিটি AmbientAware composable নামক একটি সহায়ক ইউটিলিটি প্রদান করে, যা এই প্যাটার্নটির বাস্তবায়নকে সহজ করে তোলে।

পরিবেশ-সচেতন সময়পাঠ্য

কাস্টম অবজারভারের প্রয়োজনীয়তার ব্যতিক্রম হিসেবে, Wear OS 6-এ TimeText উইজেটটি অ্যাম্বিয়েন্ট-অ্যাওয়্যার। ডিভাইসটি অ্যাম্বিয়েন্ট অবস্থায় থাকলে এটি কোনো অতিরিক্ত কোড ছাড়াই প্রতি মিনিটে একবার স্বয়ংক্রিয়ভাবে আপডেট হয়।

পারিপার্শ্বিক আচরণের ফ্লোচার্ট

নিম্নলিখিত ফ্লোচার্টটি ব্যাখ্যা করে যে, ডিভাইসের Wear OS সংস্করণ, আপনার অ্যাপের targetSdkVersion এবং এটি AmbientLifecycleCallback প্রয়োগ করে কিনা, তার উপর ভিত্তি করে সিস্টেমটি কীভাবে পারিপার্শ্বিক আচরণ নির্ধারণ করে।

Wear OS অ্যাম্বিয়েন্ট মোডের সিদ্ধান্ত গ্রহণের কার্যপ্রণালী ব্যাখ্যা করে একটি ফ্লোচার্ট। এতে দেখানো হয়েছে কীভাবে ডিভাইসের OS ভার্সন এবং অ্যাপের কনফিগারেশন তিনটি ফলাফলের মধ্যে একটি নির্ধারণ করে: একটি ঝাপসা ওভারলে, গ্লোবাল AOD, অথবা অ্যাপ-পরিচালিত অ্যাম্বিঅ্যাক্টিভ মোড।
চিত্র ১. : Wear OS অ্যাম্বিয়েন্ট মোডের সিদ্ধান্ত গ্রহণের যুক্তির একটি ফ্লোচার্ট।

স্ক্রিন চালু থাকার সময়কাল নিয়ন্ত্রণ করুন

আপনার অ্যাপটি স্ক্রিনে কতক্ষণ থাকবে তা কীভাবে নিয়ন্ত্রণ করবেন, তা নিম্নলিখিত বিভাগগুলিতে বর্ণনা করা হয়েছে।

চলমান কার্যকলাপ বা লাইভ আপডেট চলাকালীন ওয়াচ ফেসে ফিরে আসা প্রতিরোধ করুন।

অ্যাম্বিয়েন্ট স্টেটে (টাইমআউট #২) একটি নির্দিষ্ট সময় থাকার পর, সিস্টেমটি সাধারণত ওয়াচ ফেসে ফিরে আসবে। ব্যবহারকারী সিস্টেম সেটিংসে টাইমআউটের সময়কাল নির্ধারণ করতে পারেন। কিছু নির্দিষ্ট ব্যবহারের ক্ষেত্রে, যেমন কোনো ব্যবহারকারীর ওয়ার্কআউট ট্র্যাক করার জন্য, একটি অ্যাপকে আরও বেশি সময় ধরে দৃশ্যমান থাকার প্রয়োজন হতে পারে।

Wear OS 5 এবং এর পরবর্তী সংস্করণগুলিতে, আপনি একটি 'Ongoing Activity' প্রয়োগ করে এটি প্রতিরোধ করতে পারেন। যদি আপনার অ্যাপ কোনো চলমান ইউজার টাস্ক, যেমন একটি ওয়ার্কআউট সেশন, সম্পর্কে তথ্য প্রদর্শন করে, তবে টাস্কটি শেষ না হওয়া পর্যন্ত আপনার অ্যাপটিকে দৃশ্যমান রাখতে আপনি 'Ongoing Activity' API ব্যবহার করতে পারেন। যদি কোনো ইউজার নিজে থেকে ওয়াচফেসে ফিরে আসেন, তবে 'Ongoing Activity' ইন্ডিকেটরটি তাদের জন্য এক-ট্যাপে আপনার অ্যাপে ফিরে আসার একটি উপায় প্রদান করে।

বিকল্পভাবে, Wear OS 7 এবং এর পরবর্তী সংস্করণগুলিতে, আপনি Ongoing Activity-এর পরিবর্তে Live Update ব্যবহার করতে পারেন। পূর্ববর্তী সংস্করণের সাথে সামঞ্জস্যতা বজায় রাখার জন্য, Wear OS 6 বা তার পূর্ববর্তী সংস্করণ চালিত ডিভাইসগুলিতে Ongoing Activity সমর্থন করা অব্যাহত রাখুন।

এটি বাস্তবায়ন করতে, চলমান নোটিফিকেশনের টাচ ইন্টেন্টকে অবশ্যই আপনার অলওয়েজ-অন অ্যাক্টিভিটির দিকে নির্দেশ করতে হবে, যেমনটি নিম্নলিখিত কোড স্নিপেটে দেখানো হয়েছে:

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)

val notification = notificationBuilder.build()

স্ক্রিন চালু রাখুন এবং পারিপার্শ্বিক অবস্থা প্রতিরোধ করুন

বিরল ক্ষেত্রে, ডিভাইসটিকে অ্যাম্বিয়েন্ট স্টেটে প্রবেশ করা থেকে সম্পূর্ণভাবে বিরত রাখার প্রয়োজন হতে পারে। অর্থাৎ, টাইমআউট #১ এড়ানোর জন্য। এটি করার জন্য, আপনি FLAG_KEEP_SCREEN_ON উইন্ডো ফ্ল্যাগটি ব্যবহার করতে পারেন। এটি একটি ওয়েক লক হিসেবে কাজ করে, যা ডিভাইসটিকে ইন্টারেক্টিভ স্টেটে রাখে। এটি অত্যন্ত সতর্কতার সাথে ব্যবহার করুন, কারণ এটি ব্যাটারির আয়ুকে মারাত্মকভাবে প্রভাবিত করে।

অ্যাম্বিয়েন্ট মোডের জন্য সুপারিশসমূহ

অ্যাম্বিয়েন্ট মোডে সেরা ব্যবহারকারীর অভিজ্ঞতা প্রদান করতে এবং শক্তি সাশ্রয় করতে, এই ডিজাইন নির্দেশিকাগুলো অনুসরণ করুন। এই সুপারিশগুলো বিভ্রান্তিকর তথ্য প্রতিরোধ করে ও দৃশ্যমান জঞ্জাল কমিয়ে একটি সুস্পষ্ট ব্যবহারকারীর অভিজ্ঞতাকে অগ্রাধিকার দেয় এবং একই সাথে ডিসপ্লের শক্তি অপ্টিমাইজ করে।

  • ভিজ্যুয়াল জঞ্জাল কমান এবং ডিসপ্লে পাওয়ার সাশ্রয় করুন। একটি পরিচ্ছন্ন, মিনিমালিস্ট ইউআই ব্যবহারকারীকে সংকেত দেয় যে অ্যাপটি কম-পাওয়ার অবস্থায় আছে এবং উজ্জ্বল পিক্সেল সীমিত করার মাধ্যমে উল্লেখযোগ্য পরিমাণে ব্যাটারি সাশ্রয় করে।
    • স্ক্রিনের কমপক্ষে ৮৫% কালো রাখুন।
    • শুধুমাত্র সবচেয়ে গুরুত্বপূর্ণ তথ্য দেখান এবং গৌণ বিবরণ ইন্টারেক্টিভ ডিসপ্লেতে সরিয়ে দিন।
    • বড় আইকন বা বাটনের ক্ষেত্রে সলিড ফিলের পরিবর্তে আউটলাইন ব্যবহার করুন।
    • একরঙা বড় ব্লক এবং অকার্যকর ব্র্যান্ডিং বা ব্যাকগ্রাউন্ড ছবি পরিহার করুন।
  • পুরনো ডাইনামিক ডেটা পরিচালনা করুন
    • শক্তি সাশ্রয়ের জন্য onUpdateAmbient() কলব্যাকটি শুধুমাত্র নির্দিষ্ট সময় পর পর—সাধারণত প্রতি মিনিটে একবার—চালু করা হয়। এই সীমাবদ্ধতার কারণে, যে কোনো ডেটা যা ঘন ঘন পরিবর্তিত হয়—যেমন স্টপওয়াচ, হার্ট রেট বা ওয়ার্কআউটের দূরত্ব—তা আপডেটের মধ্যবর্তী সময়ে পুরনো হয়ে যায়। বিভ্রান্তিকর এবং ভুল তথ্য প্রদর্শন এড়াতে, onEnterAmbient কলব্যাকের জন্য লিসেন করুন এবং এই লাইভ মানগুলিকে স্ট্যাটিক প্লেসহোল্ডার কন্টেন্ট দিয়ে প্রতিস্থাপন করুন, যেমন --
  • একটি সামঞ্জস্যপূর্ণ বিন্যাস বজায় রাখুন
    • একটি মসৃণ রূপান্তর তৈরি করতে ইন্টারেক্টিভ এবং অ্যাম্বিয়েন্ট মোড জুড়ে উপাদানগুলিকে একই অবস্থানে রাখুন।
    • সর্বদা সময় দেখান।
  • প্রসঙ্গ সম্পর্কে সচেতন হন
    • ডিভাইসটি অ্যাম্বিয়েন্ট মোডে প্রবেশ করার সময় যদি ব্যবহারকারী কোনো সেটিংস বা কনফিগারেশন স্ক্রিনে থাকেন, তাহলে সেটিংস ভিউয়ের পরিবর্তে আপনার অ্যাপ থেকে আরও প্রাসঙ্গিক একটি স্ক্রিন দেখানোর কথা বিবেচনা করুন।
  • ডিভাইস-নির্দিষ্ট প্রয়োজনীয়তাগুলি পরিচালনা করুন
    • onEnterAmbient() এ পাস করা AmbientDetails অবজেক্টে:
      • যদি deviceHasLowBitAmbient true হয়, তাহলে যেখানে সম্ভব অ্যান্টি-অ্যালিয়াসিং নিষ্ক্রিয় করুন।
      • যদি burnInProtectionRequired true হয়, তাহলে স্ক্রিন বার্ন-ইন প্রতিরোধ করতে UI এলিমেন্টগুলোকে পর্যায়ক্রমে সামান্য সরান এবং নিরেট সাদা অংশ পরিহার করুন।

ডিবাগিং এবং টেস্টিং

ডিভাইস অ্যাম্বিয়েন্ট মোডে থাকাকালীন আপনার অ্যাপটি কীভাবে আচরণ করে, তা তৈরি বা পরীক্ষা করার সময় এই 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. ইন্টারেক্টিভ এবং অ্যাম্বিয়েন্ট অবস্থার মধ্যে UI পরিবর্তন, যেমন স্ক্রিন ম্লান করা এবং অপ্রয়োজনীয় ডেটা মুছে ফেলা, পরিচালনা করার জন্য একটি AmbientLifecycleObserver প্রয়োগ করুন।
  2. সর্বোত্তম অনুশীলন অনুসরণ করে অ্যাম্বিয়েন্ট স্টেটের জন্য একটি নতুন স্বল্প-শক্তিসম্পন্ন লেআউট তৈরি করুন।
  3. ওয়ার্কআউট চলাকালীন সিস্টেমকে ওয়াচ ফেসে ফিরে আসা থেকে বিরত রাখতে অনগোয়িং অ্যাক্টিভিটি এপিআই (অথবা Wear OS 7 এবং তার পরবর্তী সংস্করণগুলোতে লাইভ আপডেট ) ব্যবহার করুন।

সম্পূর্ণ বাস্তবায়নের জন্য, গিটহাবে থাকা কম্পোজ-ভিত্তিক এক্সারসাইজ স্যাম্পলটি দেখুন। এই স্যাম্পলটি কম্পোজে অ্যাম্বিয়েন্ট মোড হ্যান্ডলিং সহজ করার জন্য হরোলজিস্ট লাইব্রেরির AmbientAware কম্পোজেবল-এর ব্যবহারও প্রদর্শন করে।