কার অ্যাপ লাইব্রেরি টেমপ্লেট ব্যবহারকারী মিডিয়া অ্যাপগুলো তাদের মিডিয়া ব্রাউজিং ও প্লেব্যাক অভিজ্ঞতাকে নিজেদের মতো করে সাজিয়ে নিতে পারে। এর মাধ্যমে তারা নিশ্চিত করে যে, এই অভিজ্ঞতা গাড়ির স্ক্রিনের জন্য সর্বোত্তমভাবে তৈরি এবং গাড়ি চালানোর সময় মনোযোগের বিচ্যুতি সর্বনিম্ন থাকে।
এই নির্দেশিকাটি ধরে নেয় যে আপনার কাছে ইতিমধ্যেই একটি মিডিয়া অ্যাপ আছে যা ফোনে অডিও প্লে করে এবং আপনার মিডিয়া অ্যাপটি অ্যান্ড্রয়েড মিডিয়া অ্যাপ আর্কিটেকচার মেনে চলে। কার অ্যাপ লাইব্রেরি আপনাকে 'Build media apps for cars' MediaBrowser ডেটা স্ট্রাকচার ব্যবহার করে তৈরি টেমপ্লেটের পরিবর্তে ইন-অ্যাপ অভিজ্ঞতাকে টেমপ্লেট দিয়ে প্রতিস্থাপন করার ক্ষমতা দেয়। প্লেব্যাক নিয়ন্ত্রণের জন্য আপনাকে অবশ্যই একটি MediaSession এবং সুপারিশ ও অন্যান্য স্মার্ট অভিজ্ঞতার জন্য ব্যবহৃত একটি MediaBrowserService বা MediaLibraryService প্রদান করতে হবে।
আপনার অ্যাপের ম্যানিফেস্ট কনফিগার করুন
"অ্যান্ড্রয়েড ফর কারস অ্যাপ লাইব্রেরি ব্যবহার" অংশে বর্ণিত ধাপগুলো ছাড়াও, টেমপ্লেটেড মিডিয়া অ্যাপগুলোর জন্য নিম্নলিখিত বিষয়গুলো প্রয়োজন:
আপনার ম্যানিফেস্টে ক্যাটাগরি সাপোর্ট ঘোষণা করুন।
আপনার অ্যাপের CarAppService এর ইন্টেন্ট ফিল্টারে androidx.car.app.category.MEDIA কার অ্যাপ ক্যাটাগরিটি ডিক্লেয়ার করতে হবে।
<application>
...
<service
...
android:name=".MyCarAppService"
android:exported="true">
<intent-filter>
<action android:name="androidx.car.app.CarAppService" />
<category android:name="androidx.car.app.category.MEDIA"/>
</intent-filter>
</service>
...
<application>
MediaPlaybackTemplate এ অ্যাক্সেস পেতে হলে, আপনার অ্যাপের ম্যানিফেস্ট ফাইলে androidx.car.app.MEDIA_TEMPLATES পারমিশনটিও ডিক্লেয়ার করতে হবে:
<manifest ...>
...
<uses-permission android:name="androidx.car.app.MEDIA_TEMPLATES"/>
...
</manifest>
গাড়ির অ্যাপের সর্বনিম্ন API স্তর সেট করুন
MediaPlaybackTemplate ব্যবহারকারী মিডিয়া অ্যাপগুলো শুধুমাত্র CAL API 8 এবং তার উপরের সংস্করণগুলোতে সমর্থিত, তাই নিশ্চিত করুন যে আপনার সর্বনিম্ন Car App API level 8-এ সেট করা আছে।
<application ...>
...
<meta-data
android:name="androidx.car.app.minCarApiLevel"
android:value="8"/>
...
</application>
একটি অ্যাট্রিবিউশন আইকন প্রদান করুন
কার অ্যাপ লাইব্রেরি ব্যবহার করে তৈরি মিডিয়া অ্যাপগুলোর জন্য একটি অ্যাট্রিবিউশন আইকন যোগ করতে ভুলবেন না।
অ্যান্ড্রয়েড অটো সমর্থন ঘোষণা করুন
আপনার অ্যাপের ম্যানিফেস্টে নিম্নলিখিত বিষয়গুলো অন্তর্ভুক্ত আছে কিনা তা নিশ্চিত করুন:
<application>
...
<meta-data android:name="com.google.android.gms.car.application"
android:resource="@xml/automotive_app_desc"/>
...
</application>
এরপর, আপনার এক্সএমএল রিসোর্সের automotive_app_desc.xml ফাইলে টেমপ্লেট ডিক্লারেশনটি যোগ করুন। এটি দেখতে নিম্নলিখিতের মতো হবে:
<automotiveApp xmlns:android="http://schemas.android.com/apk/res/android">
<uses name="media"/>
<uses name="template"/>
</automotiveApp>
অ্যান্ড্রয়েড অটোমোটিভ ওএস সমর্থন ঘোষণা করুন
অ্যান্ড্রয়েড অটোমোটিভ ওএস-এ কার অ্যাপ লাইব্রেরি-সক্ষম একটি মিডিয়া অ্যাপ বিতরণ করার দুটি ভিন্ন উপায় রয়েছে: একটি একক APK হিসাবে অথবা দুটি পৃথক APK হিসাবে। আপনি যদি একটি একক APK বিতরণ করেন, তবে এটি কার অ্যাপ লাইব্রেরি হোস্ট সহ অ্যান্ড্রয়েড অটোমোটিভ ওএস-এর জন্য সক্ষম যানবাহনগুলিকে সমর্থন করবে এবং অন্যথায় একটি MediaBrowserService বা MediaLibraryService অ্যাপ্লিকেশনে ফিরে যাবে, এমনকি পুরোনো অ্যান্ড্রয়েড সংস্করণগুলির (অ্যান্ড্রয়েড ১০ - অ্যান্ড্রয়েড ১৩) জন্যও। আপনি যদি দুটি পৃথক APK বিতরণ করার সিদ্ধান্ত নেন, তবে আপনি আপনার অ্যাপের MediaBrowserService বা MediaLibraryService সংস্করণকে প্রভাবিত করার ভয় ছাড়াই কার অ্যাপ লাইব্রেরি সংস্করণে নতুন সংযোজনগুলি আরও সহজে আপডেট করতে পারবেন।
একটি একক APK বিতরণ করা
আপনার অ্যাপের Car App Library এবং MediaBrowserService বা MediaLibraryService ভার্সনগুলোর জন্য একটিমাত্র APK বিতরণ করার সময়, "android:required="false" এ পরিবর্তন করুন।
<uses-feature android:name="android.software.car.templates_host.media" android:required="false"/>
এরপরে, AAOS-এর জন্য কার অ্যাপ লাইব্রেরির নির্দেশিকা অনুসরণ করুন এবং একটি লঞ্চযোগ্য CarAppActivity (বা ট্রাম্পোলিন অ্যাক্টিভিটি) যুক্ত করুন। আপনাকে অবশ্যই ম্যানিফেস্টে অ্যাক্টিভিটিটির জন্য android:enabled="false" সেট করতে হবে। এরপরে, MediaBrowserService ডিক্লারেশনে একটি মেটাডেটা ট্যাগ যোগ করুন, যা CarAppActivity কম্পোনেন্টটিকে প্রতিস্থাপন হিসেবে নির্দেশ করবে। নিচে উদাহরণ ম্যানিফেস্টটি দেখুন:
<service android:name=".media.MyMediaService"
android:exported="true"
android:label="@string/app_name">
<intent-filter>
<action android:name="androidx.media3.session.MediaLibraryService"/>
</intent-filter>
<!-- Link to Car App Library Activity -->
<meta-data
android:name="androidx.car.app.media.CalMediaActivityComponent"
android:value="com.example.mediaapp.LaunchableTrampoline"/>
</service>
<activity
android:name=".LaunchableTrampoline"
android:exported="true"
android:theme="@android:style/Theme.DeviceDefault.NoActionBar"
android:launchMode="singleTask"
android:label="@string/app_name_cal"
android:enabled="false"> <!-- Set to false -->
<meta-data android:name="distractionOptimized" android:value="true" />
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<action android:name="androidx.car.app.media.action.SHOW_MEDIA_PLAYBACK"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
খেলার বন্টন
আপনার APK-তে Car App Library এবং MediaBrowserService অথবা MediaLibraryService থাকলে, সেটিকে অবশ্যই একটি উচ্চতর সংস্করণ কোড এবং Android 14 (34) টার্গেট করা minSdk দিয়ে সক্রিয় করতে হবে।
দুটি APK সহ বিতরণ করা হচ্ছে
কার অ্যাপ লাইব্রেরি এবং MediaBrowserService বা MediaLibraryService ব্যবহার করে দুটি পৃথক APK বিতরণ করতে, গাড়ির সঠিক সক্ষমতাগুলো যেন সঠিকভাবে টার্গেট করা হয় তা নিশ্চিত করতে এই ধাপগুলো অনুসরণ করুন।
আপনার অ্যাপের কার অ্যাপ লাইব্রেরি সংস্করণের জন্য একটি পৃথক APK তৈরি করার সময়, আপনাকে অবশ্যই android.software.car.templates_host.media কে android:required=true তে সেট করতে হবে। এটি নিশ্চিত করে যে অ্যাপটি শুধুমাত্র সেইসব অ্যান্ড্রয়েড অটোমোটিভ ওএস বিল্ডগুলিতে বিতরণ করা হবে, যেগুলি কার অ্যাপ লাইব্রেরি হোস্টের সমর্থনের জন্য প্রত্যয়িত।
<uses-feature android:name="android.software.car.templates_host.media" android:required="true"/>
উপরে android.software.car.templates_host.media ব্যবহার করা এবং এটিকে android:required=true সেট করা ছাড়াও, আপনার লঞ্চযোগ্য কার অ্যাপ লাইব্রেরি অ্যাক্টিভিটির জন্য অ্যান্ড্রয়েড অটোমোটিভ ওএস সক্রিয় করতে এই ধাপগুলি অনুসরণ করুন।
খেলার বিতরণ
যে APK-টি কার অ্যাপ লাইব্রেরি ব্যবহার করে, সেটি অটোমোটিভ ওএস-এর জন্য নির্ধারিত ট্র্যাকে বিতরণ করা উচিত।
ভয়েস অ্যাকশন সমর্থন করুন
ব্যবহারকারীদের হাত ব্যবহার না করেই সাধারণ কাজগুলো সম্পন্ন করার সুযোগ দিতে আপনার অ্যাপটিকে ভয়েস-সক্ষম করুন। আরও বিস্তারিত বাস্তবায়ন নির্দেশাবলীর জন্য ‘মিডিয়ার জন্য ভয়েস অ্যাকশন সমর্থন’ দেখুন। একটি টেমপ্লেটেড মিডিয়া অ্যাপে যদি আপনি কোনো ভয়েস কমান্ড পান, তাহলে সার্চ রেজাল্ট দিয়ে আপনার MediaBrowserService বা MediaLibraryService আপডেট করার প্রয়োজন নেই। এর পরিবর্তে, আপনার মিডিয়া প্লেব্যাক টেমপ্লেটে একটি অ্যাকশন যোগ করার কথা বিবেচনা করুন, যা ব্যবহারকারীকে সেই প্লে বা সার্চ কোয়েরির উপর ভিত্তি করে আরও কন্টেন্ট খুঁজে পেতে সাহায্য করবে। VC-1 কোয়ালিটি গাইডলাইন পূরণের জন্য ভয়েস কমান্ড সমর্থন করা আবশ্যক।
আপনার প্লেব্যাক টেমপ্লেট তৈরি করুন
MediaPlaybackTemplate আপনার Car App Library মিডিয়া অ্যাপে মিডিয়া প্লেব্যাকের তথ্য প্রদর্শন করে। এই টেমপ্লেটটি একটি শিরোনামসহ হেডার এবং কাস্টমাইজযোগ্য অ্যাকশন সেট করার সুযোগ দেয়, যেখানে মিডিয়ার তথ্য এবং প্লেব্যাক কন্ট্রোলগুলো আপনার অ্যাপের MediaSession এর অবস্থার উপর ভিত্তি করে হোস্ট দ্বারা পূরণ করা হয়।

