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

এই নির্দেশিকাটি ব্যাখ্যা করে যে কীভাবে আপনার অ্যাপকে সর্বদা চালু রাখতে হয়, কীভাবে পাওয়ার স্টেট ট্রানজিশনে প্রতিক্রিয়া জানাতে হয় এবং ব্যাটারি সংরক্ষণের সময় একটি ভাল ব্যবহারকারীর অভিজ্ঞতা প্রদানের জন্য কীভাবে অ্যাপ্লিকেশন আচরণ পরিচালনা করতে হয়।

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

মূল ধারণা

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

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

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

একটি সর্বদা-অন অ্যাপ হল একটি অ্যাপ্লিকেশন যা ইন্টারেক্টিভ এবং অ্যাম্বিয়েন্ট উভয় অবস্থায়ই সামগ্রী প্রদর্শন করে৷

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

সিস্টেম ট্রানজিশন এবং ডিফল্ট আচরণ

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

  • টাইমআউট #1: অ্যাম্বিয়েন্ট স্টেটে ইন্টারেক্টিভ: ব্যবহারকারীর নিষ্ক্রিয়তার পর, ডিভাইসটি অ্যাম্বিয়েন্ট স্টেটে প্রবেশ করে।
  • টাইমআউট #2: ঘড়ির মুখটিতে ফিরে যান: আরও একটি নিষ্ক্রিয়তার পরে, সিস্টেম বর্তমান অ্যাপটি লুকিয়ে রাখতে পারে এবং ঘড়ির মুখ প্রদর্শন করতে পারে।

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

  • Wear OS 5 এবং তার নিচের সংস্করণে , সিস্টেমটি আপনার বিরতি দেওয়া অ্যাপ্লিকেশনটির একটি ঝাপসা স্ক্রিনশট প্রদর্শন করে, উপরে ওভারলেড করা সময় সহ।
  • Wear OS 6 এবং উচ্চতর সংস্করণে , যদি কোনো অ্যাপ SDK 36 বা তার থেকে নতুনকে লক্ষ্য করে, তাহলে এটি সর্বদা চালু বলে বিবেচিত হয়। ডিসপ্লেটি ম্লান হয়ে গেছে, কিন্তু অ্যাপ্লিকেশনটি চলতে থাকে এবং দৃশ্যমান থাকে। (আপডেট প্রতি মিনিটে একবারের মতো বিরল হতে পারে।)

অ্যাম্বিয়েন্ট স্টেটের জন্য আচরণ কাস্টমাইজ করুন

ডিফল্ট সিস্টেম আচরণ যাই হোক না কেন, সমস্ত Wear OS সংস্করণে আপনি অ্যাম্বিয়েন্ট স্টেটে থাকাকালীন অ্যাম্বিয়েন্ট AmbientLifecycleObserver ব্যবহার করে স্টেট ট্রানজিশনে কলব্যাক শোনার জন্য আপনার অ্যাপের চেহারা বা আচরণ কাস্টমাইজ করতে পারেন।

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() কল করুন।

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

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

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

স্ক্রিন-অন সময়কাল নিয়ন্ত্রণ করুন

আপনার অ্যাপ কতক্ষণ স্ক্রিনে থাকবে তা কীভাবে পরিচালনা করবেন তা নিম্নলিখিত বিভাগগুলি বর্ণনা করে৷

একটি চলমান কার্যকলাপের মাধ্যমে ঘড়ির মুখে ফিরে আসা প্রতিরোধ করুন

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

Wear OS 5 এবং উচ্চতর ডিভাইসে, আপনি একটি চলমান কার্যকলাপ প্রয়োগ করে এটি প্রতিরোধ করতে পারেন। যদি আপনার অ্যাপটি একটি চলমান ব্যবহারকারীর টাস্ক সম্পর্কে তথ্য প্রদর্শন করে, যেমন একটি ওয়ার্কআউট সেশন, আপনি টাস্ক শেষ না হওয়া পর্যন্ত আপনার অ্যাপকে দৃশ্যমান রাখতে চলমান কার্যকলাপ 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() কলব্যাক শুধুমাত্র প্রয়োজনীয় আপডেটের জন্য ব্যবহার করা উচিত, সাধারণত প্রতি মিনিটে একবার।
  • একটি সামঞ্জস্যপূর্ণ বিন্যাস বজায় রাখুন
    • একটি মসৃণ রূপান্তর তৈরি করতে ইন্টারেক্টিভ এবং অ্যাম্বিয়েন্ট মোড জুড়ে উপাদানগুলিকে একই অবস্থানে রাখুন।
    • সবসময় সময় দেখান।
  • প্রসঙ্গ সচেতন হন
    • ডিভাইসটি অ্যাম্বিয়েন্ট মোডে প্রবেশ করার সময় ব্যবহারকারী যদি সেটিংস বা কনফিগারেশন স্ক্রিনে থাকে, তাহলে সেটিংস ভিউয়ের পরিবর্তে আপনার অ্যাপ থেকে আরও প্রাসঙ্গিক স্ক্রীন দেখানোর কথা বিবেচনা করুন।
  • ডিভাইস-নির্দিষ্ট প্রয়োজনীয়তা হ্যান্ডেল
    • AmbientDetails অবজেক্টে onEnterAmbient() এ পাস করা হয়েছে:
      • যদি 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. ওয়ার্কআউটের সময়কালের জন্য চলমান অ্যাক্টিভিটি API ব্যবহার করুন যাতে সিস্টেমটি ঘড়ির মুখে ফিরে না আসে।

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