Android Auto และ Android Automotive OS (AAOS) จะเรียกใช้บริการ Media Browser ของแอปเพื่อค้นหาเนื้อหาที่พร้อมใช้งาน คุณต้องใช้ 2 เมธอดนี้ในบริการ Media Browser เพื่อรองรับการทำงานดังกล่าว
ใช้ 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 เพื่อปฏิเสธการเข้าถึงเนื้อหา
บริการต้องแสดงผล BrowserRoot ที่ไม่ใช่ค่า Null เมื่อแอปของระบบ เช่น Android Auto และ AAOS เรียกใช้เมธอด 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 ใช้ชื่อแพ็กเกจที่แตกต่างกัน
สำหรับแอปบนอุปกรณ์เคลื่อนที่และแอป 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 แท็บ (หรือน้อยกว่า)
แฟล็กที่รองรับในโหนดลูกของรูท: คาดว่าค่านี้จะเป็น
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
ตัวอย่างเช่น หากปกติคุณแสดงรายการที่เล่นได้ของรูท คุณอาจต้องการฝังรายการดังกล่าวไว้ใต้รายการที่เรียกดูได้ของรูทแทนเนื่องจากค่าของคำแนะนำแฟล็กที่รองรับ
นอกเหนือจากคำแนะนำรากแล้ว ให้ใช้หลักเกณฑ์ต่อไปนี้เพื่อแสดงแท็บอย่างเหมาะสม
ไอคอนสีเดียว (ควรเป็นสีขาว) สำหรับแต่ละรายการแท็บ
ป้ายกำกับสั้นๆ ที่สื่อความหมายสำหรับแต่ละรายการแท็บ (ป้ายกำกับสั้นๆ จะช่วยลดโอกาสที่ป้ายกำกับจะถูกตัดทอน)