Car App Library के टेंप्लेट का इस्तेमाल करने वाले मीडिया ऐप्लिकेशन, मीडिया ब्राउज़ करने और चलाने के अनुभव को अपनी पसंद के मुताबिक बना सकते हैं. साथ ही, यह पक्का कर सकते हैं कि अनुभव को कार की स्क्रीन के लिए ऑप्टिमाइज़ किया गया हो और ड्राइविंग के दौरान ध्यान भटकने की समस्या कम हो.
इस गाइड में यह माना गया है कि आपके पास पहले से ही कोई ऐसा मीडिया ऐप्लिकेशन है जो फ़ोन पर ऑडियो चलाता है. साथ ही, आपका मीडिया ऐप्लिकेशन Android मीडिया ऐप्लिकेशन आर्किटेक्चर के मुताबिक है. Car App Library की मदद से, ऐप्लिकेशन में मिलने वाले अनुभव को टेंप्लेट से बदला जा सकता है. इसके लिए, कार के लिए मीडिया ऐप्लिकेशन बनाएं
MediaBrowser डेटा स्ट्रक्चर का इस्तेमाल करने की ज़रूरत नहीं होती. आपको अब भी MediaSession
प्लेबैक कंट्रोल के लिए, और MediaBrowserService या MediaLibraryService
सुझाव देने और अन्य स्मार्ट सुविधाओं के लिए उपलब्ध कराना होगा.
अपने ऐप्लिकेशन के मेनिफ़ेस्ट को कॉन्फ़िगर करना
कार के लिए Android App Library का इस्तेमाल करना में बताए गए चरणों के अलावा, टेंप्लेट वाले मीडिया ऐप्लिकेशन के लिए ये ज़रूरी शर्तें पूरी करना ज़रूरी है:
मेनिफ़ेस्ट में, कैटगरी के साथ काम करने की सुविधा के बारे में जानकारी देना
आपके ऐप्लिकेशन को, 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>
Car App API का कम से कम लेवल सेट करना
MediaPlaybackTemplate का इस्तेमाल करने वाले मीडिया ऐप्लिकेशन, सिर्फ़ CAL API 8 और इसके बाद के वर्शन पर काम करते हैं. पक्का करें कि Car App API level कम से कम 8 पर सेट हो.
<application ...>
...
<meta-data
android:name="androidx.car.app.minCarApiLevel"
android:value="8"/>
...
</application>
एट्रिब्यूशन आइकॉन उपलब्ध कराना
कार ऐप्लिकेशन की लाइब्रेरी का इस्तेमाल करके बनाए गए मीडिया ऐप्लिकेशन के लिए, एट्रिब्यूशन आइकॉन जोड़ना न भूलें.
Android Auto के साथ काम करने की सुविधा के बारे में जानकारी देना
पक्का करें कि आपके ऐप्लिकेशन के मेनिफ़ेस्ट में यह शामिल हो:
<application>
...
<meta-data android:name="com.google.android.gms.car.application"
android:resource="@xml/automotive_app_desc"/>
...
</application>
इसके बाद, अपनी xml फ़ाइल में मौजूद automotive_app_desc.xml में टेंप्लेट का एलान जोड़ें. यह इस तरह दिखना चाहिए:
<automotiveApp xmlns:android="http://schemas.android.com/apk/res/android">
<uses name="media"/>
<uses name="template"/>
</automotiveApp>
Android Automotive OS के साथ काम करने की सुविधा के बारे में जानकारी देना
Android Automotive OS पर, कार में इस्तेमाल किए जाने वाले ऐप्लिकेशन की लाइब्रेरी की सुविधा वाले मीडिया ऐप्लिकेशन को दो अलग-अलग तरीकों से डिस्ट्रिब्यूट किया जा सकता है: एक APK के तौर पर या दो अलग-अलग APK के तौर पर. अगर आपने एक ही APK डिस्ट्रिब्यूट किया है, तो यह उन वाहनों के साथ काम करेगा जिनमें Car App Library होस्ट के साथ Android Automotive OS चालू है. अगर ऐसा नहीं है, तो यह MediaBrowserService या MediaLibraryService ऐप्लिकेशन पर वापस आ जाएगा. ऐसा Android के पुराने वर्शन (Android 10 से Android 13) के लिए भी होगा. अगर आपको दो अलग-अलग APK डिस्ट्रिब्यूट करने हैं, तो Car App Library के नए वर्शन में जोड़े गए अपडेट को लागू किया जा सकता है. इससे आपके ऐप्लिकेशन के MediaBrowserService या MediaLibraryService वर्शन पर कोई असर नहीं पड़ेगा.
एक APK डिस्ट्रिब्यूट करना
कार के लिए ऐप्लिकेशन लाइब्रेरी और MediaBrowserService या MediaLibraryService वर्शन के लिए एक ही APK डिस्ट्रिब्यूट करते समय, android.software.car.templates_host.media को android:required="false" पर सेट करना ज़रूरी है.
<uses-feature android:name="android.software.car.templates_host.media" android:required="false"/>
इसके बाद, AAOS के लिए Car App Library के दिशा-निर्देशों का पालन करें. साथ ही, लॉन्च की जा सकने वाली 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>
Play पर डिस्ट्रिब्यूशन
Car App Library और MediaBrowserService या MediaLibraryService के साथ आपके APK में, वर्शन कोड को ज़्यादा होना चाहिए. साथ ही, Android 14 (34) को टारगेट करने वाले minSdk को चालू किया जाना चाहिए.
दो APK के ज़रिए ऐप्लिकेशन डिस्ट्रिब्यूट करना
Car App Library और MediaBrowserService या MediaLibraryService का इस्तेमाल करने वाले दो अलग-अलग APK डिस्ट्रिब्यूट करने के लिए, यह तरीका अपनाएं. इससे यह पक्का किया जा सकेगा कि कार की सही सुविधाओं को सही तरीके से टारगेट किया गया है.
कार ऐप्लिकेशन की लाइब्रेरी के वर्शन के लिए अलग APK बनाते समय, आपको android.software.car.templates_host.media को android:required=true पर सेट करना होगा. इससे यह पक्का होता है कि ऐप्लिकेशन को सिर्फ़ उन Android Automotive OS बिल्ड पर उपलब्ध कराया जाए जिन्हें कार के लिए ऐप्लिकेशन लाइब्रेरी होस्ट करने की सुविधा के साथ सर्टिफ़ाइड किया गया है.
<uses-feature android:name="android.software.car.templates_host.media" android:required="true"/>
android.software.car.templates_host.media का इस्तेमाल करने और इसे android:required=true पर सेट करने के अलावा, इन चरणों का पालन करके, लॉन्च की जा सकने वाली कार ऐप्लिकेशन लाइब्रेरी की गतिविधि के लिए, Android Automotive OS को चालू करें.
Play Distribution
कार ऐप्लिकेशन की लाइब्रेरी का इस्तेमाल करने वाले APK को, Automotive OS के लिए बनाए गए खास ट्रैक में डिस्ट्रिब्यूट किया जाना चाहिए.
बोलकर कार्रवाइयां करने की सुविधा
अपने ऐप्लिकेशन में बोलकर कंट्रोल करने की सुविधा चालू करें, ताकि उपयोगकर्ता बिना हाथ लगाए सामान्य कार्रवाइयां कर सकें.
लागू करने के बारे में ज़्यादा जानकारी के लिए, मीडिया के लिए आवाज़ से कंट्रोल करने की सुविधा देखें. अगर आपको टेंप्लेट वाले मीडिया ऐप्लिकेशन पर कोई वॉइस कमांड मिलती है, तो आपको खोज के नतीजों के साथ 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)
}
...
}
)
}
}
}
Android Auto पर मीडिया प्लेबैक की जानकारी और कंट्रोल दिखाने के लिए, .registerMediaPlaybackToken ज़रूरी है. होस्ट के लिए भी यह ज़रूरी है, ताकि वह मीडिया के हिसाब से सूचनाएं बना सके.
Media3 लाइब्रेरी का इस्तेमाल करने वाले ऐप्लिकेशन के लिए, आपको अपने MediaLibrarySession.Callback में कस्टम SessionCommand लागू करना होगा. ये ऐप्लिकेशन, स्टैंडर्ड MediaSessionCompat.Token के बजाय PlatformToken का इस्तेमाल करते हैं. यह कस्टम, सेशन के प्लैटफ़ॉर्म टोकन: 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();
Car App Library 1.9 के कॉम्पोनेंट और सुविधाएं
Car App Library API 1.9 वर्शन में, ब्राउज़िंग की खास सुविधाओं के लिए कस्टम कॉम्पोनेंट पेश किए गए हैं. जैसे, चिप, प्रोग्रेस बार, छोटे किए गए आइटम, इंटरैक्टिव और बड़ा किया गया हेडर, स्पॉटलाइट सेक्शन, और बैनर.
तीसरी इमेज: SectionedItemTemplate में Chips, Condensed Items, Interactive Header, Grid Items, और Minimized Control Panel शामिल हैं
चौथी इमेज: मीडिया ब्राउज़ करने की दो स्क्रीन दिखाई गई हैं. इनमें Expanded Header, Spotlight Sections, और Progress Bars को हाइलाइट किया गया है
इन टेंप्लेट का इस्तेमाल करके, अपने मीडिया ऐप्लिकेशन का यूज़र इंटरफ़ेस डिज़ाइन करने के तरीके के बारे में ज़्यादा जानने के लिए, मीडिया ऐप्लिकेशन लेख पढ़ें.
प्लेबैक कंट्रोल पर जाना
मीडिया ब्राउज़ करते समय, यह ज़रूरी है कि उपयोगकर्ता कम से कम रुकावट के साथ MediaPlaybackTemplate पर तुरंत नेविगेट कर सके.MFT-1 क्वालिटी से जुड़ी ज़रूरी शर्त को पूरा करने के लिए, आपके ऐप्लिकेशन में मीडिया ब्राउज़ करने वाली सभी स्क्रीन से MediaPlaybackTemplate को ऐक्सेस करने का तरीका होना चाहिए.
अगर SectionedItemTemplate का इस्तेमाल किया जा रहा है, तो मीडिया चलाने की स्क्रीन पर रीडायरेक्ट करने वाले ऐक्शन बटन को जोड़कर ऐसा किया जा सकता है. Car App Library Action.MEDIA_PLAYBACK के स्टैंडर्ड ऐक्शन का इस्तेमाल करें. मीडिया ऐप्लिकेशन, इस कार्रवाई को छोटा किया गया कंट्रोल पैनल के तौर पर दिखाएगा. अगर Car App Library API 1.9 या इसके बाद के वर्शन का इस्तेमाल किया जा रहा है, तो MFT-1 क्वालिटी से जुड़ी ज़रूरी शर्तें पूरी करना ज़रूरी है. अन्य टेंप्लेट के लिए, हेडर ऐक्शन का इस्तेमाल करके भी ऐसा किया जा सकता है.
सिस्टम मीडिया प्लेबैक के इंटेंट मैनेज करना
जब किसी मीडिया कार्ड जैसे मीडिया चलाने वाले सिस्टम से कोई ऐप्लिकेशन लॉन्च किया जाता है, तो उपयोगकर्ता को MediaPlaybackTemplate पर रीडायरेक्ट करना ज़रूरी होता है. हमारा सुझाव है कि मीडिया ऐप्लिकेशन, इस Intent Action को मैनेज करें, ताकि लोगों को बेहतर अनुभव मिल सके.
Car App Library कॉम्पोनेंट (CarAppActivity या ट्रैम्पोलिन Activity) के intent-filter में androidx.car.app.media.action.SHOW_MEDIA_PLAYBACK कार्रवाई जोड़ें.
पक्का करें कि आपकी गतिविधि में singleTask या singleTop का launchMode इस्तेमाल किया गया हो, ताकि 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();
}
}