टेंप्लेट वाला मीडिया ऐप्लिकेशन बनाना

टेंप्लेट वाले मीडिया ऐप्लिकेशन, बीटा वर्शन में हैं
फ़िलहाल, कोई भी व्यक्ति Google Play Store पर इंटरनल टेस्टिंग और क्लोज़्ड टेस्टिंग ट्रैक के लिए, टेंप्लेट वाले मीडिया ऐप्लिकेशन पब्लिश कर सकता है. ओपन ट्रैक और प्रोडक्शन ट्रैक पर पब्लिश करने की अनुमति बाद में दी जाएगी.

Car App Library के टेंप्लेट का इस्तेमाल करने वाले मीडिया ऐप्लिकेशन, मीडिया ब्राउज़ करने और चलाने के अनुभव को अपनी पसंद के मुताबिक बना सकते हैं. साथ ही, यह पक्का कर सकते हैं कि अनुभव को कार की स्क्रीन के लिए ऑप्टिमाइज़ किया गया हो और ड्राइविंग के दौरान ध्यान भटकने की संभावना कम हो.

इस गाइड में यह मानकर चला गया है कि आपके पास पहले से ही कोई ऐसा मीडिया ऐप्लिकेशन है जो फ़ोन पर ऑडियो चलाता है. साथ ही, आपका मीडिया ऐप्लिकेशन Android मीडिया ऐप्लिकेशन के आर्किटेक्चर के मुताबिक है. Car App Library की मदद से, ऐप्लिकेशन में मिलने वाले अनुभव को कार के लिए मीडिया ऐप्लिकेशन बनाएं MediaBrowser डेटा स्ट्रक्चर का इस्तेमाल करके बनाए गए टेंप्लेट के बजाय, टेंप्लेट से बदला जा सकता है. आपको अब भी प्लेबैक कंट्रोल के लिए MediaSession और सुझावों के लिए MediaBrowserService या MediaLibraryService देना होगा. इनका इस्तेमाल सुझाव देने और अन्य स्मार्ट सुविधाओं के लिए किया जाता है.

अपने ऐप्लिकेशन के मेनिफ़ेस्ट को कॉन्फ़िगर करना

Android for Cars 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>

कार ऐप्लिकेशन के लिए, कम से कम एपीआई लेवल सेट करना

MediaPlaybackTemplate का इस्तेमाल करने वाले मीडिया ऐप्लिकेशन, सिर्फ़ CAL API 8 और इसके बाद के वर्शन में काम करते हैं. इसलिए, पक्का करें कि आपका कम से कम Car App API level 8 पर सेट हो.

<application ...>
  ...
  <meta-data
    android:name="androidx.car.app.minCarApiLevel"
    android:value="8"/>
  ...
</application>

एट्रिब्यूशन आइकॉन उपलब्ध कराना

CarApp लाइब्रेरी का इस्तेमाल करके बनाए गए मीडिया ऐप्लिकेशन के लिए, एट्रिब्यूशन आइकॉन जोड़ना न भूलें.

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 पर, Car App Library की सुविधा वाले मीडिया ऐप्लिकेशन को दो अलग-अलग तरीकों से डिस्ट्रिब्यूट किया जा सकता है: एक APK के तौर पर या दो अलग-अलग APK के तौर पर. अगर आपने एक ही APK डिस्ट्रिब्यूट किया है, तो यह उन वाहनों के साथ काम करेगा जिनमें Car App Library होस्ट के साथ Android Automotive OS की सुविधा चालू है. अगर ऐसा नहीं है, तो यह MediaBrowserService या MediaLibraryService ऐप्लिकेशन पर वापस आ जाएगा. ऐसा Android के पुराने वर्शन (Android 10 से Android 13) के लिए भी होगा. अगर आपने दो अलग-अलग APK डिस्ट्रिब्यूट करने का विकल्प चुना है, तो Car App Library के नए वर्शन में जोड़े गए नए कॉन्टेंट को आसानी से अपडेट किया जा सकता है. इससे आपके ऐप्लिकेशन के 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>

Play पर डिस्ट्रिब्यूशन

Car App Library और MediaBrowserService या MediaLibraryService के साथ आपके APK को, ज़्यादा वर्शन कोड के साथ चालू किया जाना चाहिए. साथ ही, Android 14 (34) को टारगेट करने वाले minSdk को चालू किया जाना चाहिए.

दो APK के ज़रिए डिस्ट्रिब्यूट करना

अगर आपको दो अलग-अलग APK डिस्ट्रिब्यूट करने हैं, जिनमें से एक Car App Library का इस्तेमाल करता है और दूसरा MediaBrowserService या MediaLibraryService का, तो यह पक्का करने के लिए कि वाहन की सही सुविधाओं को सही तरीके से टारगेट किया गया है, यह तरीका अपनाएं.

अपने ऐप्लिकेशन के Car App Library वर्शन के लिए अलग APK बनाते समय, आपको android.software.car.templates_host.media को android:required=true पर सेट करना होगा. इससे यह पक्का होता है कि ऐप्लिकेशन को सिर्फ़ Android Automotive OS के उन बिल्ड पर डिस्ट्रिब्यूट किया गया है जिन्हें Car App Library होस्ट के साथ काम करने का सर्टिफ़िकेट मिला है.

