Android Auto และ Android Automotive OS (AAOS) จะเรียกใช้บริการเบราว์เซอร์สื่อของแอปเพื่อค้นหาเนื้อหาที่พร้อมใช้งาน หากต้องการรองรับฟีเจอร์นี้ คุณต้องใช้ เมธอดทั้ง 2 นี้ในบริการเบราว์เซอร์สื่อ
ใช้งาน onGetRoot
เมธอด onGetRoot
ของบริการจะแสดงข้อมูลเกี่ยวกับโหนดรูท
ของลำดับชั้นเนื้อหา Android Auto และ AAOS ใช้รูท
โหนดนี้เพื่อขอเนื้อหาที่เหลือโดยใช้วิธีonLoadChildren
ข้อมูลโค้ดนี้แสดงการใช้งานเมธอด onGetRoot
Kotlin
override fun onGetRoot(
clientPackageName: String,
clientUid: Int,
rootHints: Bundle?
): BrowserRoot? =
// Verify that the specified package is allowed to access your
// content. You'll need to write your own logic to do this.
if (!isValid(clientPackageName, clientUid)) {
// If the request comes from an untrusted package, return null.
// No further calls will be made to other media browsing methods.
null
} else MediaBrowserServiceCompat.BrowserRoot(MY_MEDIA_ROOT_ID, null)
Java
@Override
public BrowserRoot onGetRoot(String clientPackageName, int clientUid,
Bundle rootHints) {
// Verify that the specified package is allowed to access your
// content. You'll need to write your own logic to do this.
if (!isValid(clientPackageName, clientUid)) {
// If the request comes from an untrusted package, return null.
// No further calls will be made to other media browsing methods.
return null;
}
return new MediaBrowserServiceCompat.BrowserRoot(MY_MEDIA_ROOT_ID, null);
}
ดูตัวอย่างโดยละเอียดของวิธีการนี้ได้ที่ onGetRoot
ในแอปตัวอย่าง Universal
Android Music Player บน GitHub
เพิ่มการตรวจสอบแพ็กเกจ
เมื่อมีการโทรไปยังเมธอด onGetRoot
ของบริการ แพ็กเกจที่เรียกจะส่งข้อมูลระบุตัวตนไปยังบริการของคุณ บริการของคุณสามารถใช้
ข้อมูลนี้เพื่อพิจารณาว่าแพ็กเกจดังกล่าวเข้าถึงเนื้อหาของคุณได้หรือไม่
เช่น คุณสามารถจำกัดการเข้าถึงเนื้อหาของแอปให้เฉพาะแพ็กเกจที่ได้รับอนุมัติ ในรายการได้
- เปรียบเทียบ
clientPackageName
กับรายการที่อนุญาต - ยืนยันใบรับรองที่ใช้ลงนาม APK สำหรับแพ็กเกจ
หากยืนยันแพ็กเกจไม่ได้ ให้กลับไปที่ null
เพื่อปฏิเสธการเข้าถึงเนื้อหา
หากต้องการให้แอประบบ เช่น Android Auto และ AAOS
เข้าถึงเนื้อหาของคุณได้ บริการของคุณต้องแสดงผลค่าที่ไม่ใช่ Null
BrowserRoot
เมื่อแอประบบเหล่านี้เรียกใช้เมธอด onGetRoot
ลายเซ็นของแอปของระบบ AAOS จะแตกต่างกันไปตาม ยี่ห้อและรุ่นของรถยนต์ โปรดตรวจสอบว่าได้อนุญาตการเชื่อมต่อจากแอประบบทั้งหมดเพื่อรองรับ AAOS
ข้อมูลโค้ดนี้แสดงวิธีที่บริการของคุณสามารถตรวจสอบได้ว่าแพ็กเกจที่เรียกใช้ เป็นแอประบบ
fun isKnownCaller(
callingPackage: String,
callingUid: Int
): Boolean {
...
val isCallerKnown = when {
// If the system is making the call, allow it.
callingUid == Process.SYSTEM_UID -> true
// If the app was signed by the same certificate as the platform
// itself, also allow it.
callerSignature == platformSignature -> true
// ... more cases
}
return isCallerKnown
}
ข้อมูลโค้ดนี้เป็นข้อความที่ตัดตอนมาจากคลาส PackageValidator
ใน
แอปตัวอย่าง Universal Android Music Player บน GitHub ดูตัวอย่างที่ละเอียดยิ่งขึ้นเกี่ยวกับวิธีติดตั้งใช้งานการตรวจสอบแพ็กเกจสำหรับบริการของonGetRoot
ในชั้นเรียนดังกล่าว
นอกเหนือจากการอนุญาตแอปของระบบแล้ว คุณต้องอนุญาตให้ Google Assistant เชื่อมต่อกับMediaBrowserService
ด้วย Google Assistant ใช้ชื่อแพ็กเกจแยกกัน
สำหรับโทรศัพท์ ซึ่งรวมถึง Android Auto และ Android AAOS
ใช้ onLoadChildren
หลังจากได้รับออบเจ็กต์โหนดรูทแล้ว Android Auto และ AAOS
จะสร้างเมนูระดับบนสุดโดยเรียกใช้ onLoadChildren
ในออบเจ็กต์โหนดรูท
เพื่อรับออบเจ็กต์ลูกหลาน แอปไคลเอ็นต์สร้างเมนูย่อยโดยเรียกใช้เมธอดเดียวกันนี้
โดยใช้ออบเจ็กต์โหนดลูกหลาน
แต่ละโหนดในลำดับชั้นเนื้อหาจะแสดงด้วยออบเจ็กต์
MediaBrowserCompat.MediaItem
โดยรายการสื่อแต่ละรายการจะมีสตริงรหัสที่ไม่ซ้ำกัน
เป็นตัวระบุ แอปไคลเอ็นต์จะถือว่าสตริงรหัสเหล่านี้เป็นโทเค็นที่ไม่โปร่งใส
เมื่อแอปไคลเอ็นต์ต้องการเรียกดูเมนูย่อยหรือเล่นรายการสื่อ แอปจะส่งโทเค็น แอปของคุณมีหน้าที่เชื่อมโยงโทเค็นกับ รายการสื่อที่เหมาะสม
ข้อมูลโค้ดนี้แสดงการใช้งาน onLoadChildren
Kotlin
override fun onLoadChildren(
parentMediaId: String,
result: Result<List<MediaBrowserCompat.MediaItem>>
) {
// Assume for example that the music catalog is already loaded/cached.
val mediaItems: MutableList<MediaBrowserCompat.MediaItem> = mutableListOf()
// Check if this is the root menu:
if (MY_MEDIA_ROOT_ID == parentMediaId) {
// Build the MediaItem objects for the top level
// and put them in the mediaItems list.
} else {
// Examine the passed parentMediaId to see which submenu we're at
// and put the descendants of that menu in the mediaItems list.
}
result.sendResult(mediaItems)
}
Java
@Override
public void onLoadChildren(final String parentMediaId,
final Result<List<MediaBrowserCompat.MediaItem>> result) {
// Assume for example that the music catalog is already loaded/cached.
List<MediaBrowserCompat.MediaItem> mediaItems = new ArrayList<>();
// Check if this is the root menu:
if (MY_MEDIA_ROOT_ID.equals(parentMediaId)) {
// Build the MediaItem objects for the top level
// and put them in the mediaItems list.
} else {
// Examine the passed parentMediaId to see which submenu we're at
// and put the descendants of that menu in the mediaItems list.
}
result.sendResult(mediaItems);
}
หากต้องการดูตัวอย่างของเมธอดนี้ โปรดดู onLoadChildren
ใน
แอปตัวอย่าง Universal Android Music Player บน GitHub
สร้างโครงสร้างเมนูหลัก
Android Auto และ Android Automotive OS มีข้อจำกัดเฉพาะเกี่ยวกับ
โครงสร้างของเมนูรูท โดยจะสื่อสารกับ MediaBrowserService
ผ่านคำแนะนำรูท ซึ่งอ่านได้ผ่านอาร์กิวเมนต์ Bundle ที่ส่งไปยัง
onGetRoot()
เมื่อทำตามคำแนะนำเหล่านี้ ระบบจะแสดงเนื้อหาระดับบนสุดเป็นแท็บนำทาง หากไม่ปฏิบัติตามคำแนะนำเหล่านี้ ระบบอาจทิ้งเนื้อหาระดับบนสุดบางรายการหรือทำให้ค้นพบได้ยากขึ้น
รูปที่ 1 เนื้อหาระดับบนสุดจะแสดงเป็นแท็บการนำทาง
เมื่อใช้คำแนะนำเหล่านี้ ระบบจะแสดงเนื้อหาระดับบนสุดเป็นแท็บการนำทาง หากไม่ใช้คำแนะนำเหล่านี้ ระบบอาจทิ้งเนื้อหาระดับรูทบางรายการหรือทำให้ค้นพบได้ยากขึ้น ระบบจะส่งคำใบ้เหล่านี้
ขีดจำกัดจำนวนองค์ประกอบย่อยระดับรูท: โดยส่วนใหญ่แล้ว จำนวนนี้จะเป็น 4 ซึ่งหมายความว่าจะแสดงได้เพียง 4 แท็บ (หรือน้อยกว่า)
Flags ที่รองรับในองค์ประกอบย่อยระดับรูท: คาดว่าค่านี้จะเป็น
MediaItem#FLAG_BROWSABLE
ซึ่งหมายความว่าเฉพาะรายการที่เรียกดูได้ (ไม่ใช่รายการที่เล่นได้) เท่านั้นที่จะแสดงเป็นแท็บได้ขีดจำกัดจำนวนการดำเนินการเรียกดูที่กำหนดเอง: ตรวจสอบว่าระบบรองรับการดำเนินการเรียกดูที่กำหนดเองกี่รายการ
Kotlin
import androidx.media.utils.MediaConstants
override fun onGetRoot(
clientPackageName: String,
clientUid: Int,
rootHints: Bundle
): BrowserRoot {
val maximumRootChildLimit = rootHints.getInt(
MediaConstants.BROWSER_ROOT_HINTS_KEY_ROOT_CHILDREN_LIMIT,
/* defaultValue= */ 4)
val supportedRootChildFlags = rootHints.getInt(
MediaConstants.BROWSER_ROOT_HINTS_KEY_ROOT_CHILDREN_SUPPORTED_FLAGS,
/* defaultValue= */ MediaItem.FLAG_BROWSABLE)
// Rest of method...
}
Java
import androidx.media.utils.MediaConstants;
// Later, in your MediaBrowserServiceCompat.
@Override
public BrowserRoot onGetRoot(
String clientPackageName, int clientUid, Bundle rootHints) {
int maximumRootChildLimit = rootHints.getInt(
MediaConstants.BROWSER_ROOT_HINTS_KEY_ROOT_CHILDREN_LIMIT,
/* defaultValue= */ 4);
int supportedRootChildFlags = rootHints.getInt(
MediaConstants.BROWSER_ROOT_HINTS_KEY_ROOT_CHILDREN_SUPPORTED_FLAGS,
/* defaultValue= */ MediaItem.FLAG_BROWSABLE);
// Rest of method...
}
คุณเลือกที่จะแยกตรรกะสำหรับโครงสร้างของลำดับชั้นเนื้อหาได้
โดยอิงตามค่าของคำแนะนำเหล่านี้ โดยเฉพาะอย่างยิ่งหากลำดับชั้นแตกต่างกันในMediaBrowser
การผสานรวมภายนอก Android Auto และ AAOS
เช่น หากปกติคุณแสดงไอเทมที่เล่นได้ระดับรูท คุณอาจต้องการซ้อนไอเทมดังกล่าว ไว้ใต้ไอเทมที่เรียกดูได้ระดับรูทแทน เนื่องจากค่าของแฟล็กที่รองรับ คำแนะนำ
นอกเหนือจากคำแนะนำรูทแล้ว ให้ใช้หลักเกณฑ์ต่อไปนี้เพื่อแสดงแท็บอย่างเหมาะสม
ไอคอนขาวดำ (สีขาวจะดีที่สุด) สำหรับรายการในแต่ละแท็บ
ป้ายกำกับที่สั้นและมีความหมายสำหรับรายการในแต่ละแท็บ (ป้ายกำกับสั้นๆ จะช่วยลดโอกาสที่ระบบจะตัดป้ายกำกับ)