يسمح لك "مساعد Google" باستخدام الطلبات الصوتية للتحكّم في العديد من الأجهزة، مثل Google Home وهاتفك وغير ذلك الكثير. ويشتمل هذا البرنامج على إمكانية مضمّنة لفهم أوامر الوسائط ("تشغيل أغنية لـ Beyoncé") كما يتوافق مع عناصر التحكّم في الوسائط (مثل الإيقاف المؤقت والتخطي والتقديم السريع وإبداء الإعجاب).
يتواصل "مساعد Google" مع تطبيقات الوسائط على Android باستخدام جلسة وسائط. ويمكنها استخدام النية أو الخدمات لإطلاق التطبيق وبدء التشغيل. للحصول على أفضل النتائج، يجب أن ينفِّذ تطبيقك جميع الميزات الموضحة في هذه الصفحة.
.استخدام جلسة وسائط
يجب أن ينفّذ كل تطبيق صوتي أو فيديو جلسة وسائط لكي يتمكّن "مساعد Google" من تشغيل عناصر التحكّم في النقل عند بدء التشغيل.
يُرجى العِلم أنّ "مساعد Google" لا يستخدم سوى الإجراءات المدرَجة في هذا القسم، إلا أنّ أفضل الممارسات هي تنفيذ جميع واجهات برمجة تطبيقات الإعداد والتشغيل لضمان التوافق مع التطبيقات الأخرى. بالنسبة إلى أي إجراءات غير متاحة، يمكن أن تعرض عمليات استدعاء جلسة الوسائط ببساطة خطأ باستخدام ERROR_CODE_NOT_SUPPORTED
.
يمكنك تفعيل عناصر التحكّم في الوسائط والنقل من خلال ضبط هذه العلامات في عنصر
MediaSession
في تطبيقك:
Kotlin
session.setFlags( MediaSessionCompat.FLAG_HANDLES_MEDIA_BUTTONS or MediaSessionCompat.FLAG_HANDLES_TRANSPORT_CONTROLS )
Java
session.setFlags(MediaSessionCompat.FLAG_HANDLES_MEDIA_BUTTONS | MediaSessionCompat.FLAG_HANDLES_TRANSPORT_CONTROLS);
يجب أن تعرض جلسة الوسائط في تطبيقك الإجراءات المتوافقة مع التطبيق، وأن تنفّذ عمليات استدعاء جلسة تشغيل الوسائط المقابلة. يُرجى تعريف الإجراءات المتاحة في
setActions()
.
ويشكّل مشروع Universal Android Music Player مثالاً جيدًا على كيفية إعداد جلسة وسائط.
إجراءات التشغيل
لبدء التشغيل من خدمة، يجب أن تتضمّن جلسة الوسائط إجراءات PLAY
هذه واستدعاءاتها:
الإجراء | هاتف معاودة الاتصال |
---|---|
ACTION_PLAY |
onPlay() |
ACTION_PLAY_FROM_SEARCH |
onPlayFromSearch() |
ACTION_PLAY_FROM_URI (*) |
onPlayFromUri() |
يجب أن تنفّذ جلستك أيضًا إجراءات PREPARE
هذه وعمليات معاودة الاتصال المرتبطة بها:
الإجراء | هاتف معاودة الاتصال |
---|---|
ACTION_PREPARE |
onPrepare() |
ACTION_PREPARE_FROM_SEARCH |
onPrepareFromSearch() |
ACTION_PREPARE_FROM_URI (*) |
onPrepareFromUri() |
من خلال تنفيذ واجهات برمجة تطبيقات الإعداد، يمكن تقليل وقت استجابة التشغيل الذي يأتي بعد توجيه طلب صوتي. ويمكن لتطبيقات الوسائط التي تريد تحسين وقت استجابة التشغيل استخدام الوقت الإضافي لبدء التخزين المؤقت للمحتوى وإعداد تشغيل الوسائط.
تحليل طلبات البحث
عندما يبحث المستخدم عن عنصر وسائط محدّد، مثل "تشغيل موسيقى الجاز على
[اسم تطبيقك]" أو "الاستماع إلى [عنوان الأغنية]"، تتلقّى طريقة معاودة الاتصال
onPrepareFromSearch()
أو
onPlayFromSearch()
مَعلمة طلب بحث وحزمة ميزات إضافية.
يجب أن يحلل التطبيق طلب البحث الصوتي ويبدأ التشغيل من خلال اتباع الخطوات التالية:
- استخدم حزمة الإضافات وسلسلة طلب البحث المعروضة من البحث الصوتي لتصفية النتائج.
- أنشئ قائمة انتظار التشغيل بناءً على هذه النتائج.
- شغِّل عنصر الوسائط الأكثر صلة من النتائج.
تأخذ الطريقة onPlayFromSearch()
مَعلمة إضافية تتضمّن معلومات أكثر تفصيلاً من البحث الصوتي. تساعدك هذه الميزات الإضافية في العثور على محتوى الصوت في تطبيقك لتشغيله.
إذا لم تتمكن من تقديم هذه البيانات في نتائج البحث، يمكنك استخدام المنطق لتحليل استعلام البحث الأولي وتشغيل المسارات المناسبة بناءً على طلب البحث.
تتوفر الميزات الإضافية التالية في نظامَي التشغيل Android Automotive وAndroid Auto:
يعرض مقتطف الرمز التالي كيفية إلغاء طريقة onPlayFromSearch()
في تنفيذ MediaSession.Callback
لتحليل طلب البحث الصوتي وبدء التشغيل:
Kotlin
override fun onPlayFromSearch(query: String?, extras: Bundle?) { if (query.isNullOrEmpty()) { // The user provided generic string e.g. 'Play music' // Build appropriate playlist queue } else { // Build a queue based on songs that match "query" or "extras" param val mediaFocus: String? = extras?.getString(MediaStore.EXTRA_MEDIA_FOCUS) if (mediaFocus == MediaStore.Audio.Artists.ENTRY_CONTENT_TYPE) { isArtistFocus = true artist = extras.getString(MediaStore.EXTRA_MEDIA_ARTIST) } else if (mediaFocus == MediaStore.Audio.Albums.ENTRY_CONTENT_TYPE) { isAlbumFocus = true album = extras.getString(MediaStore.EXTRA_MEDIA_ALBUM) } // Implement additional "extras" param filtering } // Implement your logic to retrieve the queue var result: String? = when { isArtistFocus -> artist?.also { searchMusicByArtist(it) } isAlbumFocus -> album?.also { searchMusicByAlbum(it) } else -> null } result = result ?: run { // No focus found, search by query for song title query?.also { searchMusicBySongTitle(it) } } if (result?.isNotEmpty() == true) { // Immediately start playing from the beginning of the search results // Implement your logic to start playing music playMusic(result) } else { // Handle no queue found. Stop playing if the app // is currently playing a song } }
Java
@Override public void onPlayFromSearch(String query, Bundle extras) { if (TextUtils.isEmpty(query)) { // The user provided generic string e.g. 'Play music' // Build appropriate playlist queue } else { // Build a queue based on songs that match "query" or "extras" param String mediaFocus = extras.getString(MediaStore.EXTRA_MEDIA_FOCUS); if (TextUtils.equals(mediaFocus, MediaStore.Audio.Artists.ENTRY_CONTENT_TYPE)) { isArtistFocus = true; artist = extras.getString(MediaStore.EXTRA_MEDIA_ARTIST); } else if (TextUtils.equals(mediaFocus, MediaStore.Audio.Albums.ENTRY_CONTENT_TYPE)) { isAlbumFocus = true; album = extras.getString(MediaStore.EXTRA_MEDIA_ALBUM); } // Implement additional "extras" param filtering } // Implement your logic to retrieve the queue if (isArtistFocus) { result = searchMusicByArtist(artist); } else if (isAlbumFocus) { result = searchMusicByAlbum(album); } if (result == null) { // No focus found, search by query for song title result = searchMusicBySongTitle(query); } if (result != null && !result.isEmpty()) { // Immediately start playing from the beginning of the search results // Implement your logic to start playing music playMusic(result); } else { // Handle no queue found. Stop playing if the app // is currently playing a song } }
للحصول على مثال أكثر تفصيلاً حول كيفية إجراء البحث الصوتي لتشغيل محتوى صوتي في تطبيقك، راجع النموذج Universal Android Music Player.
معالجة طلبات البحث الفارغة
إذا تم استدعاء onPrepare()
أو onPlay()
أو onPrepareFromSearch()
أو onPlayFromSearch()
بدون طلب بحث، من المفترض أن يشغِّل تطبيق الوسائط
الوسائط "الحالية". وإذا لم تكن هناك وسائط حالية، يجب أن يحاول التطبيق تشغيل شيء ما، مثل
أغنية من آخر قائمة تشغيل أو قائمة انتظار عشوائية. ويستخدم المساعد
واجهات برمجة التطبيقات هذه عندما يطلب المستخدم "تشغيل الموسيقى على [اسم تطبيقك]" بدون
معلومات إضافية.
عندما يقول المستخدم "تشغيل الموسيقى على [اسم تطبيقك]"، يحاول نظام التشغيل Android Automotive أو
Android Auto تشغيل تطبيقك وتشغيل الصوت من خلال استدعاء طريقة onPlayFromSearch()
في تطبيقك. وبما أنّ المستخدم لم يذكر اسم عنصر الوسائط، ستتلقّى الطريقة onPlayFromSearch()
مَعلمة طلب بحث فارغة. في هذه الحالات، من المفترض أن يستجيب التطبيق من خلال تشغيل الصوت على الفور، مثل أغنية من أحدث قائمة تشغيل أو قائمة انتظار عشوائية.
توضيح إتاحة الإجراءات الصوتية القديمة
في معظم الحالات، تمنح إجراءات التشغيل الموضحة أعلاه تطبيقك كل وظائف التشغيل التي يحتاج إليها. ومع ذلك، تتطلب بعض الأنظمة أن يحتوي تطبيقك على فلتر Intent للبحث. يجب أن تذكر دعمًا لفلتر Intent هذا في ملفات بيان تطبيقك.
يمكنك تضمين هذا الرمز في ملف البيان لتطبيق الهاتف:
<activity>
<intent-filter>
<action android:name=
"android.media.action.MEDIA_PLAY_FROM_SEARCH" />
<category android:name=
"android.intent.category.DEFAULT" />
</intent-filter>
</activity>
عناصر التحكّم في النقل
بعد تفعيل جلسة الوسائط في التطبيق، يمكن لخدمة "مساعد Google" إصدار طلبات صوتية للتحكّم في التشغيل وتعديل البيانات الوصفية للوسائط. ولكي ينجح ذلك، يجب أن تمكّن التعليمة البرمجية الإجراءات التالية وأن تنفذ عمليات استدعاء الاتصال المقابلة:
الإجراء | هاتف معاودة الاتصال | الوصف |
---|---|---|
ACTION_SKIP_TO_NEXT |
onSkipToNext() |
الفيديو التالي |
ACTION_SKIP_TO_PREVIOUS |
onSkipToPrevious() |
الأغنية السابقة |
ACTION_PAUSE, ACTION_PLAY_PAUSE |
onPause() |
إيقاف مؤقت |
ACTION_STOP |
onStop() |
إيقاف |
ACTION_PLAY |
onPlay() |
استئناف التشغيل |
ACTION_SEEK_TO |
onSeekTo() |
ترجيع بمقدار 30 ثانية |
ACTION_SET_RATING |
onSetRating(android.support.v4.media.RatingCompat) |
رائع/لا يعجبني. |
ACTION_SET_CAPTIONING_ENABLED |
onSetCaptioningEnabled(boolean) |
فعِّل ميزة الترجمة والشرح أو أوقِفها. |
ملاحظة:
- لكي تعمل أوامر التقديم، يجب تحديث
PlaybackState
معstate, position, playback speed, and update time
. يجب أن يتصل التطبيق بالرمزsetPlaybackState()
عندما تتغير الحالة. - ويجب أيضًا أن يعدّل تطبيق الوسائط البيانات الوصفية لجلسة الوسائط باستمرار. يدعم ذلك أسئلة مثل "ما الأغنية التي يتم تشغيلها؟" يجب أن يتصل التطبيق بـ
setMetadata()
عند تغيير الحقول المناسبة (مثل عنوان المقطع الصوتي والفنان والاسم). - يجب ضبط
MediaSession.setRatingType()
للإشارة إلى نوع التقييم المتوافق مع التطبيق، ويجب أن ينفِّذonSetRating()
. إذا كان التطبيق لا يتيح التقييم، يجب ضبط نوع التقييم علىRATING_NONE
.
ومن المرجح أن تختلف الإجراءات الصوتية التي تتيحها حسب نوع المحتوى.
نوع المحتوى | الإجراءات المطلوبة |
---|---|
تطبيق موسيقى |
ضرورة الدعم: التشغيل والإيقاف المؤقت والإيقاف والتخطّي إلى التالي والتخطّي إلى السابق أوصي بشدة بالحصول على الدعم بشأن: "تقديم" |
بودكاست |
ضرورة الدعم: التشغيل والإيقاف المؤقت والإيقاف والسعي إلى اقتراح الدعم لـ: التخطّي إلى التالي والتخطّي إلى السابق |
كتاب مسموع | ضرورة الدعم: التشغيل والإيقاف المؤقت والإيقاف والسعي إلى |
راديو | ضرورة الدعم: التشغيل والإيقاف المؤقت والإيقاف |
أخبار | ضرورة الدعم: التشغيل والإيقاف المؤقت والإيقاف والتخطّي إلى التالي والتخطّي إلى السابق |
الفيديو |
ضرورة الدعم: التشغيل، والإيقاف المؤقت، والإيقاف، والتقديم، والترجيع، والتقديم السريع ننصح بشدة بتوفير الدعم لـ: التخطّي إلى التالي والتخطّي إلى السابق |
عليك دعم أكبر عدد ممكن من الإجراءات المذكورة أعلاه على النحو الذي تسمح به عروض منتجاتك، مع الاستمرار في الاستجابة بشكل ملائم لأي إجراءات أخرى. على سبيل المثال، إذا كان بإمكان المستخدمين المشتركين في Premium فقط الرجوع إلى العنصر السابق، قد تعرض رسالة خطأ إذا طلب مستخدم المستوى المجاني من "مساعد Google" الرجوع إلى العنصر السابق. راجِع قسم التعامل مع الأخطاء للحصول على مزيد من الإرشادات.
نماذج طلبات صوتية يمكن تجربتها
يوضح الجدول التالي بعض نماذج طلبات البحث التي يجب استخدامها أثناء اختبار التنفيذ:
معاودة الاتصال في MediaSession | عبارة "Ok Google" التي يمكن استخدامها | |
---|---|---|
onPlay() |
"تشغيل" "استئناف التشغيل" |
|
onPlayFromSearch()
onPlayFromUri() |
الموسيقى |
"تشغيل موسيقى أو أغانٍ على (اسم التطبيق)". هذا طلب بحث فارغ. "تشغيل (أغنية | فنان | ألبوم | نوع | قائمة تشغيل) على (اسم التطبيق)" |
الراديو | "تشغيل (التردد | المحطة) على (اسم التطبيق)" | |
كتاب مسموع |
"قراءة كتابي المسموع عن (اسم التطبيق)" "يُرجى قراءة (كتاب مسموع) على (اسم التطبيق)". |
|
Podcasts | "أريد تشغيل (بودكاست) على (اسم التطبيق)". | |
onPause() |
"الإيقاف مؤقّتًا" | |
onStop() |
"إيقاف" | |
onSkipToNext() |
"التالي (الأغنية | الحلقة | المقطع الصوتي)". | |
onSkipToPrevious() |
"(الأغنية | الحلقة | المقطع الصوتي) السابقة". | |
onSeekTo() |
"إعادة التشغيل" "التخطّي إلى الأمام ## ثانية". "الرجوع بمقدار ## دقيقة" |
|
لا ينطبق (يجب تعديل معلومات
MediaMetadata
الخاصة بك) |
"ما الذي يتم تشغيله؟" |
الأخطاء
يعالج "مساعد Google" الأخطاء الواردة في جلسة وسائط عند حدوثها، ويُبلغ المستخدمين
بها. احرص على تعديل جلسة الوسائط لحالة النقل ورمز الخطأ في PlaybackState
بشكل صحيح، على النحو الموضّح في مقالة العمل مع جلسة وسائط. يتعرَّف "مساعد Google"
على جميع رموز الخطأ التي يعرضها
getErrorCode()
.
الحالات التي يُساء استخدامها عادةً
إليك بعض الأمثلة لحالات الخطأ التي يجب التأكد من معالجتها بشكل صحيح:
- يحتاج المستخدم إلى تسجيل الدخول
- اضبط رمز الخطأ
PlaybackState
علىERROR_CODE_AUTHENTICATION_EXPIRED
. - اضبط رسالة الخطأ
PlaybackState
. - وإذا لزم الأمر للتشغيل، اضبط حالة
PlaybackState
علىSTATE_ERROR
، وإلا احتفظ بباقيPlaybackState
كما هي.
- اضبط رمز الخطأ
- يطلب المستخدم إجراءً غير متاح
- اضبط رمز الخطأ
PlaybackState
بشكل مناسب. على سبيل المثال، يمكنك ضبطPlaybackState
علىERROR_CODE_NOT_SUPPORTED
إذا كان الإجراء غير متاح أو علىERROR_CODE_PREMIUM_ACCOUNT_REQUIRED
إذا كان الإجراء محميًا بتسجيل الدخول. - اضبط رسالة الخطأ
PlaybackState
. - احتفظ بباقي
PlaybackState
كما هي.
- اضبط رمز الخطأ
- يطلب المستخدم محتوى غير متاح في التطبيق
- اضبط رمز الخطأ
PlaybackState
بشكل مناسب. على سبيل المثال، استخدِمERROR_CODE_NOT_AVAILABLE_IN_REGION
. - اضبط رسالة الخطأ
PlaybackState
. - يمكنك ضبط حالة
PlaybackSate
علىSTATE_ERROR
لمقاطع التشغيل، وإلا احتفظ بباقيPlaybackState
كما هي.
- اضبط رمز الخطأ
- يطلب المستخدم محتوى في حال عدم توفّر مطابقة تامة. على سبيل المثال، يطلب مستخدم من الدرجة المجانية
محتوى متاح فقط لمستخدمي الدرجة المميزة.
- ننصحك بعدم عرض رسالة خطأ، بل يجب أن تعطي الأولوية للعثور على محتوى مشابه لتشغيله. سيتعامل "مساعد Google" مع سماع الردود الصوتية الأكثر صلة قبل بدء التشغيل.
التشغيل حسب النية بالشراء
بإمكان "مساعد Google" تشغيل تطبيق صوتي أو فيديو وبدء التشغيل من خلال إرسال هدف باستخدام رابط لصفحة في التطبيق.
يمكن أن يأتي الغرض والرابط لصفحة معيّنة في التطبيق من مصادر مختلفة:
- عندما يبدأ "مساعد Google" تطبيقًا متوافقًا مع الأجهزة الجوّالة، يمكنه استخدام "بحث Google" لاسترداد المحتوى المرمَّز الذي يوفّر إجراء ساعة مع رابط.
- عندما يبدأ "مساعد Google" تطبيق تلفزيون، يجب أن يتضمّن التطبيق مقدِّم خدمة البحث عن التلفزيون لعرض معرّفات الموارد المنتظمة (URI) لمحتوى الوسائط. يرسل "مساعد Google" طلبًا إلى
مقدّم المحتوى والذي من المفترض أن يعرض هدفًا يحتوي على معرّف موارد منتظم (URI) لرابط صفحة معيّنة وإجراء اختياري.
إذا عرض طلب البحث إجراءً في الغرض،
يُرسل "مساعد Google" هذا الإجراء مع معرّف الموارد المنتظم (URI) إلى تطبيقك.
إذا لم يحدّد مقدّم الخدمة
إجراءً، سيضيف المساعد
ACTION_VIEW
إلى Intent.
يضيف "مساعد Google" EXTRA_START_PLAYBACK
الإضافية ذات القيمة true
إلى الغرض الذي يرسله إلى تطبيقك. ومن المفترض أن يبدأ تطبيقك في التشغيل عندما يتلقّى طلبًا من خلال EXTRA_START_PLAYBACK
.
التعامل مع الأغراض أثناء النشاط
يمكن للمستخدمين أن يطلبوا من "مساعد Google" تشغيل محتوى ما أثناء تشغيل التطبيق لمحتوى من طلب سابق. وهذا يعني أنّ تطبيقك يمكن أن يتلقّى أغراضًا جديدة لبدء التشغيل عندما يكون نشاط التشغيل نشطًا بالفعل.
إنّ الأنشطة التي تدعم الأغراض ذات الروابط لصفحات في التطبيق يجب أن تتجاوز onNewIntent()
للتعامل مع الطلبات الجديدة.
عند بدء التشغيل، قد يضيف "مساعد Google" علامات
إضافية
إلى الغرض الذي يرسله إلى تطبيقك. وخاصةً، قد يضيف
FLAG_ACTIVITY_CLEAR_TOP
أو
FLAG_ACTIVITY_NEW_TASK
أو كليهما. على الرغم من أنّ رمزك البرمجي لا يحتاج إلى التعامل مع هذه العلامات،
يستجيب نظام Android لها.
قد يؤثر ذلك في سلوك تطبيقك عند وصول طلب تشغيل ثانٍ بعنوان URI جديد أثناء تشغيل URI السابق. وفي هذه الحالة، من المفيد اختبار طريقة استجابة التطبيق. يمكنك استخدام أداة سطر الأوامر adb
لمحاكاة الموقف (القيمة الثابتة 0x14000000
هي القيمة المنطقية على مستوى البت OR العلامتين):
adb shell 'am start -a android.intent.action.VIEW --ez android.intent.extra.START_PLAYBACK true -d "<first_uri>"' -f 0x14000000
adb shell 'am start -a android.intent.action.VIEW --ez android.intent.extra.START_PLAYBACK true -d "<second_uri>"' -f 0x14000000
التشغيل من خدمة
إذا كان تطبيقك يحتوي على
media browser service
تسمح بالاتصالات من "مساعد Google"،
يمكن لخدمة "مساعد Google" تشغيل التطبيق من خلال التواصل مع
media session
الخاص بالخدمة.
يجب ألا تشغّل خدمة متصفح الوسائط أي نشاط.
سيشغِّل "مساعد Google" نشاطك بالاستناد إلى علامة PendingIntent
التي تحدّدها
باستخدام setSessionActivity().
تأكَّد من ضبط MediaSession.Token عند إعداد خدمة متصفح الوسائط. تذكَّر ضبط إجراءات التشغيل المتوافقة في جميع الأوقات، بما في ذلك أثناء الإعداد. يتوقع "مساعد Google" أن يضبط تطبيق الوسائط إجراءات التشغيل قبل أن يرسل "مساعد Google" أمر التشغيل الأول.
للبدء من إحدى الخدمات، ينفّذ "مساعد Google" واجهات برمجة تطبيقات عميل متصفّح الوسائط. ويجري مكالمات TransportControls التي تؤدي إلى استدعاء إجراءات PLAY في جلسة وسائط تطبيقك.
يوضِّح المخطّط التالي ترتيب المكالمات التي أنشأها "مساعد Google" وعمليات معاودة الاتصال في جلسات تشغيل الوسائط المقابلة. (يتم إرسال استدعاءات الإعداد فقط إذا كان تطبيقك يتيحها). جميع المكالمات غير متزامنة. ولا ينتظر "مساعد Google" أي ردّ من تطبيقك.
عندما يصدر المستخدم طلبًا صوتيًا لتشغيله، يستجيب "مساعد Google" بإعلان قصير. فور اكتمال الإشعار، يُصدر "مساعد Google" إجراء PLAY. ولا ينتظر أي حالة تشغيل محددة.
إذا كان تطبيقك يتيح تنفيذ إجراءات "ACTION_PREPARE_*
"، يطلب "مساعد Google" الإجراء PREPARE
قبل بدء الإشعار.
الاتصال بـ MediaBrowserService
لاستخدام إحدى الخدمات لبدء تشغيل تطبيقك، يجب أن يتمكّن "مساعد Google" من الاتصال بخدمة MediaBrowserService الخاصة بالتطبيق
واسترداد رمز MediaSession.Token. يتم التعامل مع طلبات الاتصال من خلال طريقة
onGetRoot()
الخاصة بالخدمة. هناك طريقتان لمعالجة الطلبات:
- قبول جميع طلبات الربط
- قبول طلبات الاتصال من تطبيق "مساعد Google" فقط
قبول جميع طلبات الربط
يجب إرجاع متصفِّحRoot للسماح لخدمة "مساعد Google" بإرسال الأوامر إلى جلسة تشغيل الوسائط. تتمثل أسهل طريقة في السماح لجميع تطبيقات MediaBrowser بالاتصال بخدمة MediaBrowserService. يجب عرض جذر متصفح غير فارغ. إليك الرمز الساري من Universal Music Player:
Kotlin
override fun onGetRoot( clientPackageName: String, clientUid: Int, rootHints: Bundle? ): BrowserRoot? { // To ensure you are not allowing any arbitrary app to browse your app's contents, you // need to check the origin: if (!packageValidator.isCallerAllowed(this, clientPackageName, clientUid)) { // If the request comes from an untrusted package, return an empty browser root. // If you return null, then the media browser will not be able to connect and // no further calls will be made to other media browsing methods. Log.i(TAG, "OnGetRoot: Browsing NOT ALLOWED for unknown caller. Returning empty " + "browser root so all apps can use MediaController. $clientPackageName") return MediaBrowserServiceCompat.BrowserRoot(MEDIA_ID_EMPTY_ROOT, null) } // Return browser roots for browsing... }
Java
@Override public BrowserRoot onGetRoot(@NonNull String clientPackageName, int clientUid, Bundle rootHints) { // To ensure you are not allowing any arbitrary app to browse your app's contents, you // need to check the origin: if (!packageValidator.isCallerAllowed(this, clientPackageName, clientUid)) { // If the request comes from an untrusted package, return an empty browser root. // If you return null, then the media browser will not be able to connect and // no further calls will be made to other media browsing methods. LogHelper.i(TAG, "OnGetRoot: Browsing NOT ALLOWED for unknown caller. " + "Returning empty browser root so all apps can use MediaController." + clientPackageName); return new MediaBrowserServiceCompat.BrowserRoot(MEDIA_ID_EMPTY_ROOT, null); } // Return browser roots for browsing... }
قبول حزمة تطبيق "مساعد Google" وتوقيعها
يمكنك السماح بشكل واضح لـ "مساعد Google" بالاتصال بخدمة متصفح الوسائط من خلال البحث عن اسم الحزمة والتوقيع. سيتلقّى تطبيقك اسم الحزمة في طريقة onGetRoot في MediaBrowserService. يجب إرجاع متصفِّحRoot للسماح لخدمة "مساعد Google" بإرسال الأوامر إلى جلسة تشغيل الوسائط. يحتفظ نموذج Universal Music Player بقائمة بأسماء الحزم والتوقيعات المعروفة. في ما يلي أسماء الحِزم والتوقيعات التي يستخدمها "مساعد Google".
<signature name="Google" package="com.google.android.googlequicksearchbox">
<key release="false">19:75:b2:f1:71:77:bc:89:a5:df:f3:1f:9e:64:a6:ca:e2:81:a5:3d:c1:d1:d5:9b:1d:14:7f:e1:c8:2a:fa:00</key>
<key release="true">f0:fd:6c:5b:41:0f:25:cb:25:c3:b5:33:46:c8:97:2f:ae:30:f8:ee:74:11:df:91:04:80:ad:6b:2d:60:db:83</key>
</signature>
<signature name="Google Assistant on Android Automotive OS" package="com.google.android.carassistant">
<key release="false">17:E2:81:11:06:2F:97:A8:60:79:7A:83:70:5B:F8:2C:7C:C0:29:35:56:6D:46:22:BC:4E:CF:EE:1B:EB:F8:15</key>
<key release="true">74:B6:FB:F7:10:E8:D9:0D:44:D3:40:12:58:89:B4:23:06:A6:2C:43:79:D0:E5:A6:62:20:E3:A6:8A:BF:90:E2</key>
</signature>