<uses-feature android:name="android.software.car.templates_host.media" android:required="true"/>

android.software.car.templates_host.media का इस्तेमाल करने और इसे ऊपर दिए गए android:required=true पर सेट करने के अलावा, लॉन्च की जा सकने वाली Car App Library गतिविधि के लिए, Android Automotive OS को चालू करने के लिए यह तरीका अपनाएं.

Play Distribution

Car App Library का इस्तेमाल करने वाले APK को Automotive OS के खास ट्रैक में डिस्ट्रिब्यूट किया जाना चाहिए.

बोलकर फ़ोन का इस्तेमाल करने की सुविधा

अपने ऐप्लिकेशन में बोलकर कंट्रोल करने की सुविधा चालू करें, ताकि उपयोगकर्ता सामान्य कार्रवाइयां बोलकर कर सकें. लागू करने के बारे में ज़्यादा जानकारी के लिए, मीडिया के लिए बोलकर की जाने वाली कार्रवाइयों की सुविधा देखें. अगर आपको टेंप्लेट वाले मीडिया ऐप्लिकेशन पर कोई वॉइस कमांड मिलती है, तो आपको खोज के नतीजों के साथ MediaBrowserService या MediaLibraryService को अपडेट करने की ज़रूरत नहीं है. इसके बजाय, मीडिया चलाने वाले टेंप्लेट में कोई कार्रवाई जोड़ें, ताकि उपयोगकर्ता को उस गाने या खोज क्वेरी के आधार पर ज़्यादा कॉन्टेंट मिल सके. VC-1 क्वालिटी के दिशा-निर्देश का पालन करने के लिए, बोले गए निर्देशों को सपोर्ट करना ज़रूरी है.

अपना प्लेबैक टेंप्लेट बनाना

MediaPlaybackTemplate, Car App Library के मीडिया ऐप्लिकेशन में मीडिया प्लेबैक की जानकारी दिखाता है. इस टेंप्लेट की मदद से, टाइटल और पसंद के मुताबिक कार्रवाइयों वाला हेडर सेट किया जा सकता है. वहीं, मीडिया की जानकारी और प्लेबैक कंट्रोल, होस्ट के ज़रिए भरे जाते हैं. ये जानकारी और कंट्रोल, आपके ऐप्लिकेशन के MediaSession की स्थिति के आधार पर तय होते हैं.

म्यूज़िक प्लेयर में, समर फ़ील्डिंग का &#39;साउंड्स ऑफ़ स्प्रिंग&#39; गाना दिखाया गया है. साथ ही, गिटार बजाती हुई महिला का स्क्वेयर पोर्ट्रेट दिखाया गया है.

पहली इमेज: 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, Android Auto को मीडिया प्लेबैक की जानकारी और कंट्रोल दिखाने के लिए ज़रूरी है. होस्ट के लिए भी यह ज़रूरी है, ताकि वह मीडिया के हिसाब से सूचनाएं बना सके.

Media3 लाइब्रेरी का इस्तेमाल करने वाले ऐप्लिकेशन के लिए, आपको अपने MediaLibrarySession.Callback में कस्टम SessionCommand लागू करना होगा. ये ऐप्लिकेशन, स्टैंडर्ड MediaSessionCompat.Token के बजाय PlatformToken का इस्तेमाल करते हैं. यह कस्टम 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();

कार ऐप्लिकेशन लाइब्रेरी 1.9 के कॉम्पोनेंट और सुविधाएं

Car App Library API के वर्शन 1.9 में, ब्राउज़िंग की खास सुविधाओं के लिए पसंद के मुताबिक बनाए गए कॉम्पोनेंट शामिल किए गए हैं. जैसे, चिप, प्रोग्रेस बार, छोटे किए गए आइटम, इंटरैक्टिव और बड़ा किया गया हेडर, स्पॉटलाइट सेक्शन, और बैनर.

संगीत ऐप्लिकेशन के इंटरफ़ेस में, हाल ही में सुने गए गाने और एल्बम दिखाए गए हैं. इनमें दो वर्टिकल लाइनें और तीन हॉरिज़ॉन्टल एल्बम आर्ट पोर्ट्रेट शामिल हैं.

तीसरी इमेज: इसमें Chips, Condensed Items, Interactive Header, Grid Items, और Minimized Control Panel के साथ SectionedItemTemplate दिखाया गया है

संगीत ऐप्लिकेशन के इंटरफ़ेस में, हाल ही में सुने गए गाने और एल्बम दिखाए गए हैं. इनमें दो वर्टिकल लाइनें और तीन हॉरिज़ॉन्टल एल्बम आर्ट पोर्ट्रेट शामिल हैं.

चौथी इमेज: मीडिया ब्राउज़ करने की दो स्क्रीन दिखाई गई हैं. इनमें 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 का singleTask या singleTop इस्तेमाल किया गया हो, ताकि onNewIntent() को चालू किया जा सके.launchMode

<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();
    }
}