চিত্র ১: MediaPlaybackTemplate , যার শীর্ষে কিউ খোলার জন্য একটি হেডার অ্যাকশন রয়েছে।
এই কোড উদাহরণটি দেখায় কিভাবে একটি নমুনা প্লেব্যাক টেমপ্লেট তৈরি করতে হয়, যা একটি হেডার অ্যাকশন সেট করে এবং এর মাধ্যমে ব্যবহারকারীকে গানের সারিযুক্ত স্ক্রিনে নেভিগেট করার সুযোগ দেয়।
val playbackTemplate = MediaPlaybackTemplate.Builder()
.setHeader(
Header.Builder()
.setStartHeaderAction(Action.BACK)
.addEndHeaderAction(
Action.Builder()
.setTitle(model.context.getString(R.string.queue_button_title))
.setIcon(
CarIcon.Builder(
IconCompat.createWithResource(
model.context,
R.drawable.gs_queue_music_vd_theme_24,
))
.build())
.setOnClickListener(showQueueScreen())
.build())
.setTitle(model.context.getString(R.string.media_playback_view_title))
.build())
.build()
যখন আপনি MediaPlaybackTemplate ব্যবহার করেন, তখন আপনার CarAppService এর MediaPlaybackManager ব্যবহার করে একটি MediaSession টোকেন রেজিস্টার করুন। এটি করতে ব্যর্থ হলে, হোস্টে একটি MediaPlaybackTemplate পাঠানোর সময় একটি ত্রুটি প্রদর্শিত হয়।
import androidx.car.app.media.MediaPlaybackManager
…
override fun onCreateSession(sessionInfo: SessionInfo): Session {
return object : Session() {
…
init {
lifecycle.addObserver(
LifecycleEventObserver { _, event ->
if (event == ON_CREATE) {
val token = ... // MediaSessionCompat.Token
(carContext.getCarService(CarContext.MEDIA_PLAYBACK_SERVICE) as MediaPlaybackManager)
.registerMediaPlaybackToken(token)
}
...
}
)
}
}
}
অ্যান্ড্রয়েড অটোতে মিডিয়া প্লেব্যাকের তথ্য ও নিয়ন্ত্রণগুলো প্রকাশ করার জন্য .registerMediaPlaybackToken অপরিহার্য। হোস্টের মিডিয়া-নির্দিষ্ট নোটিফিকেশন তৈরি করার জন্যও এটি গুরুত্বপূর্ণ।
Media3 লাইব্রেরি ব্যবহারকারী অ্যাপগুলির জন্য, যেগুলি স্ট্যান্ডার্ড MediaSessionCompat.Token এর পরিবর্তে PlatformToken ব্যবহার করে, আপনাকে আপনার MediaLibrarySession.Callback এ একটি কাস্টম SessionCommand ইমপ্লিমেন্ট করতে হবে যা সেশনের অন্তর্নিহিত প্ল্যাটফর্ম টোকেন: session.platformToken রিটার্ন করে। আপনার CarAppService এ এই কাস্টম কমান্ডটি সেশনে পাঠান। প্ল্যাটফর্ম টোকেনটি পাওয়ার পর, MediaSessionCompat.Token.fromToken(platformToken) ব্যবহার করে এটিকে রূপান্তর করুন এবং এই কম্প্যাট টোকেনটি .registerMediaPlaybackToken() -এ Car App Library-তে পাস করুন।
টেমপ্লেট ব্যবহার করে মিডিয়া সাজান
গান বা অ্যালবামের মতো মিডিয়া ব্রাউজ করার সুবিধার্থে সাজানোর জন্য, আমরা SectionedItemTemplate ব্যবহার করার পরামর্শ দিই, যা আপনাকে GridSection এবং RowSection একসাথে ব্যবহার করে ছবি ও টেক্সট আইটেমের তালিকা মিশ্রিত লেআউট তৈরি করতে দেয়।

