Android Auto और Android Automotive OS (AAOS), आपके ऐप्लिकेशन की मीडिया ब्राउज़र सेवा को कॉल करते हैं. इससे उन्हें यह पता चलता है कि कौन-कौनसा कॉन्टेंट उपलब्ध है. इसके लिए, आपको मीडिया ब्राउज़र सेवा में इन दो तरीकों को लागू करना होगा.
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, nu
ll)
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)
;
}
इस तरीके का उदाहरण देखने के लिए, GitHub पर Universal Android Music Player के सैंपल ऐप्लिकेशन में onGetRoot
देखें.
पैकेज की पुष्टि करने की सुविधा जोड़ना
जब आपकी सेवा के onGetRoot
तरीके को कॉल किया जाता है, तो कॉल करने वाला पैकेज आपकी सेवा को पहचान करने वाली जानकारी भेजता है. आपकी सेवा इस जानकारी का इस्तेमाल करके यह तय कर सकती है कि उस पैकेज को आपका कॉन्टेंट ऐक्सेस करने की अनुमति दी जा सकती है या नहीं.
उदाहरण के लिए, अपने ऐप्लिकेशन के कॉन्टेंट का ऐक्सेस, मंज़ूरी पा चुके पैकेज की सूची तक सीमित किया जा सकता है:
- अनुमति वाले चैनलों की सूची में शामिल चैनलों से
clientPackageName
की तुलना करें. - पैकेज के APK पर हस्ताक्षर करने के लिए इस्तेमाल किए गए सर्टिफ़िकेट की पुष्टि करें.
अगर पैकेज की पुष्टि नहीं हो पाती है, तो null
पर वापस जाएं और अपने कॉन्टेंट का ऐक्सेस देने से मना करें.
Android Auto और AAOS जैसे सिस्टम ऐप्लिकेशन को आपके कॉन्टेंट का ऐक्सेस देने के लिए, आपकी सेवा को 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
}
यह कोड स्निपेट, GitHub पर मौजूद Universal Android Music Player के सैंपल ऐप्लिकेशन में PackageValidator
क्लास का एक हिस्सा है. अपनी सेवा के 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)
;
}
इस तरीके का उदाहरण देखने के लिए, GitHub पर Universal Android Music Player के सैंपल ऐप्लिकेशन में onLoadChildren
देखें.
रूट मेन्यू को स्ट्रक्चर करना
Android Auto और Android Automotive OS में, रूट मेन्यू के स्ट्रक्चर के बारे में कुछ खास पाबंदियां हैं. इनकी जानकारी MediaBrowserService
को रूट हिंट के ज़रिए दी जाती है. इन्हें onGetRoot()
में पास किए गए बंडल आर्ग्युमेंट के ज़रिए पढ़ा जा सकता है. इन निर्देशों का पालन करने पर, सिस्टम रूट कॉन्टेंट को नेविगेशन टैब के तौर पर दिखा सकता है. इन सुझावों का पालन न करने पर, सिस्टम कुछ रूट कॉन्टेंट को हटा सकता है या उसे कम खोजा जा सकने वाला बना सकता है.
पहली इमेज. रूट कॉन्टेंट, नेविगेशन टैब के तौर पर दिखता है.
इन संकेतों को लागू करने पर, सिस्टम रूट कॉन्टेंट को नेविगेशन टैब के तौर पर दिखाता है. इन संकेतों को लागू न करने पर, हो सकता है कि कुछ मुख्य कॉन्टेंट को हटा दिया जाए या उसे कम खोजा जा सके. ये सुराग इस तरह से भेजे जाते हैं:
रूट चाइल्ड की संख्या की सीमा: ज़्यादातर मामलों में, यह संख्या चार होती है. इसका मतलब है कि सिर्फ़ चार (या इससे कम) टैब दिखाए जा सकते हैं.
रूट चाइल्ड पर काम करने वाले फ़्लैग: इस वैल्यू के
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...
}
इन संकेतों की वैल्यू के आधार पर, कॉन्टेंट के क्रम के लिए लॉजिक को ब्रांच किया जा सकता है. खास तौर पर, अगर आपका क्रम Android Auto और AAOS के बाहर MediaBrowser
इंटिग्रेशन के हिसाब से अलग-अलग होता है.
उदाहरण के लिए, अगर आपको आम तौर पर रूट लेवल पर मौजूद कोई चलाने लायक आइटम दिखाना होता है, तो हो सकता है कि आपको उसे रूट लेवल पर मौजूद ब्राउज़ करने लायक आइटम के नीचे नेस्ट करना पड़े. ऐसा इसलिए, क्योंकि 'सुविधाओं के बारे में जानकारी देने वाले फ़्लैग' एट्रिब्यूट की वैल्यू के हिसाब से, ऐसा करना ज़रूरी हो सकता है.
रूट हिंट के अलावा, टैब को बेहतर तरीके से रेंडर करने के लिए इन दिशा-निर्देशों का पालन करें:
हर टैब आइटम के लिए मोनोक्रोम (सफ़ेद रंग के) आइकॉन
हर टैब आइटम के लिए छोटे और काम के लेबल (छोटे लेबल से, लेबल के कटने की संभावना कम हो जाती है)