برنامههای رسانهای که از الگوهای «کتابخانه برنامههای ماشین» استفاده میکنند میتوانند تجربه مرور و بازپخش رسانه خود را سفارشیسازی کنند و درعینحال مطمئن شوند که این تجربه برای صفحهنمایش خودرو بهینهسازی شده است و حواسپرتیها را درحین رانندگی بهحداقل میرساند.
این راهنما فرض میکند که ازقبل برنامه رسانهای دارید که صدا را در تلفن پخش میکند
و برنامه رسانه شما با معماری برنامه رسانه Android مطابقت دارد. «کتابخانه برنامه خودرو» به شما امکان میدهد تجربه درونبرنامه را با الگوها جایگزین کنید، بهجای الگوهایی که بااستفاده از ساختار داده ساختن برنامههای رسانه برای خودرو
MediaBrowser ساخته شدهاند. همچنان باید MediaSession
برای کنترلهای بازپخش، و MediaBrowserService یا MediaLibraryService
ارائه دهید که برای توصیهها و دیگر تجربههای هوشمند استفاده میشود.
پیکربندی مانیفست برنامه
علاوهبر مراحل شرحدادهشده در استفاده از کتابخانه برنامه Android برای ماشینها، موارد زیر برای برنامههای رسانهای الگودار الزامی است:
اعلام پشتیبانی از دسته در مانیفست
برنامه شما باید androidx.car.app.category.MEDIA
دسته برنامه خودرو را در فیلتر قصد
CarAppService خود اعلام کند.
<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 روی ۸ تنظیم شده باشد.
<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>
سپس، اظهارنامه الگو را به automotive_app_desc.xml در منابع xml خود اضافه کنید. باید بهصورت زیر باشد:
<automotiveApp xmlns:android="http://schemas.android.com/apk/res/android">
<uses name="media"/>
<uses name="template"/>
</automotiveApp>
اعلام پشتیبانی از «سیستم عامل Android Automotive»
به دو روش مختلف میتوانید برنامه رسانه فعالشده Car App Library را در «سیستمعامل Android Automotive» توزیع کنید: بهصورت یک APK واحد یا بهصورت دو APK جداگانه. اگر یک فایل APK تکی توزیع کنید، این فایل از خودروهایی که برای «سیستم عامل Android Automotive» با میزبان «کتابخانه برنامه خودرو» فعال شدهاند پشتیبانی میکند و درغیراینصورت به برنامه MediaBrowserService یا MediaLibraryService برمیگردد، حتی برای نسخههای قدیمیتر Android (Android 10 تا Android 13). اگر تصمیم بگیرید دو فایل APK جداگانه توزیع کنید، میتوانید موارد جدید اضافهشده به نسخه Car App Library را بدون نگرانی از تأثیرگذاری بر نسخه MediaBrowserService یا MediaLibraryService برنامهتان بهروز کنید.
توزیع یک APK
هنگام توزیع یک APK برای Car App Library و نسخههای MediaBrowserService یا MediaLibraryService برنامهتان، بسیار مهم است که android.software.car.templates_host.media را روی 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
فایل APK شما با «کتابخانه برنامههای ماشین» و MediaBrowserService
یا MediaLibraryService باید با کد نسخه بالاتر و
minSdk که Android 14 (34) را هدف قرار میدهد فعال شود.
توزیع با دو APK
برای توزیع دو APK جداگانه، یکی بااستفاده از «کتابخانه برنامههای ماشین» و دیگری بااستفاده از
MediaBrowserService یا MediaLibraryService، این مراحل را دنبال کنید تا مطمئن شوید
قابلیتهای صحیح خودرو بهدرستی هدفیابی شدهاند.
هنگام ایجاد APK جداگانه برای نسخه «کتابخانه برنامههای ماشین» برنامهتان،
باید android.software.car.templates_host.media را روی
android:required=true تنظیم کنید. این کار تضمین میکند که برنامه فقط در ساختهای «سیستم عامل Android Automotive» که با پشتیبانی از میزبان «کتابخانه برنامه خودرو» تأیید شدهاند توزیع شود.
<uses-feature android:name="android.software.car.templates_host.media" android:required="true"/>
علاوهبر استفاده از android.software.car.templates_host.media و تنظیم آن روی
android:required=true، این مراحل را برای
فعال کردن سیستم عامل Android Automotive برای فعالیت قابلراهاندازی «کتابخانه برنامه خودرو»
دنبال کنید.
توزیع Play
فایل APK که از «کتابخانه برنامه خودرو» استفاده میکند باید در دسته هدف اختصاصی Automotive OS توزیع شود.
پشتیبانی از کنشهای گفتاری
برنامهتان را صوتی کنید تا کاربران بتوانند کنشهای رایج را در حالت دستآزاد انجام دهند.
برای دستورالعملهای دقیقتر پیادهسازی، به پشتیبانی از کنشهای گفتاری برای رسانه مراجعه کنید. با برنامه رسانه قالببندیشده، اگر فرمان صوتی دریافت کنید،
نیازی نیست MediaBrowserService یا MediaLibraryService خود را با
نتایج جستجو بهروز کنید. درعوض، کنشی به الگوی بازپخش رسانه اضافه کنید تا کاربر بتواند براساس آن پرسمان جستجو یا پخش، محتوای بیشتری پیدا کند. پشتیبانی از فرمانهای صوتی برای برآورده کردن دستورالعمل کیفیت VC-1 الزامی است.
ایجاد کردن «الگوی بازپخش»
MediaPlaybackTemplate اطلاعات بازپخش رسانه را در برنامه رسانه «کتابخانه برنامه خودرو» شما نمایش میدهد. این الگو امکان تنظیم سرصفحه با عنوان و کنشهای سفارشیسازیشدنی را فراهم میکند، درحالیکه اطلاعات رسانه و کنترلهای بازپخش توسط میزبان براساس وضعیت 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 استفاده میکنید،
یک کد MediaSession را بااستفاده از MediaPlaybackManager در
CarAppService ثبت کنید. درصورت عدم انجام این کار، هنگام ارسال 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 استفاده میکنند و بهجای MediaSessionCompat.Token استاندارد از PlatformToken استفاده میکنند، باید SessionCommand سفارشی را در MediaLibrarySession.Callback خود پیادهسازی کنید که کد پلاتفرم اصلی جلسه را برمیگرداند: session.platformToken. در
CarAppService این فرمان سفارشی را به جلسه ارسال کنید. پساز دریافت کردن
نشانواره پلاتفرم، آن را بااستفاده از
MediaSessionCompat.Token.fromToken(platformToken) تبدیل کنید و این نشانواره سازگار را
به «کتابخانه برنامه خودرو» در .registerMediaPlaybackToken() ارسال کنید.
سازماندهی رسانه بااستفاده از الگوها
برای سازماندهی رسانهها برای مرور، مثل آهنگها یا آلبومها، توصیه میکنیم از
SectionedItemTemplate استفاده کنید،
که به شما امکان میدهد از GridSection و
RowSection با هم استفاده کنید تا طرحبندیهایی ایجاد کنید که فهرستهای تصاویر
و موارد نوشتاری را ترکیب میکنند.
شکل ۲: SectionedItemTemplate حاوی RowSection و بهدنبال آن GridSection
استفاده از SectionedItemTemplate در TabTemplate
یکی از روشهای راحت برای دستهبندی رسانه در برنامه، استفاده از
SectionedItemTemplate در
TabTemplate است.
val template =
SectionedItemTemplate.Builder()...build();
val tabTemplate =
TabTemplate.Builder(tabCallback)
.setTabContents(TabContents.Builder(template).build)
.setHeaderAction(Action.APP_ICON)
…
.build();
ویژگیها و مؤلفههای نسخه ۱.۹ «کتابخانه برنامههای خودرو»
Car App Library API نسخه ۱.۹ مؤلفههای سفارشیشدهای را برای قابلیتهای مرور منحصربهفرد معرفی میکند، مانند تراشهها، نوار پیشرفت، موارد فشرده، سرصفحه تعاملی و گسترده، بخشهای Spotlight، و برنماها.
شکل ۳: 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 «کتابخانه برنامه خودرو» استفاده کنید. برنامه رسانه این کنش را بهصورت پانل کنترل کوچکشده نشان میدهد،
که برای برآورده کردن الزامات کیفی MFT-1 لازم است اگر
از Car App Library API نسخه ۱.۹ یا بالاتر استفاده میکنید. برای الگوهای دیگر، کنش سرصفحه
روش دیگری برای دستیابی به این هدف است.
مدیریت هدفهای بازپخش رسانه سیستم
وقتی برنامهای از سطح رسانه درحال پخش سیستم (مثلاً کارت رسانه) راهاندازی میشود، لازم است کاربر به MediaPlaybackTemplate هدایت شود. ما از برنامههای رسانهای میخواهیم که این Intent Action را مدیریت کنند تا
تجربهای یکپارچه برای کاربران فراهم شود.
کنش androidx.car.app.media.action.SHOW_MEDIA_PLAYBACK را به
فیلتر هدف مؤلفه «کتابخانه برنامههای» خودرو (CarAppActivity یا
ترامپولین Activity) اضافه کنید.
مطمئن شوید فعالیتتان از 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();
}
}