চিত্র ২: একটি SectionedItemTemplate যার মধ্যে একটি RowSection এবং তারপরে একটি GridSection রয়েছে।
TabTemplate-এর ভিতরে SectionedItemTemplate ব্যবহার করা
আপনার অ্যাপের মধ্যে মিডিয়াকে শ্রেণীবদ্ধ করার একটি সুবিধাজনক উপায় হলো TabTemplate এর ভিতরে SectionedItemTemplate ব্যবহার করা।
val template =
SectionedItemTemplate.Builder()...build();
val tabTemplate =
TabTemplate.Builder(tabCallback)
.setTabContents(TabContents.Builder(template).build)
.setHeaderAction(Action.APP_ICON)
…
.build();
গাড়ির অ্যাপ লাইব্রেরি ১.৯ এর উপাদান এবং বৈশিষ্ট্যসমূহ
কার অ্যাপ লাইব্রেরি এপিআই সংস্করণ ১.৯-এ স্বতন্ত্র ব্রাউজিং ক্ষমতার জন্য কাস্টমাইজড কম্পোনেন্ট যুক্ত করা হয়েছে, যেমন চিপস , প্রোগ্রেস বার , কনডেন্সড আইটেম , ইন্টারেক্টিভ ও এক্সপান্ডেড হেডার , স্পটলাইট সেকশন এবং ব্যানার ।

