Android Automotive OS cho phép người dùng cài đặt ứng dụng trong ô tô. Để tiếp cận người dùng trên nền tảng này, bạn cần phân phối một ứng dụng được tối ưu hoá cho người lái và tương thích với Android Automotive OS. Bạn có thể sử dụng lại hầu hết đoạn mã và tài nguyên trong ứng dụng Android Auto của mình. Tuy nhiên, bạn cần tạo riêng một bản dựng đáp ứng những yêu cầu trên trang này.
Tổng quan về quá trình phát triển
Để thêm khả năng hỗ trợ Android Automotive OS, bạn chỉ cần thực hiện một vài bước theo mô tả trong các phần dưới đây:
- Bật các tính năng dành cho ô tô trong Android Studio
- Tạo mô-đun cho ô tô.
- Cập nhật phần phụ thuộc Gradle.
- Triển khai hoạt động cài đặt và đăng nhập (không bắt buộc)
- Bạn có thể Đọc gợi ý về máy chủ lưu trữ nội dung nghe nhìn.
Cân nhắc về thiết kế
Android Automotive OS sắp xếp nội dung đa phương tiện mà ứng dụng nhận được từ dịch vụ trình duyệt nội dung đa phương tiện của ứng dụng. Tức là ứng dụng sẽ không vẽ lại giao diện người dùng hay khởi chạy hoạt động nào khi người dùng kích hoạt chế độ phát nội dung đa phương tiện.
Nếu bạn đang triển khai hoạt động cài đặt hoặc đăng nhập, thì các hoạt động này phải được tối ưu hoá cho xe. Hãy tham khảo Nguyên tắc thiết kế dành cho Android Automotive OS khi thiết kế những phần như vậy trong ứng dụng.
Thiết lập dự án
Bạn cần thiết lập một số phần trong dự án của ứng dụng để có thể hỗ trợ Android Automotive OS.
Bật các tính năng dành cho ô tô trong Android Studio
Sử dụng phiên bản Android Studio 4.0 trở lên để đảm bảo rằng tất cả các tính năng của Automotive OS đều được bật.
Tạo mô-đun ô tô
Một số thành phần của Android Automotive OS (chẳng hạn như tệp kê khai) có những yêu cầu riêng tuỳ theo nền tảng. Hãy tạo một mô-đun có thể tách biệt đoạn mã cho các thành phần này với đoạn mã khác trong dự án của bạn (ví dụ như đoạn mã dùng trong ứng dụng dành cho điện thoại).
Làm theo các bước sau để thêm mô-đun ô tô vào dự án:
- Trong Android Studio, hãy nhấp vào File > New > New Module (Tệp > Mới > Mô-đun mới).
- Chọn Automotive Module (Mô-đun Automotive), rồi nhấp vào Next (Tiếp theo).
- Nhập Application/Library name (Tên thư viện/ứng dụng). Đây là tên ứng dụng mà người dùng sẽ nhìn thấy trên Android Automotive OS.
- Nhập Module name (Tên mô-đun).
- Điều chỉnh Package name (Tên gói) cho phù hợp với ứng dụng.
Chọn API 28: Android 9.0 (Pie) cho Minimum SDK (SDK tối thiểu), sau đó nhấp vào Next (Tiếp theo).
Mọi ô tô hỗ trợ Android Automotive OS đều chạy trên Android 9 (API cấp 28) trở lên. Vì vậy, việc chọn giá trị này sẽ nhắm đến mọi ô tô tương thích.
Chọn No Activity (Không có hoạt động) rồi nhấp vào Finish (Hoàn tất).
Sau khi tạo mô-đun trong Android Studio, hãy mở AndroidManifest.xml trong mô-đun ô tô mới:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.media">
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme" />
<uses-feature
android:name="android.hardware.type.automotive"
android:required="true" />
</manifest>
Phần tử <application> chứa một số thông tin tiêu chuẩn về ứng dụng cùng một phần tử <uses-feature> khai báo việc hỗ trợ Android Automotive OS.
Xin lưu ý rằng không có hoạt động nào được khai báo trong tệp kê khai.
Nếu bạn triển khai các chế độ cài đặt hoặc hoạt động đăng nhập, hãy thêm chúng vào đây. Các hoạt động này là các hoạt động duy nhất cần khai báo trong tệp kê khai cho ứng dụng trên Android Automotive OS, được hệ thống kích hoạt bằng cách sử dụng ý định tường minh.
Sau khi thêm hoạt động cài đặt hoặc đăng nhập, hãy hoàn tất tệp kê khai bằng cách thiết lập thuộc tính android:appCategory của phần tử <application> thành "audio".
<application
...
android:appCategory="audio" />
Khai báo yêu cầu về tính năng
Tất cả ứng dụng được tạo cho Android Automotive OS đều phải đáp ứng một số yêu cầu nhất định để được phân phối bằng Google Play. Hãy xem bài viết Đáp ứng các yêu cầu về tính năng của Google Play để biết thêm thông tin.
Khai báo việc hỗ trợ nội dung nghe nhìn cho Android Automotive OS
Hãy sử dụng mục kê khai sau đây để khai báo rằng ứng dụng của bạn có hỗ trợ Android Automotive OS:
<application>
...
<meta-data android:name="com.android.automotive"
android:resource="@xml/automotive_app_desc"/>
...
</application>
Mục kê khai này là một tệp XML khai báo những chức năng cho ô tô mà ứng dụng của bạn hỗ trợ.
Để biểu thị việc bạn có một ứng dụng đa phương tiện, hãy thêm tệp XML có tên automotive_app_desc.xml vào thư mục res/xml/ trong dự án. Đưa nội dung sau đây vào tệp này:
<automotiveApp>
<uses name="media"/>
</automotiveApp>
Bộ lọc ý định
Android Automotive OS sử dụng ý định tường minh để kích hoạt các hoạt động trong ứng dụng đa phương tiện. Đừng thêm bất kỳ hoạt động nào có bộ lọc ý định CATEGORY_LAUNCHER hoặc ACTION_MAIN vào tệp kê khai.
Các hoạt động tương tự như trong ví dụ sau thường nhắm đến điện thoại hoặc một số thiết bị di động khác. Hãy khai báo các hoạt động này trong mô-đun xây dựng ứng dụng điện thoại, chứ không phải trong mô-đun xây dựng ứng dụng cho Android Automotive OS.
<activity android:name=".MyActivity">
<intent-filter>
<!-- You can't use either of these intents for Android Automotive OS -->
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
<!--
In their place, you can include other intent filters for any activities
that your app needs for Android Automotive OS, such as settings or
sign-in activities.
-->
</intent-filter>
</activity>
Cập nhật phần phụ thuộc Gradle
Bạn nên đặt dịch vụ trình duyệt nội dung đa phương tiện trong một mô-đun riêng biệt mà bạn dùng chung giữa ứng dụng điện thoại và mô-đun ô tô. Nếu đang áp dụng phương pháp này, bạn cần cập nhật mô-đun ô tô của mình để thêm mô-đun dùng chung, như minh hoạ trong đoạn mã sau:
my-auto-module/build.gradle
Groovy
buildscript { ... dependencies { ... implementation project(':shared_module_name') } }
Kotlin
buildscript { ... dependencies { ... implementation(project(":shared_module_name")) } }
Triển khai hoạt động cài đặt và đăng nhập
Ngoài dịch vụ trình duyệt nội dung đa phương tiện, bạn cũng có thể cung cấp các hoạt động cài đặt và đăng nhập được tối ưu hoá cho xe cho ứng dụng của mình trên Android Automotive OS. Các hoạt động này cho phép bạn cung cấp chức năng của ứng dụng không có sẵn trong các API Android Media.
Chỉ triển khai các hoạt động này nếu ứng dụng trên Android Automotive OS cần cho phép người dùng đăng nhập hoặc thay đổi các chế độ cài đặt của ứng dụng. Những hoạt động này không được Android Auto sử dụng.
Quy trình hoạt động
Sơ đồ sau cho biết cách người dùng tương tác với các chế độ cài đặt và đăng nhập khi sử dụng Android Automotive OS:
Hình 1. Quy trình cho hoạt động cài đặt và đăng nhập.
Ngăn các yếu tố gây xao lãng trong hoạt động cài đặt và đăng nhập của bạn
Để đảm bảo các hoạt động cài đặt và đăng nhập của bạn chỉ sử dụng được trong khi xe của người dùng đang đỗ, hãy xác minh rằng(các) phần tử <activity> không bao gồm phần tử <meta-data> sau đây. Ứng dụng của bạn sẽ bị từ chối trong quá trình xem xét nếu có phần tử như vậy.
<!-- NOT ALLOWED -->
<meta-data
android:name="distractionOptimized"
android:value="true"/>
Thêm hoạt động cài đặt
Bạn có thể thêm hoạt động cài đặt được tối ưu hoá cho xe, để người dùng có thể định cấu hình các chế độ cài đặt cho ứng dụng trong ô tô của họ. Hoạt động cài đặt cũng có thể cung cấp các quy trình khác, như đăng nhập hoặc đăng xuất khỏi tài khoản của người dùng hay chuyển đổi tài khoản người dùng. Hãy nhớ rằng hoạt động này chỉ được kích hoạt bởi một ứng dụng chạy trên Android Automotive OS. Các ứng dụng điện thoại kết nối với Android Auto không sử dụng hoạt động này.
Khai báo hoạt động cài đặt
Bạn phải khai báo hoạt động cài đặt của mình trong tệp kê khai của ứng dụng, như được minh hoạ trong đoạn mã sau:
<application>
...
<activity android:name=".AppSettingsActivity"
android:exported="true"
android:theme="@style/SettingsActivity"
android:label="@string/app_settings_activity_title">
<intent-filter>
<action android:name="android.intent.action.APPLICATION_PREFERENCES"/>
</intent-filter>
</activity>
...
</application>
Triển khai hoạt động cài đặt
Khi một người dùng chạy ứng dụng, Android Automotive OS sẽ phát hiện hoạt động cài đặt mà bạn đã khai báo và hiển thị một affordance (thuộc tính), chẳng hạn như biểu tượng.
Người dùng có thể nhấn hoặc chọn affordance này trên màn hình của ô tô để chuyển đến hoạt động. Android Automotive OS gửi ý định ACTION_APPLICATION_PREFERENCES để giúp ứng dụng bắt đầu hoạt động cài đặt.
Nội dung còn lại của phần này cho biết cách điều chỉnh mã trong ứng dụng mẫu Universal Android Music Player (UAMP) để triển khai hoạt động cài đặt cho ứng dụng.
Để bắt đầu, hãy tải mã mẫu xuống:
# Clone the UAMP repositorygit clone https://github.com/android/uamp.git# Fetch the appropriate pull request to your local repositorygit fetch origin pull/323/head:NEW_LOCAL_BRANCH_NAME# Switch to the new branchgit checkout NEW_LOCAL_BRANCH_NAME
Để triển khai hoạt động, hãy làm theo các bước sau:
- Sao chép thư mục
automotive/automotive-libvào mô-đun ô tô. - Xác định cây lựa chọn ưu tiên như trong
automotive/src/main/res/xml/preferences.xml. Triển khai
PreferenceFragmentCompatmà hoạt động cài đặt của bạn hiển thị. Xem các tệpSettingsFragment.ktvàSettingsActivity.kttrong UAMP và Hướng dẫn cài đặt Android để biết thêm thông tin.
Khi triển khai hoạt động cài đặt, hãy cân nhắc dùng các phương pháp hay nhất dưới đây trong việc sử dụng một số thành phần trong Thư viện lựa chọn ưu tiên:
- Chỉ phân nhiều nhất 2 cấp dưới thành phần hiển thị chính trong hoạt động cài đặt.
- Đừng sử dụng
DropDownPreference. Thay vào đó hãy sử dụngListPreference. - Thành phần tổ chức:
PreferenceScreen- Đây phải là cấp cao nhất trong cây tuỳ chọn.
PreferenceCategory- Thuộc tính này dùng để nhóm các đối tượng
Preferencelại với nhau. - Đưa vào một
title.
- Thuộc tính này dùng để nhóm các đối tượng
- Thêm
keyvàtitlevào tất cả thành phần dưới đây. Bạn cũng có thể thêmsummary,iconhoặc cả hai:Preference- Tuỳ chỉnh logic trong lệnh gọi
onPreferenceTreeClick()của quá trình triển khaiPreferenceFragmentCompat.
- Tuỳ chỉnh logic trong lệnh gọi
CheckBoxPreference- Có thể dùng
summaryOnhoặcsummaryOffthay chosummaryđối với văn bản có điều kiện.
- Có thể dùng
SwitchPreference- Có thể dùng
summaryOnhoặcsummaryOffthay chosummaryđối với văn bản có điều kiện. - Có thể thiết lập
switchTextOnhoặcswitchTextOff.
- Có thể dùng
SeekBarPreference- Bao gồm
min,maxvàdefaultValue.
- Bao gồm
EditTextPreference- Bao gồm
dialogTitle,positiveButtonTextvànegativeButtonText. - Có thể có một hoặc cả hai cờ
dialogMessagevàdialogLayoutResource.
- Bao gồm
com.example.android.uamp.automotive.lib.ListPreference- Lấy dữ liệu chủ yếu từ
ListPreference - Dùng để hiển thị danh sách có một lựa chọn về các đối tượng
Preference. - Phải có một mảng
entriesvàentryValuestương ứng.
- Lấy dữ liệu chủ yếu từ
com.example.android.uamp.automotive.lib.MultiSelectListPreference- Chủ yếu bắt nguồn từ
MultiSelectListPreference - Dùng để hiển thị một danh sách có nhiều lựa chọn về các đối tượng
Preference. - Phải có một mảng
entriesvàentryValuestương ứng.
- Chủ yếu bắt nguồn từ
Thêm hoạt động đăng nhập
Nếu người dùng bắt buộc phải đăng nhập để được sử dụng ứng dụng, bạn có thể thêm hoạt động đăng nhập đã tối ưu hoá cho xe để xử lý tính năng đăng nhập và đăng xuất khỏi ứng dụng. Bạn cũng có thể thêm quy trình đăng nhập và đăng xuất vào hoạt động cài đặt nhưng nếu ứng dụng đòi hỏi người dùng đăng nhập mới có thể sử dụng, hãy dùng hoạt động đăng nhập chuyên biệt. Hãy nhớ rằng hoạt động này chỉ được kích hoạt bởi ứng dụng chạy trên Android Automotive OS. Các ứng dụng điện thoại kết nối với Android Auto không sử dụng hoạt động này.
Yêu cầu đăng nhập khi khởi động ứng dụng
Để yêu cầu người dùng đăng nhập trước khi sử dụng ứng dụng, dịch vụ trình duyệt đa phương tiện phải thực hiện những việc sau:
- Trong phương thức
onLoadChildren()của dịch vụ, hãy gửi kết quảnullbằng phương thứcsendResult(). - Đặt
PlaybackStateCompatcủa phiên đa phương tiện thànhSTATE_ERRORbằng cách sử dụng phương thứcsetState(). Điều này cho Android Automotive OS biết rằng không thể thực hiện hoạt động nào khác cho đến khi lỗi được giải quyết. - Đặt mã lỗi
PlaybackStateCompatcủa phiên đa phương tiện thànhERROR_CODE_AUTHENTICATION_EXPIRED. Điều này cho Android Automotive OS biết rằng người dùng cần phải xác thực. - Đặt thông báo lỗi
PlaybackStateCompatcủa phiên đa phương tiện bằng phương thứcsetErrorMessage(). Vì thông báo lỗi này chỉ dành cho người dùng nên phải được bản địa hoá theo ngôn ngữ hiện tại của người dùng. Đặt thông tin bổ sung về
PlaybackStateCompatcủa phiên đa phương tiện bằng phương thứcsetExtras(). Thêm vào hai hoặc ba khoá sau:PLAYBACK_STATE_EXTRAS_KEY_ERROR_RESOLUTION_ACTION_LABEL: Một chuỗi hiển thị trên nút bắt đầu quy trình đăng nhập. Vì chuỗi này chỉ dành cho người dùng nên phải được bản địa hoá theo ngôn ngữ hiện tại của người dùng.PLAYBACK_STATE_EXTRAS_KEY_ERROR_RESOLUTION_ACTION_INTENT:PendingIntentchuyển hướng người dùng đến hoạt động đăng nhập khi người dùng nhấn vào nút màPLAYBACK_STATE_EXTRAS_KEY_ERROR_RESOLUTION_ACTION_LABELtham chiếu đến.PLAYBACK_STATE_EXTRAS_KEY_ERROR_RESOLUTION_USING_CAR_APP_LIBRARY_INTENT:PendingIntentchuyển hướng người dùng đến hoạt động đăng nhập Thư viện ứng dụng ô tô. Vì máy chủ Thư viện ứng dụng cho ô tô được tối ưu hoá cho việc lái xe, nên ý định này sẽ tự động bỏ qua màn hình giải quyết lỗi và hiển thị ngay màn hình đăng nhập của bạn. Nếu bạn đặt giá trị bổ sung này, hãy đặt cả hai giá trị bổ sung trước đó để đảm bảo khả năng tương thích ngược với các xe cũ.
Đoạn mã sau đây giới thiệu cách để yêu cầu người dùng phải đăng nhập trước khi sử dụng ứng dụng của bạn:
Kotlin
import androidx.media.utils.MediaConstants val signInIntent = Intent(this, SignInActivity::class.java) val signInActivityPendingIntent = PendingIntent.getActivity(this, 0, signInIntent, 0) val extras = Bundle().apply { putString( MediaConstants.PLAYBACK_STATE_EXTRAS_KEY_ERROR_RESOLUTION_ACTION_LABEL, "Sign in" ) putParcelable( MediaConstants.PLAYBACK_STATE_EXTRAS_KEY_ERROR_RESOLUTION_ACTION_INTENT, signInActivityPendingIntent ) } val playbackState = PlaybackStateCompat.Builder() .setState(PlaybackStateCompat.STATE_ERROR, 0, 0f) .setErrorMessage( PlaybackStateCompat.ERROR_CODE_AUTHENTICATION_EXPIRED, "Authentication required" ) .setExtras(extras) .build() mediaSession.setPlaybackState(playbackState)
Java
import androidx.media.utils.MediaConstants; Intent signInIntent = new Intent(this, SignInActivity.class); PendingIntent signInActivityPendingIntent = PendingIntent.getActivity(this, 0, signInIntent, 0); Bundle extras = new Bundle(); extras.putString( MediaConstants.PLAYBACK_STATE_EXTRAS_KEY_ERROR_RESOLUTION_ACTION_LABEL, "Sign in"); extras.putParcelable( MediaConstants.PLAYBACK_STATE_EXTRAS_KEY_ERROR_RESOLUTION_ACTION_INTENT, signInActivityPendingIntent); PlaybackStateCompat playbackState = new PlaybackStateCompat.Builder() .setState(PlaybackStateCompat.STATE_ERROR, 0, 0f) .setErrorMessage( PlaybackStateCompat.ERROR_CODE_AUTHENTICATION_EXPIRED, "Authentication required" ) .setExtras(extras) .build(); mediaSession.setPlaybackState(playbackState);
Sau khi xác thực người dùng thành công, hãy đặt PlaybackStateCompat trở lại một trạng thái khác với STATE_ERROR, sau đó đưa người dùng quay lại Android Automotive OS bằng cách gọi phương thức finish() của hoạt động đăng nhập.
Triển khai hoạt động đăng nhập
Google cung cấp nhiều công cụ nhận dạng mà bạn có thể sử dụng để giúp người dùng đăng nhập vào ứng dụng trong ô tô. Một số công cụ, chẳng hạn như Xác thực Firebase, cung cấp các bộ công cụ full-stack có thể giúp bạn xây dựng trải nghiệm xác thực tuỳ thích. Các công cụ khác tận dụng thông tin xác thực hiện có của người dùng hoặc các công nghệ khác để giúp bạn xây dựng trải nghiệm đăng nhập trơn tru cho người dùng.
Các công cụ sau đây có thể giúp bạn xây dựng trải nghiệm đăng nhập dễ dàng hơn cho những người dùng trước đó từng đăng nhập trên một thiết bị khác:
- Đăng ký và Đăng nhập bằng một lần chạm: nếu bạn đã triển khai tính năng Một lần chạm cho các thiết bị khác (chẳng hạn như ứng dụng điện thoại), hãy triển khai tính năng này cho ứng dụng của bạn trên Android Automotive OS để hỗ trợ người dùng vốn sử dụng tính năng Một lần chạm.
- Đăng nhập bằng Google: nếu bạn đã triển khai tính năng Đăng nhập bằng Google cho các thiết bị khác, chẳng hạn như ứng dụng điện thoại, hãy triển khai tính năng này cho ứng dụng của bạn trên Android Automotive OS để hỗ trợ người dùng vốn Đăng nhập bằng Google.
- Tự động điền bằng Google: nếu người dùng đã sử dụng tính năng Tự động điền bằng Google trên các thiết bị Android khác thì thông tin xác thực của người dùng sẽ được lưu vào Trình quản lý mật khẩu của Google. Khi những người dùng đó đăng nhập vào ứng dụng trên Android Automotive OS, tính năng Tự động điền bằng Google sẽ đề xuất thông tin xác thực đã lưu có liên quan. Việc sử dụng tính năng Tự động điền bằng Google không đòi hỏi nhà phát triển ứng dụng tốn nhiều công sức. Tuy nhiên, nhà phát triển ứng dụng có thể tối ưu hoá ứng dụng để có được kết quả chất lượng cao hơn. Tính năng Tự động điền bằng Google được hỗ trợ trên tất cả thiết bị chạy Android 8.0 (API cấp 26) trở lên, bao gồm cả Android Automotive OS.
Sử dụng AccountManager
Các ứng dụng trên Android Automotive OS có trình xác thực thì phải sử dụng AccountManager vì những lý do sau:
- Trải nghiệm người dùng tốt hơn và dễ dàng quản lý tài khoản: người dùng có thể quản lý tất cả tài khoản của họ trên trình đơn tài khoản trong phần cài đặt hệ thống, bao gồm cả hoạt động đăng nhập và đăng xuất.
- Trải nghiệm dành cho "khách": ô tô là thiết bị dùng chung, nghĩa là OEM (Nhà sản xuất thiết bị gốc) có thể bật trải nghiệm "khách" trong xe nhằm ngăn việc thêm tài khoản. Bạn có thể thiết lập chế độ hạn chế này bằng cách sử dụng
DISALLOW_MODIFY_ACCOUNTSchoAccountManager.
Quyền
Nếu bạn cần yêu cầu người dùng cấp quyền, hãy sử dụng quy trình tương tự như hoạt động xác thực hoặc hoạt động cài đặt trong sơ đồ quy trình hoạt động trình bày ở phần trước.
Triển khai tính năng đăng xuất
Bất kể bạn chọn triển khai quy trình đăng nhập như thế nào, khi người dùng đăng xuất, bạn phải gọi MediaBrowserServiceCompat#notifyChildrenChanged(rootId) để vô hiệu hoá cây duyệt qua để ứng dụng lưu trữ nội dung nghe nhìn xoá mọi thông tin liên quan đến người dùng (chẳng hạn như cụm từ tìm kiếm gần đây nhất).
Khởi động ứng dụng lưu trữ nội dung nghe nhìn
Bạn có thể tạo ý định mở ứng dụng lưu trữ nội dung nghe nhìn cho ứng dụng hoặc nội dung trong ứng dụng của mình. Ví dụ:
- Ứng dụng của bạn có thể đăng một thông báo kèm theo ý định đang chờ xử lý cho phép người dùng mở ứng dụng để nghe một nội dung mới.
- Ứng dụng của bạn có thể xử lý đường liên kết sâu và mở ứng dụng lưu trữ ở chế độ xem phù hợp nhất.
Xác định các chức năng của máy chủ lưu trữ nội dung nghe nhìn
Các phiên bản của ứng dụng lưu trữ nội dung nghe nhìn hỗ trợ nhiều chức năng. Các máy chủ cho biết khả năng hỗ trợ các chức năng khác nhau bằng cách thêm bộ lọc ý định cho các thao tác ý định sau:
Tất cả ứng dụng lưu trữ nội dung nghe nhìn đều hỗ trợ ý định MEDIA_TEMPLATE. Để xác định xem máy chủ lưu trữ nội dung nghe nhìn có hỗ trợ ý định MEDIA_TEMPLATE_V2 hay không, bạn có thể sử dụng queryIntentActivities() như sau:
val isMediaTemplateV2Supported = packageManager.queryIntentActivities(
Intent(MediaIntentExtras.ACTION_MEDIA_TEMPLATE_V2),
// MATCH_DEFAULT_ONLY since the host should be started with implicit intents
// MATCH_SYSTEM_ONLY excludes any apps that aren't preinstalled
PackageManager.MATCH_DEFAULT_ONLY or PackageManager.MATCH_SYSTEM_ONLY
).size > 0
Tạo và sử dụng ý định
Tuỳ thuộc vào những thao tác theo ý định mà máy chủ lưu trữ nội dung nghe nhìn hỗ trợ và trường hợp sử dụng cụ thể của bạn, bạn có thể cung cấp các phần bổ sung sau đây khi tạo ý định mà bạn dùng để khởi động ứng dụng máy chủ lưu trữ nội dung nghe nhìn.
| Khoá bổ sung | Loại | Mô tả | Thao tác được hỗ trợ |
|---|---|---|---|
EXTRA_KEY_MEDIA_COMPONENT |
String |
Tên thành phần được rút gọn của MediaBrowserService ứng dụng lưu trữ nội dung nghe nhìn cần kết nối – thường là tên thành phần cho ứng dụng của bạn. Nếu không chỉ định phần bổ sung này, thì máy chủ lưu trữ nội dung nghe nhìn sẽ mặc định là nguồn nội dung nghe nhìn đang hoạt động. |
MEDIA_TEMPLATE, MEDIA_TEMPLATE_V2 |
EXTRA_KEY_SEARCH_QUERY |
String |
Cụm từ tìm kiếm sẽ được dùng khi gọi | MEDIA_TEMPLATE, MEDIA_TEMPLATE_V2 |
EXTRA_KEY_MEDIA_ID |
String |
Mã nhận dạng nội dung nghe nhìn cần mở ở chế độ xem duyệt qua. | MEDIA_TEMPLATE_V2 |
EXTRA_KEY_SEARCH_ACTION |
Integer |
Hành động cần thực hiện sau khi quá trình tìm kiếm EXTRA_KEY_SEARCH_QUERY hoàn tất. |
MEDIA_TEMPLATE_V2 |
Ví dụ: với một máy chủ lưu trữ hỗ trợ các thao tác MEDIA_TEMPLATE_V2, mã sau đây sẽ mở ứng dụng máy chủ lưu trữ nội dung nghe nhìn, kết nối ứng dụng đó với MyMediaBrowserService, thực hiện tìm kiếm "Jazz", rồi phát mục đầu tiên trong kết quả tìm kiếm. Trên tất cả các máy chủ lưu trữ khác, thao tác này sẽ chỉ mở ứng dụng máy chủ lưu trữ nội dung nghe nhìn và thực hiện tìm kiếm "Jazz", để người dùng chọn một mục để phát trong số các kết quả.
val startMediaHostIntent = Intent(ACTION_MEDIA_TEMPLATE)
.putExtra(MediaIntentExtras.EXTRA_KEY_MEDIA_COMPONENT, MyMediaBrowserService::class.java)
.putExtra(MediaIntentExtras.EXTRA_KEY_SEARCH_QUERY, "Jazz")
.putExtra(MediaIntentExtras.EXTRA_KEY_SEARCH_ACTION, MediaIntentExtras.EXTRA_VALUE_PLAY_FIRST_ITEM_FROM_SEARCH)
context.startActivity(startMediaHostIntent)
Hỗ trợ đường liên kết sâu
Để cải thiện trải nghiệm của ứng dụng đa phương tiện trên các thiết bị Android Automotive OS, bạn có thể thêm tính năng hỗ trợ đường liên kết sâu vào ứng dụng. Ví dụ: tính năng này cho phép người dùng mở ứng dụng của bạn ngay từ trình duyệt hoặc khi nhận được một URL được chia sẻ từ điện thoại bằng tính năng Chia sẻ nhanh.
Thêm bộ lọc ý định đường liên kết sâu
Để thông báo cho hệ điều hành rằng ứng dụng của bạn có thể xử lý các đường liên kết sâu, ứng dụng đó cần có các hoạt động với bộ lọc ý định phù hợp. Hãy xem phần Thêm bộ lọc ý định cho các đường liên kết đến để biết hướng dẫn về định dạng của bộ lọc ý định dùng cho đường liên kết sâu.
Để mang lại trải nghiệm tốt nhất cho người dùng, hãy hỗ trợ tất cả các đường liên kết sâu mà ứng dụng di động của bạn hỗ trợ, nếu ứng dụng trên ô tô có thể hỗ trợ các đường liên kết đó một cách hợp lý. Nếu ứng dụng của bạn có các hoạt động cài đặt hoặc đăng nhập, thì bộ lọc ý định để xử lý các đường liên kết sâu cài đặt và đăng nhập phải được khai báo trong các phần tử tệp kê khai <activity> tương ứng. Đối với đường liên kết sâu để phát và duyệt xem nội dung nghe nhìn, bạn có thể dùng một hoạt động trung gian như mô tả ở phần sau trong mục này.
Xử lý ý định liên kết sâu
Hãy xem phần Đọc dữ liệu từ các ý định đến để biết hướng dẫn về cách đọc và phản hồi ý định dùng để bắt đầu hoạt động của ứng dụng.
Xử lý đường liên kết sâu để phát và duyệt xem nội dung nghe nhìn
Vì giao diện người dùng để duyệt xem và phát được ứng dụng lưu trữ vẽ, nên hoạt động dùng để xử lý đường liên kết sâu cho các thao tác phát và duyệt xem không được có giao diện người dùng riêng.
Thay vào đó, bạn nên chủ yếu dùng phương thức này để tạo và sử dụng một ý định nhằm khởi động ứng dụng lưu trữ nội dung nghe nhìn. Nếu cần, phương thức này cũng có thể xử lý mọi thay đổi bổ sung đối với trạng thái của ứng dụng, chẳng hạn như thêm một mục nội dung nghe nhìn vào hàng đợi. Đoạn mã sau đây minh hoạ một ví dụ về cách triển khai hoạt động đàn hồi:
fun DeepLinkTrampolineActivity : ComponentActivity() {
override fun onCreate() {
handleIntent(intent)
}
override fun onNewIntent(intent: Intent) {
handleIntent(intent)
}
private fun handleIntent(intent: Intent) {
// Handle any side effects, such as adding a song to the queue
...
// Build the intent used to start the media host app
val startMediaHostIntent = ...
startActivity(intent)
// Finish the activity immediately so it isn't shown on screen
finish()
}
}
Đọc gợi ý về máy chủ lưu trữ nội dung nghe nhìn
Tuỳ thuộc vào ứng dụng hệ thống (bao gồm cả phiên bản) kết nối với dịch vụ trình duyệt nội dung nghe nhìn, ứng dụng của bạn có thể nhận được các dữ liệu bổ sung sau:
Xử lý lỗi
Lỗi trong các ứng dụng đa phương tiện trên Android Automotive OS được thông báo bằng PlaybackStateCompat của phiên phát nội dung đa phương tiện. Đối với tất cả các lỗi, hãy đặt mã lỗi và thông báo lỗi thích hợp vào PlaybackStateCompat. Điều này khiến Toast xuất hiện trong giao diện người dùng.
Khi ứng dụng xảy ra lỗi nhưng vẫn có thể tiếp tục phát, hãy đưa ra lỗi không nghiêm trọng. Ví dụ: người dùng có thể phát nhạc trong ứng dụng trước khi đăng nhập. Tuy nhiên, người dùng phải đăng nhập để có thể bỏ qua bài hát. Khi bạn dùng trạng thái lỗi không nghiêm trọng, hệ thống có thể đề xuất người dùng đăng nhập mà không làm gián đoạn mục nội dung nghe nhìn đang phát.
Khi bạn dùng trạng thái lỗi không nghiêm trọng, hãy giữ nguyên phần còn lại của PlaybackStateCompat, ngoài mã lỗi và thông báo lỗi. Phương pháp này cho phép tiếp tục phát mục nội dung nghe nhìn hiện tại trong lúc người dùng quyết định có đăng nhập hay không.
Trong trường hợp không thể phát, chẳng hạn như khi không có kết nối Internet và không có nội dung ngoại tuyến, hãy đặt trạng thái PlaybackStateCompat thành STATE_ERROR.
Trong các lần cập nhật PlaybackStateCompat tiếp theo, hãy xoá mọi mã lỗi và thông báo lỗi để tránh việc hiển thị nhiều cảnh báo cho cùng một lỗi.
Tại một thời điểm bất kỳ, nếu bạn không thể tải cây duyệt xem (ví dụ: nếu bạn yêu cầu xác thực và người dùng chưa đăng nhập), hãy gửi một cây duyệt xem trống. Để biểu thị điều này, hãy trả về một kết quả rỗng từ onLoadChildren() cho nút phương tiện gốc. Khi điều này xảy ra, hệ thống sẽ hiển thị lỗi toàn màn hình với thông báo lỗi được đặt trong PlaybackStateCompat.
Lỗi có thể xử lý
Nếu có một lỗi xử lý được, hãy thiết lập thêm hai tuỳ chọn bổ sung sau đây trong PlaybackStateCompat:
PLAYBACK_STATE_EXTRAS_KEY_ERROR_RESOLUTION_ACTION_LABEL: nhãn cho nút khắc phục lỗi. Vì chuỗi này chỉ dành cho người dùng nên phải được bản địa hoá theo ngôn ngữ hiện tại của người dùng.PLAYBACK_STATE_EXTRAS_KEY_ERROR_RESOLUTION_ACTION_INTENT: làPendingIntentmà nút chạy để khắc phục lỗi, chẳng hạn như bằng cách chạy hoạt động đăng nhập.
Các lỗi có thể xử lý xuất hiện dưới dạng Dialog mà người dùng chỉ có thể khắc phục khi dừng ô tô.
Kiểm thử các trường hợp lỗi
Xác minh rằng ứng dụng của bạn xử lý lỗi một cách linh hoạt trong mọi trường hợp, trong đó có:
- Các cấp độ khác nhau của sản phẩm:chẳng hạn như phiên bản miễn phí so với phiên bản đặc biệt hoặc khi đăng nhập so với khi đăng xuất
- Đa dạng trạng thái lái xe: chẳng hạn như khi đỗ xe so với khi lái xe.
- Đa dạng trạng thái kết nối: chẳng hạn như trực tuyến so với ngoại tuyến.
Lưu ý khác
Hãy ghi nhớ những điều cần xem xét sau đây khi phát triển ứng dụng cho Android Automotive OS:
Nội dung ngoại tuyến
Nếu có thể, hãy tích hợp tính năng hỗ trợ phát ngoại tuyến. Ô tô chạy bằng Android Automotive OS sẽ có khả năng kết nối dữ liệu riêng, nghĩa là một gói dữ liệu sẽ được tính vào chi phí của xe hoặc do người dùng thanh toán. Tuy nhiên, ô tô cũng sẽ có nhiều cách thức kết nối hơn so với thiết bị di động.
Sau đây là một vài điều cần lưu ý khi bạn xem xét chiến lược hỗ trợ ngoại tuyến:
- Thời điểm tốt nhất để tải nội dung xuống là trong lúc ứng dụng đang được sử dụng.
- Đừng giả định rằng có sẵn Wi-Fi. Ô tô có thể không bao giờ đi vào phạm vi Wi-Fi, hoặc có thể OEM đã vô hiệu hoá tính năng bắt Wi-Fi để sử dụng mạng di động.
- Mặc dù bạn có thể lưu vào bộ nhớ đệm những nội dung mà người dùng có khả năng sẽ sử dụng, nhưng bạn nên cho phép người dùng thay đổi hành vi này thông qua hoạt động cài đặt.
- Dung lượng ổ đĩa trên ô tô có thể thay đổi, vì vậy, hãy cung cấp cho người dùng một cách để xoá nội dung ngoại tuyến, chẳng hạn như thông qua một tuỳ chọn trong hoạt động cài đặt.
Hỗ trợ WebView
WebView được hỗ trợ trong Android Automotive OS, nhưng chỉ được phép cho các hoạt động cài đặt và đăng nhập. Các hoạt động sử dụng WebView phải có thuộc tính tương tác với tính năng "đóng" hoặc "quay lại" bên ngoài WebView.
Sau đây là ví dụ về một số trường hợp sử dụng được chấp nhận đối với WebView:
- Hiển thị chính sách quyền riêng tư, điều khoản dịch vụ hoặc các đường liên kết liên quan đến pháp lý khác trong hoạt động cài đặt.
- Một luồng dựa trên nền tảng web trong hoạt động đăng nhập của bạn.
Khi sử dụng WebView, bạn có thể bật JavaScript.
Bảo mật WebView
Bạn nên thực hiện tất cả các biện pháp phòng ngừa giúp đảm bảo WebView không trở thành một điểm truy cập vào mạng lưới Internet rộng hơn. Hãy xem đoạn mã sau đây để tham khảo một ví dụ về cách khoá WebView với URL dùng trong lệnh gọi loadUrl() và ngăn lệnh chuyển hướng. Bạn nên triển khai các biện pháp bảo vệ như vậy ngay khi có thể, chẳng hạn như khi hiển thị các đường liên kết liên quan đến pháp lý.
Kotlin
override fun shouldOverrideUrlLoading(webView: WebView, webResourceRequest: WebResourceRequest): Boolean { val originalUri: Uri = Uri.parse(webView.originalUrl) // Check for allowed URLs if (originalUri.equals(Uri.parse(BLANK_URL)) || originalUri.equals(webResourceRequest.url)) { return false } if (webResourceRequest.isRedirect) { logger.w("Redirect detected, not following") return true } setupWizardWebViewClientListener.onUriBlocked(webResourceRequest.url) logger.w( String.format( "Navigation prevented to %s original is %s", webResourceRequest.url, originalUri)) return true }
Java
@Override public boolean shouldOverrideUrlLoading(WebView webView, WebResourceRequest webResourceRequest) { Uri originalUri = Uri.parse(webView.getOriginalUrl()); // Check for allowed URLs if (originalUri.equals(Uri.parse(BLANK_URL)) || originalUri.equals(webResourceRequest.getUrl())) { return false; } if (webResourceRequest.isRedirect()) { logger.w("Redirect detected, not following"); return true; } setupWizardWebViewClientListener.onUriBlocked(webResourceRequest.getUrl()); logger.w( String.format( "Navigation prevented to %s original is %s", webResourceRequest.getUrl(), originalUri)); return true; }
Tên gói
Do bạn phân phối một Gói ứng dụng Android (APK) riêng cho Android Automotive OS, nên bạn có thể sử dụng lại tên gói của ứng dụng di động hoặc tạo một tên gói mới. Nếu bạn sử dụng một tên gói khác, ứng dụng sẽ có hai trang thông tin riêng biệt trên Cửa hàng Play. Nếu bạn sử dụng lại tên gói hiện tại, ứng dụng của bạn sẽ có một trang thông tin duy nhất trên cả hai nền tảng.
Đây chủ yếu là một quyết định kinh doanh. Ví dụ: nếu bạn có một đội ngũ phát triển ứng dụng di động và một đội ngũ khác phát triển ứng dụng trên Android Automotive OS thì bạn nên có các tên gói riêng biệt để mỗi đội ngũ quản lý trang thông tin của riêng họ trên Cửa hàng Play. Không có sự khác biệt lớn về mặt yêu cầu kỹ thuật để xem nên áp dụng phương pháp nào.
Bảng sau đây tóm tắt một số điểm khác biệt chính giữa việc giữ nguyên tên gói đang dùng và sử dụng một tên gói mới.
| Tính năng | Cùng một tên gói | Tên gói mới |
|---|---|---|
| Trang thông tin trên Cửa hàng Play | Một trang | Nhiều trang |
| Cài đặt phản chiếu | Có: "cài đặt lại ứng dụng nhanh" trong trình hướng dẫn thiết lập | Không |
| Quá trình xem xét trên Cửa hàng Play | Chặn xem xét: nếu quá trình xem xét một tệp APK không thành công, các tệp APK khác được gửi trong cùng một bản phát hành cũng sẽ bị chặn | Xem xét riêng lẻ |
| Số liệu thống kê, chỉ số và chỉ số quan trọng | Kết hợp: bạn có thể lọc dữ liệu dành riêng cho ô tô. | Riêng biệt |
| Lập chỉ mục và thứ hạng trong kết quả tìm kiếm | Xây dựng thứ hạng hiện tại | Không thể chuyển sang |
| Tích hợp với các ứng dụng khác | Nhiều khả năng không cần thay đổi gì cả, hệ thống sẽ giả định rằng mã nội dung đa phương tiện được chia sẻ giữa hai tệp APK | Có thể phải cập nhật ứng dụng tương ứng, ví dụ: đối với việc phát URI bằng Trợ lý Google |
Câu hỏi thường gặp
Hãy xem các mục sau đây để biết câu trả lời cho một số câu hỏi thường gặp về Android Automotive OS.
Phần cứng
Ứng dụng của tôi có sử dụng được micrô không
Đối với ứng dụng nhắm đến Android 10 (cấp độ API 29) trở lên, hãy tham khảo tài liệu về cách chia sẻ âm thanh đầu vào. Không thể thực hiện việc này đối với API cấp độ dưới 29.
Chúng tôi có thể truy cập vào API nào cho ô tô và bằng cách nào?
Bạn chỉ có thể sử dụng các API mà OEM cho phép. Các quy trình đang được phát triển để chuẩn hoá cách bạn truy cập vào những API này.
Các ứng dụng có thể truy cập vào API của ô tô bằng cách sử dụng SetProperty() và GetProperty() trong CarPropertyManager.
Tham khảo mã nguồn hoặc tài liệu tham khảo để xem danh sách tất cả thuộc tính hiện có. Nếu thuộc tính được chú thích bằng @SystemApi, bạn chỉ có thể sử dụng thuộc tính này trong các ứng dụng hệ thống tải trước.
Những loại bộ mã hoá và giải mã âm thanh nào được hỗ trợ?
Tham khảo chi tiết về bộ mã hoá và giải mã âm thanh trong CDD (Tài liệu định nghĩa về khả năng tương thích) của Android.
DRM của Widevine có được hỗ trợ không?
Có. DRM của Widevine được hỗ trợ.
Phát triển và kiểm thử
Có hạn chế hoặc nội dung đề xuất nào đối với việc sử dụng SDK và thư viện của bên thứ ba không?
Chúng tôi không có nguyên tắc cụ thể nào về việc sử dụng SDK và thư viện của bên thứ ba. Nếu sử dụng SDK và thư viện của bên thứ ba thì bạn vẫn có trách nhiệm tuân thủ mọi yêu cầu về chất lượng đối với ứng dụng ô tô.
Tôi có thể sử dụng dịch vụ trên nền trước không?
Đối với dịch vụ trên nền trước, trường hợp sử dụng được cho phép duy nhất là tải nội dung sử dụng xuống trong chế độ ngoại tuyến. Nếu bạn có một trường hợp sử dụng khác cho dịch vụ trên nền trước mà bạn muốn được hỗ trợ, hãy liên hệ với chúng tôi qua nhóm thảo luận về Android Automotive OS.
Phát hành ứng dụng trên Android Automotive OS
Làm thế nào để phát hành ứng dụng trên Android Automotive OS bằng Google Play Console?
Để biết thông tin chi tiết về cách phát hành ứng dụng Android Automotive OS bằng Google Play Console, hãy xem bài viết Phân phối cho ô tô.
Tài nguyên khác
Để tìm hiểu thêm về Android Automotive OS, hãy xem các tài nguyên khác sau đây.
Mẫu
Hướng dẫn
- Thiết kế để dùng khi lái xe
- Sử dụng ứng dụng kiểm thử trình điều khiển nội dung đa phương tiện
- Thông báo trên Android Automotive OS
- Chất lượng ứng dụng Android dành cho xe ô tô
Blog
- Bản cập nhật Android Automotive OS dành cho nhà phát triển
- Phát triển ứng dụng cho Android Automotive OS
Video
- Cách xây dựng ứng dụng đa phương tiện cho ô tô (Android Dev Summit '19)
- Cách xây dựng ứng dụng Android cho ô tô (Google I/O'19)
Báo cáo sự cố về nội dung nghe nhìn trên Android Automotive OS
Nếu gặp sự cố trong khi phát triển ứng dụng đa phương tiện cho Android Automotive OS, bạn có thể báo cáo lỗi đó bằng Trình theo dõi sự cố của Google. Hãy nhớ điền tất cả thông tin được yêu cầu vào mẫu báo cáo lỗi.
Trước khi báo lỗi mới, hãy kiểm tra xem lỗi đó đã được báo cáo trong danh sách lỗi hay chưa. Bạn có thể đăng ký theo dõi và bình chọn cho các lỗi bằng cách nhấp vào dấu sao cho một lỗi trong công cụ theo dõi. Để biết thêm thông tin, hãy xem bài viết Đăng ký theo dõi lỗi.