এই নির্দেশিকা থেকে আপনি জানতে পারবেন কীভাবে আপনার অ্যাপকে সবসময় চালু রাখতে হয়, কীভাবে পাওয়ার স্টেট ট্রানজিশনে প্রতিক্রিয়া জানাতে হয় এবং কীভাবে ব্যাটারি সেভ করার পাশাপাশি ব্যবহারকারীকে ভাল অভিজ্ঞতা প্রদান করার জন্য অ্যাপ্লিকেশনের আচরণ ম্যানেজ করতে হয়।
কোনও অ্যাপকে ক্রমাগত দৃশ্যমান করে রাখলে ব্যাটারির আয়ুর উপর উল্লেখযোগ্য প্রভাব পড়ে, তাই এই ফিচার যোগ করার সময় বিদ্যুৎ খরচের বিষয়টি বিবেচনা করুন।
মূল ধারণা
Wear OS অ্যাপ ফুল-স্ক্রিনে দেখানো হলে, সেটি দুটি পাওয়ার স্টেটের মধ্যে একটিতে থাকে:
- ইন্ট্যার্যাক্টিভ: এটি হল হাই-পাওয়ার স্টেট যেখানে স্ক্রিন সম্পূর্ণ উজ্জ্বলতায় থাকে, ব্যবহারকারীকে সম্পূর্ণ ইন্টার্যাক্ট করতে দেয়।
- অ্যাম্বিয়েন্ট: এটি হল কম পাওয়ারের একটি স্টেট যেখানে পাওয়ার বাঁচানোর জন্য ডিসপ্লেটি ডিম হয়ে যায়। এই অবস্থায়, আপনার অ্যাপের UI এখনও পুরো স্ক্রিন জুড়ে থাকে, কিন্তু সিস্টেম সেটির চেহারা পরিবর্তন করতে পারে, যেমন, সেটি অস্পষ্ট করে দিতে পারে অথবা সময় দেখানোর মতো ওভারলে কন্টেন্ট দেখাতে পারে। এটি অ্যাম্বিয়েন্ট মোড নামেও পরিচিত।
অপারেটিং সিস্টেম এই স্টেটগুলির মধ্যে ট্রানজিশন কন্ট্রোল করে।
সর্বদা-চালু থাকা অ্যাপ হল এমন একটি অ্যাপ্লিকেশন যা ইন্টার্যাক্টিভ এবং অ্যাম্বিয়েন্ট, এই দুটি স্টেটে কন্টেন্ট দেখায়।
ডিভাইস যখন কম পাওয়ার অ্যাম্বিয়েন্ট স্টেটে থাকে, তখন কোনও অলওয়েজ-অন অ্যাপ যদি নিজের UI দেখানো চালিয়ে যায়, তাহলে সেটি অ্যাম্বিয়্যাক্টিভ মোডে আছে বলে বর্ণনা করা হয়।
সিস্টেম ট্রানজিশন ও ডিফল্ট আচরণ
কোনও অ্যাপ ফোরগ্রাউন্ডে থাকলে, ব্যবহারকারীর ইনঅ্যাক্টিভিটি থেকে ট্রিগার হওয়া দুটি টাইমআউটের উপর ভিত্তি করে সিস্টেম পাওয়ার স্টেট ট্রানজিশন ম্যানেজ করে।
- টাইম-আউট #১: ইন্ট্যার্যাক্টিভ থেকে অ্যাম্বিয়েন্ট স্টেট: ব্যবহারকারী অ্যাক্টিভ না থাকলে, ডিভাইস অ্যাম্বিয়েন্ট স্টেটে চলে যায়।
- টাইমআউট #২: ওয়াচ ফেসে ফিরে যাওয়া: আরও কিছু সময় অ্যাক্টিভিটি না থাকলে, সিস্টেম বর্তমান অ্যাপটি লুকিয়ে ওয়াচ ফেস দেখাতে পারে।
সিস্টেম প্রথম ট্রানজিশন সম্পূর্ণ করে অ্যাম্বিয়েন্ট স্টেটে যাওয়ার সাথে সাথেই, ডিফল্ট আচরণ Wear OS ভার্সন এবং আপনার অ্যাপের কনফিগারেশনের উপর নির্ভর করে:
- Wear OS 5 ও তার আগের ভার্সনে, সিস্টেম আপনার পজ করা অ্যাপ্লিকেশনের একটি অস্পষ্ট স্ক্রিনশট দেখায়, যার উপরে সময় ওভারলে করা থাকে। এই স্টেটকে নিম্নলিখিত ফ্লোচার্টে "AOD Lite" নোড দ্বারা দেখানো হয়।
- Wear OS 6 ও তার পরবর্তী যেকোনও ভার্সনে, কোনও অ্যাপ SDK 36 বা তার পরবর্তী যেকোনও ভার্সনকে টার্গেট করলে, সেটি সর্বদা চালু আছে বলে ধরে নেওয়া হয়। ডিসপ্লে অস্পষ্ট হয়ে যায়, কিন্তু অ্যাপ্লিকেশন চলতে থাকে এবং দেখা যায়। (আপডেট প্রতি মিনিটে একবারের মতো কম ঘন ঘন হতে পারে।) এই স্টেটকে নিম্নলিখিত ফ্লোচার্টে "গ্লোবাল AOD" নোড দ্বারা দেখানো হয়।
অ্যাম্বিয়েন্ট স্টেটের আচরণ কাস্টমাইজ করা
ডিফল্ট সিস্টেম আচরণ যাই হোক না কেন, সব Wear OS ভার্সনে আপনি
অ্যাম্বিয়েন্ট স্টেটে থাকাকালীন LocalAmbientModeManager ব্যবহার করে
Wear OS-এ Jetpack Compose-এ স্টেট ট্রানজিশন পর্যবেক্ষণ করার মাধ্যমে
আপনার অ্যাপের চেহারা বা আচরণ কাস্টমাইজ করতে পারবেন। এই স্টেটকে নিম্নলিখিত ফ্লোচার্টে "Ambiactive মোড"
নোড দিয়ে দেখানো হয়েছে।
অ্যাম্বিয়েন্ট স্টেট পর্যবেক্ষণ করা
Wear OS-এ Jetpack Compose-এ অ্যাম্বিয়েন্ট মোড ইভেন্টে প্রতিক্রিয়া জানাতে:
সিস্টেমের অ্যাম্বিয়েন্ট মোডের স্ট্যাটাসে হওয়া পরিবর্তনগুলি লক্ষ্য করতে
LocalAmbientModeManagerব্যবহার করুন এবং সেই অনুযায়ী আপনার কম্পোজ করার উপযুক্ত আইটেম অ্যাডজাস্ট করুন।AmbientMode.Ambientস্টেটে কম পাওয়ার মোডে অ্যাডজাস্ট করার জন্য আপনার কম্পোনেন্ট কনফিগার করুন এবংAmbientMode.Interactiveস্টেটে এটিকে সম্পূর্ণ ইন্ট্যার্যাক্টিভ ডিসপ্লেতে রিস্টোর করুন।// In a production application, the AmbientModeManager should be instantiated and provided at // the highest level of the Compose hierarchy (typically in the host Activity's setContent // block) using a CompositionLocalProvider. This ensures proper lifecycle management and // broad accessibility. // For this self-contained demo, AmbientModeManager is created and provided locally: val activityAmbientModeManager = rememberAmbientModeManager() CompositionLocalProvider(LocalAmbientModeManager provides activityAmbientModeManager) { val ambientModeManager = LocalAmbientModeManager.current val ambientMode = ambientModeManager?.currentAmbientMode if (ambientModeManager != null) { ambientModeManager.AmbientTickEffect { // While device is in ambient mode, update properties every minute or so // ... } } // ... val ambientModeName = when (ambientMode) { is AmbientMode.Interactive -> "Interactive" is AmbientMode.Ambient -> "Ambient" else -> "Unknown" } Text(text = "$ambientModeName Mode") // ... }
অ্যাম্বিয়েন্ট আচরণ সংক্রান্ত ফ্লোচার্ট
ডিভাইসের Wear OS ভার্সন, আপনার অ্যাপের targetSdkVersion এবং এটি অ্যাম্বিয়েন্ট স্টেট ট্রানজিশন (LocalAmbientModeManager বা AmbientLifecycleCallback ব্যবহার করে) লক্ষ্য করে কিনা, এই
বিষয়গুলির উপর ভিত্তি করে সিস্টেম কীভাবে অ্যাম্বিয়েন্ট
বিহেভিয়ার নির্ধারণ করে তা নিম্নলিখিত ফ্লোচার্ট থেকে বোঝা যায়।
স্ক্রিন-অন থাকার সময়সীমা কন্ট্রোল করা
আপনার অ্যাপ কতক্ষণ স্ক্রিনে থাকবে তা কীভাবে ম্যানেজ করবেন তা নিম্নলিখিত বিভাগে বর্ণনা করা হয়েছে।
চলমান অ্যাক্টিভিটি বা লাইভ আপডেট সহ ওয়াচফেসে ফিরে যাওয়া আটকানো
অ্যাম্বিয়েন্ট স্টেটে (টাইম-আউট #২) কিছু সময় থাকার পরে, সিস্টেম সাধারণত ওয়াচ ফেসে ফিরে যাবে। ব্যবহারকারী সিস্টেম সেটিংস থেকে টাইম-আউট এর সময়সীমা কনফিগার করতে পারবেন। কিছু নির্দিষ্ট ব্যবহারের ক্ষেত্রে, যেমন কোনও ব্যবহারকারী ওয়ার্ক-আউট ট্র্যাক করলে, অ্যাপটিকে আরও বেশি সময় ধরে দৃশ্যমান থাকতে হতে পারে।
Wear OS 5 ও তার পরের যেকোনও ভার্সনে, চলমান অ্যাক্টিভিটি প্রয়োগ করে আপনি এটি আটকাতে পারবেন। আপনার অ্যাপ যদি কোনও চলমান ব্যবহারকারীর টাস্ক সম্পর্কে তথ্য দেখায়, যেমন, একটি ওয়ার্কআউট সেশন, তাহলে টাস্ক শেষ না হওয়া পর্যন্ত আপনার অ্যাপকে দৃশ্যমান রাখতে আপনি চলমান অ্যাক্টিভিটি API ব্যবহার করতে পারবেন। কোনও ব্যবহারকারী ম্যানুয়ালি ওয়াচফেসে ফিরে গেলে, চলমান অ্যাক্টিভিটি ইন্ডিকেটর তাকে এক-ট্যাপে আপনার অ্যাপে ফিরে যাওয়ার সুবিধা দেয়।
অথবা, Wear OS 7 ও তার পরের যেকোনও ভার্সনে, আপনি কোনও চলমান অ্যাক্টিভিটির পরিবর্তে লাইভ আপডেট ব্যবহার করতে পারেন। পুরনো ভার্সনের সাথে মানানসই হওয়ার জন্য, Wear OS 6 বা তার আগের ভার্সনে চলে এমন ডিভাইসে চলমান অ্যাক্টিভিটি কাজ করা চালিয়ে যাবে।
এটি প্রয়োগ করতে, নিম্নলিখিত কোড স্নিপেটে দেখানো হয়েছে সেই অনুযায়ী, চলমান বিজ্ঞপ্তির টাচ ইনটেন্টকে আপনার সর্বদা-চালু অ্যাক্টিভিটির দিকে পয়েন্ট করতে হবে:
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()
স্ক্রিন চালু রাখুন এবং অ্যাম্বিয়েন্ট স্টেট প্রতিরোধ করুন
বিরল কিছু ক্ষেত্রে, ডিভাইসকে সম্পূর্ণভাবে
অ্যাম্বিয়েন্ট স্টেটে যাওয়া থেকে আটকাতে হতে পারে। অর্থাৎ, টাইম-আউট #১ এড়াতে। এটি করতে, আপনি
keepScreenOn মডিফায়ার ব্যবহার করতে পারবেন। এটি একটি ওয়েক লক হিসেবে কাজ করে, ডিভাইসটিকে ইন্টার্যাক্টিভ
স্টেটে রাখে। এটি ব্যাটারির আয়ুর উপর
মারাত্মক প্রভাব ফেলে বলে অত্যন্ত সতর্কতা অবলম্বন করে এটি ব্যবহার করুন।
অ্যাম্বিয়েন্ট মোডের জন্য সাজেশন
অ্যাম্বিয়েন্ট মোডে সবচেয়ে ভালো ব্যবহারকারীর অভিজ্ঞতা প্রদান করতে এবং পাওয়ার সেভ করতে, এইসব ডিজাইন নির্দেশিকা অনুসরণ করুন। এইসব সাজেশন ব্যবহারকারীর স্পষ্ট অভিজ্ঞতাকে অগ্রাধিকার দেয়, এর জন্য বিভ্রান্তিকর তথ্য এড়ানো হয় এবং ভিজ্যুয়াল ক্লাটার কমানো হয়, একইসাথে ডিসপ্লে পাওয়ার অপ্টিমাইজ করা হয়।
- ভিজ্যুয়াল ক্লাটার কমান এবং পাওয়ার ডিসপ্লে করুন। পরিষ্কার, মিনিমালিস্ট UI ব্যবহারকারীকে
জানায় যে অ্যাপটি কম পাওয়ার স্টেটে আছে এবং উজ্জ্বল পিক্সেল সীমিত করে উল্লেখযোগ্য
ব্যাটারি সাশ্রয় করে।
- স্ক্রিনের অন্তত ৮৫% কালো রাখুন (১৫% বা এর কম অন-পিক্সেল রেশিও)।
- শুধুমাত্র সবচেয়ে গুরুত্বপূর্ণ তথ্য দেখান এবং সেকেন্ডারি বিবরণকে ইন্টারেক্টিভ ডিসপ্লেতে সরিয়ে দিন।
- বড় আইকন বা বোতামের জন্য সলিড ফিল না করে আউটলাইন ব্যবহার করুন, আউটলাইনের কনট্রাস্ট অ্যাডজাস্ট করুন যাতে স্ক্রিন ফ্লিকার বা বার্ন-ইন হওয়ার ঝুঁকি ছাড়াই এলিমেন্টগুলি স্পষ্ট দেখা যায়।
- গাঢ় রঙের বড় ব্লক এবং কাজ করে না এমন ব্র্যান্ডিং বা ব্যাকগ্রাউন্ড ছবি এড়িয়ে চলুন।
- পুরনো ডায়নামিক ডেটা ও অ্যানিমেশন ম্যানেজ করা
- পাওয়ার সাশ্রয় করার জন্য
AmbientTickEffectকলব্যাক শুধুমাত্র নির্দিষ্ট সময় অন্তর -- সাধারণত প্রতি মিনিটে একবার -- ইনভোক করা হয়। এই সীমাবদ্ধতার কারণে, এমন যেকোনও ডেটা যা ঘন ঘন পরিবর্তিত হয় -- যেমন স্টপওয়াচ, হার্ট রেট বা ওয়ার্কআউট দূরত্ব -- আপডেট করার মধ্যে পুরনো হয়ে যায়। বিভ্রান্তিকর ও ভুল তথ্য দেখানো এড়াতে, এই লাইভ ভ্যালুগুলির পরিবর্তে---এর মতো স্ট্যাটিক প্লেসহোল্ডার কন্টেন্ট ব্যবহার করুন। - ব্যবহারকারীর বর্তমান প্রসঙ্গ বা পরিস্থিতির জন্য উপযোগী হতে ঘন ঘন আপডেট করতে হয় এমন প্রগ্রেস ইন্ডিকেটর সরিয়ে দিন। যেমন, ছোট মিডিয়া সেশনের জন্য প্রগ্রেস রিং। আপনি প্রগ্রেস ইন্ডিকেটর রেখে দিতে পারেন যেখানে প্রতি মিনিটে একবার আপডেট করা এখনও ভ্যালু প্রদান করে, যেমন, দীর্ঘ টাইমারের ক্ষেত্রে।
- অ্যাম্বিয়েন্ট মোডে সব অ্যানিমেশন পজ করুন বা সরিয়ে দিন, এর মধ্যে অ্যানিমেটেড প্রগ্রেস ইন্ডিকেটর ও স্ক্রল করা মারকিউ টেক্সট অন্তর্ভুক্ত।
- পাওয়ার সাশ্রয় করার জন্য
- লেআউট একই রাখুন
- স্মুথ ট্রানজিশন তৈরি করতে, ইন্টার্যাক্টিভ ও অ্যাম্বিয়েন্ট মোড জুড়ে এলিমেন্টগুলিকে একই পজিশনে রাখুন। ইন্টার্যাক্টিভ UI এলিমেন্ট যেমন বোতাম দেখা যেতে পারে কারণ আধুনিক Wear OS ডিভাইস অ্যাম্বিয়েন্ট সেশনের সময় টাচ ইনপুট সাপোর্ট করে।
- সবসময় বর্তমান সময় দেখায়। Wear OS-এর জন্য Jetpack Compose-এ,
TimeText(ScreenScaffold-এ ডিফল্ট হিসেবে অন্তর্ভুক্ত) হল অ্যাম্বিয়েন্ট-সচেতন এবং অ্যাম্বিয়েন্ট মোডে প্রতি মিনিটে একবার অটোমেটিক আপডেট হয়।
- প্রাসঙ্গিকতা সম্পর্কে সচেতন থাকা
- ডিভাইস অ্যাম্বিয়েন্ট মোডে প্রবেশ করার সময় ব্যবহারকারী যদি সেটিংস বা কনফিগারেশন স্ক্রিনে থাকেন, তাহলে সেটিংস ভিউয়ের পরিবর্তে আপনার অ্যাপ থেকে আরও প্রাসঙ্গিক স্ক্রিন দেখানোর কথা বিবেচনা করুন।
- ডিভাইস-নির্দিষ্ট প্রয়োজনীয়তা ম্যানেজ করা
currentAmbientModeAmbientMode.Ambientরিটার্ন করলে:isLowBitAmbientSupportedtrueহলে, অ্যাম্বিয়েন্ট মোডে ডিসপ্লেতে প্রতি কালারে কম বিট কাজ করে। অ্যান্টি-এলাইজিং বন্ধ করুন (যেমন, কাস্টমCanvasবাPaintড্রয়িং অপারেশনে) এবং যেখানে সম্ভব সেখানে কালার গ্রেডিয়েন্ট এড়িয়ে চলুন।isBurnInProtectionRequiredtrueহলে, পিক্সেল বার্ন-ইন প্রতিরোধ করতে সিস্টেমটি মাঝে মাঝে ডিসপ্লে কন্টেন্ট শিফট করে। আপনার অ্যাপে UI এলিমেন্ট ম্যানুয়ালি শিফট করবেন না। পরিবর্তে, সম্পূর্ণ সাদা জায়গা এড়িয়ে চলুন এবং গুরুত্বপূর্ণ UI এলিমেন্ট স্ক্রিনের প্রান্ত থেকে কমপক্ষে ১০ পিক্সেল দূরে রাখুন যাতে সিস্টেম ডিসপ্লে শিফট করলে সেগুলি ক্লিপ না হয়ে যায়। (Standard Wear Compose লেআউট যেমনScreenScaffoldআগে থেকেই যথেষ্ট এজ প্যাডিং প্রদান করে।)
ডিবাগিং ও টেস্টিং
ডিভাইস অ্যাম্বিয়েন্ট মোডে থাকলে আপনার অ্যাপ
কীভাবে আচরণ করে তা ডেভেলপ বা টেস্ট করার সময় এইসব 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
যেমন: ওয়ার্ক-আউট অ্যাপ
ওয়ার্ক-আউট অ্যাপের কথা ভাবুন, যেটিকে ব্যবহারকারীর এক্সারসাইজ সেশনের সম্পূর্ণ সময় ধরে মেট্রিক দেখাতে হবে। অ্যাপটিকে অবশ্যই অ্যাম্বিয়েন্ট স্টেট ট্রানজিশনের মাধ্যমে দৃশ্যমান থাকতে হবে এবং ওয়াচফেসের মাধ্যমে প্রতিস্থাপিত হওয়া এড়াতে হবে।
এটি করতে, ডেভেলপারকে নিম্নলিখিত কাজগুলি করতে হবে:
- ইন্টার্যাক্টিভ ও অ্যাম্বিয়েন্ট স্টেটের মধ্যে UI পরিবর্তনগুলি ম্যানেজ করতে
LocalAmbientModeManagerব্যবহার করুন, যেমন স্ক্রিন ডিম করা ও অপ্রয়োজনীয় ডেটা সরিয়ে দেওয়া। - অ্যাম্বিয়েন্ট স্টেটের জন্য পেশাদার পদ্ধতি মেনে চলে এমন নতুন লো-পাওয়ার লেআউট তৈরি করুন।
- সিস্টেম যাতে ওয়াচ ফেসে ফিরে না যায়, সেই জন্য ওয়ার্কআউটের সময় Ongoing Activity API (বা Wear OS 7 ও এর পরের যেকোনও ভার্সনে লাইভ আপডেট) ব্যবহার করুন।
সম্পূর্ণ প্রয়োগের জন্য, GitHub-এ কম্পোজ-ভিত্তিক নমুনা এক্সারসাইজ দেখুন। এছাড়াও, এই নমুনাটি Compose-এ অ্যাম্বিয়েন্ট মোড হ্যান্ডেল করা সহজ করতে
LocalAmbientModeManager কম্পোজ করার উপযুক্ত আইটেম ব্যবহার করার
বিষয়টিও দেখায়।