চিত্র ৩: একটি SectionedItemTemplate , যাতে Chips , Condensed Items , একটি Interactive Header , Grid Items এবং একটি Minimized Control Panel রয়েছে।

চিত্র ৪: Expanded Header , Spotlight Sections এবং Progress Bars সমন্বিত দুটি মিডিয়া ব্রাউজিং স্ক্রিন
এই টেমপ্লেটগুলো ব্যবহার করে কীভাবে আপনার মিডিয়া অ্যাপের ইউজার ইন্টারফেস ডিজাইন করবেন সে সম্পর্কে আরও বিস্তারিত জানতে, মিডিয়া অ্যাপস দেখুন।
প্লেব্যাক নিয়ন্ত্রণগুলিতে নেভিগেট করা
মিডিয়া ব্রাউজ করার সময়, ব্যবহারকারীর জন্য ন্যূনতম বিভ্রান্তি সহ দ্রুত MediaPlaybackTemplate এ নেভিগেট করতে পারাটা গুরুত্বপূর্ণ। MFT-1 মানের শর্ত পূরণ করতে, আপনার অ্যাপে সমস্ত মিডিয়া ব্রাউজিং স্ক্রিন থেকে MediaPlaybackTemplate অ্যাক্সেস করার একটি উপায় থাকতে হবে।
আপনি যদি SectionedItemTemplate ব্যবহার করেন, তবে একটি অ্যাকশন বাটন যোগ করে এটি করতে পারেন যা আপনাকে মিডিয়া প্লেব্যাক স্ক্রিনে নিয়ে যাবে । স্ট্যান্ডার্ড কার অ্যাপ লাইব্রেরি Action.MEDIA_PLAYBACK অ্যাকশনটি ব্যবহার করুন। একটি মিডিয়া অ্যাপ এই অ্যাকশনটিকে একটি মিনিমাইজড কন্ট্রোল প্যানেল হিসেবে প্রদর্শন করবে, যা কার অ্যাপ লাইব্রেরি API 1.9 বা তার উচ্চতর সংস্করণ ব্যবহার করলে MFT-1 কোয়ালিটি রিকোয়ারমেন্ট পূরণের জন্য আবশ্যক। অন্যান্য টেমপ্লেটের জন্য, হেডার অ্যাকশন ব্যবহার করে এটি করা যায়।
সিস্টেম মিডিয়া প্লেব্যাক ইনটেন্টগুলি পরিচালনা করুন
যখন কোনো সিস্টেম প্লেয়িং মিডিয়া সারফেস (যেমন মিডিয়া কার্ড) থেকে কোনো অ্যাপ্লিকেশন চালু করা হয়, তখন ব্যবহারকারীকে MediaPlaybackTemplate এ নির্দেশিত করা প্রয়োজন। ব্যবহারকারীদের একটি নির্বিঘ্ন অভিজ্ঞতা প্রদানের জন্য আমরা চাই যে মিডিয়া অ্যাপ্লিকেশনগুলো এই Intent Action পরিচালনা করবে।
আপনার কার অ্যাপ লাইব্রেরি কম্পোনেন্টের ( CarAppActivity অথবা আপনার ট্রাম্পোলিন Activity ) ইন্টেন্ট-ফিল্টারে androidx.car.app.media.action.SHOW_MEDIA_PLAYBACK অ্যাকশনটি যোগ করুন।
আপনার অ্যাক্টিভিটির launchMode হিসেবে singleTask বা singleTop ব্যবহার করুন, যাতে onNewIntent() কল করা হয়।
<activity
android:name=".LaunchableTrampoline"
android:exported="true"
android:theme="@android:style/Theme.DeviceDefault.NoActionBar"
android:launchMode="singleTask"
android:label="@string/app_name_cal"
android:enabled="false">
<meta-data android:name="distractionOptimized" android:value="true" />
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<action android:name="androidx.car.app.media.action.SHOW_MEDIA_PLAYBACK"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
আপনার Session ক্লাসে, আগত ইন্টেন্টটি পার্স করার জন্য onNewIntent() ওভাররাইড করুন। যদি আগত ইন্টেন্টের অ্যাকশন SHOW_MEDIA_PLAYBACK সাথে মিলে যায়, তাহলে ব্যবহারকারীকে আপনার 'নাউ প্লেয়িং' স্ক্রিনে নিয়ে যান।
@Override
public void onNewIntent(@NonNull Intent intent) {
super.onNewIntent(intent);
if (SHOW_MEDIA_PLAYBACK.equals(intent.getAction())) {
ScreenManager screenManager = getCarContext().getCarService(ScreenManager.class);
// Avoid redundant navigation if already on the playing screen
if (screenManager.getTop() instanceof MyMediaPlayScreen) {
return;
}
screenManager.push(MyMediaPlayScreen.createScreenFromPlaying(
getCarContext(), mMediaSessionController));
}
}
আপনি যদি ট্রাম্পোলিন অ্যাক্টিভিটি ব্যবহার করেন, তাহলে onCreate() এর মধ্যে ইন্টেন্ট অ্যাকশনটি পরীক্ষা করুন। finish() কল করার আগে এই অ্যাকশনটি CarAppActivity তৈরির ইন্টেন্টে পাস করুন।
public class LaunchableTrampoline extends AppCompatActivity {
private static final String SHOW_MEDIA_PLAYBACK = "androidx.car.app.media.action.SHOW_MEDIA_PLAYBACK";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Intent receivedIntent = getIntent();
String action;
if (SHOW_MEDIA_PLAYBACK.equals(receivedIntent.getAction())) {
action = SHOW_MEDIA_PLAYBACK;
} else {
action = Intent.ACTION_MAIN;
}
Intent intent = new Intent(action);
intent.setClassName(getPackageName(), "androidx.car.app.activity.CarAppActivity");
startActivity(intent);
finish();
}
}