כדי להשתמש ב-MediaRouter framework באפליקציה, צריך לקבל מופע
של האובייקט MediaRouter
ומצרפים
אובייקט MediaRouter.Callback
להאזנה לאירועי ניתוב.
תוכן שנשלח דרך מסלול מדיה עובר דרך המסלול
משויך ל-MediaRouteProvider
(חוץ מכמה מקרים מיוחדים,
כגון מכשיר פלט Bluetooth). איור 1 מספק תמונה ברמה גבוהה
המחלקות המשמשות לניתוב תוכן בין מכשירים.
![](https://developer.android.google.cn/static/images/mediarouter/mediarouter-framework.png?authuser=0000&hl=he)
איור 1. סקירה כללית של המחלקות העיקריות של נתבי מדיה באפליקציות.
הערה: אם רוצים שהאפליקציה תתמוך מכשירי Google Cast, יש להשתמש ב-Cast SDK ולבנות את האפליקציה כשולח Cast שלה. פועלים לפי ההוראות שמוצגות מסמכי תיעוד של הפעלת Cast במקום להשתמש ישירות במסגרת MediaRouter.
הלחצן של נתיב המדיה
באפליקציות ל-Android צריך להשתמש בלחצן של נתיב מדיה כדי לשלוט בניתוב מדיה. מסגרת MediaRouter מספק ממשק סטנדרטי ללחצן, שעוזר למשתמשים לזהות ניתוב ולהשתמש בו כשזה זמין. הלחצן של נתיב המדיה ממוקם בדרך כלל בצד ימין של סרגל הפעולות של האפליקציה, כפי שמוצג באיור 2.
![](https://developer.android.google.cn/static/images/mediarouter/mediarouter-actionbar.png?authuser=0000&hl=he)
איור 2. לחצן נתיב המדיה ב סרגל הפעולות.
כשהמשתמש לוחץ על הלחצן של נתיב המדיה, מסלולי המדיה הזמינים מופיעים ברשימה שמוצגת באיור 3.
![](https://developer.android.google.cn/static/images/mediarouter/mediarouter-selector-ui.png?authuser=0000&hl=he)
איור 3. רשימה של מסלולי מדיה זמינים, שמוצגת לאחר לחיצה על הלחצן של נתיב המדיה.
יש לבצע את השלבים הבאים כדי ליצור לחצן למסלול מדיה:
- שימוש ב-AppCompatActivity
- הגדרת האפשרות בתפריט של הלחצן של נתיב המדיה
- יצירת MediaRouteSelector
- הוספת הלחצן של נתיב המדיה לסרגל הפעולות
- יצירה וניהול של methods של MediaRouter.Callback במחזור החיים של הפעילות
בקטע הזה מתוארים ארבעת השלבים הראשונים. הקטע הבא מתאר שיטות להתקשרות חזרה.
שימוש ב-AppCompatActivity
כשמשתמשים ב-framework של נתב המדיה בפעילות, צריך להרחיב
את הפעילות מ-AppCompatActivity
ולייבא את
חבילה מס' androidx.appcompat.app
. עליך להוסיף את
androidx.appcompat:appcompat
ו-androidx.mediarouter:mediarouter
תמיכה בספריות של פרויקט פיתוח האפליקציה. למידע נוסף על הוספת ספריות תמיכה
לפרויקט שלכם, ראו תחילת העבודה עם Android Jetpack.
זהירות: הקפידו להשתמש ב-androidx
של ה-framework של נתב המדיה. אין להשתמש בחבילה הישנה של android.media
.
הגדרת האפשרות בתפריט של הלחצן של נתיב המדיה
יוצרים קובץ XML שמגדיר פריט תפריט עבור הלחצן של נתיב המדיה.
הפעולה של הפריט צריכה להיות המחלקה MediaRouteActionProvider
.
קובץ לדוגמה:
// myMediaRouteButtonMenuItem.xml <?xml version="1.0" encoding="utf-8"?> <menu xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" > <item android:id="@+id/media_route_menu_item" android:title="@string/media_route_menu_title" app:actionProviderClass="androidx.mediarouter.app.MediaRouteActionProvider" app:showAsAction="always" /> </menu>
יצירת MediaRouteSelector
הנתיבים שמופיעים בתפריט הלחצנים של 'נתיב המדיה' נקבעים על ידי MediaRouteSelector
.
הארכת הפעילות מ-AppCompatActivity
וליצור את הבורר כשנוצרת הפעילות בקריאה אל MediaRouteSelector.Builder
מהשיטה onCreate() , כמו שמוצג
בדוגמת הקוד הבאה. שימו לב שהבורר נשמר במשתנה class, ומפורטים סוגי המסלולים המותרים.
על ידי הוספת MediaControlIntent
אובייקטים:
Kotlin
class MediaRouterPlaybackActivity : AppCompatActivity() { private var mSelector: MediaRouteSelector? = null override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) // Create a route selector for the type of routes your app supports. mSelector = MediaRouteSelector.Builder() // These are the framework-supported intents .addControlCategory(MediaControlIntent.CATEGORY_REMOTE_PLAYBACK) .build() } }
Java
public class MediaRouterPlaybackActivity extends AppCompatActivity { private MediaRouteSelector mSelector; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // Create a route selector for the type of routes your app supports. mSelector = new MediaRouteSelector.Builder() // These are the framework-supported intents .addControlCategory(MediaControlIntent.CATEGORY_REMOTE_PLAYBACK) .build(); } }
עבור רוב היישומים,
סוג המסלול הדרוש הוא CATEGORY_REMOTE_PLAYBACK
. בסוג המסלול הזה, המערכת מתייחסת למכשיר שמפעיל את האפליקציה שלך כשלט רחוק.
המכשיר המקבל המחובר מטפל בכל הנתונים באחזור, בפענוח ובהפעלה של נתוני תוכן.
כך מוצגות אפליקציות שתומכות ב-Google Cast,
Chromecast, עבודה.
מספר יצרנים תומכים באפשרות ניתוב מיוחדת שנקראת 'פלט משני'. בניתוב הזה,
אפליקציית המדיה מאחזרת, מעבדת ומשדרת מוזיקה או סרטונים ישירות למסך או לרמקולים במכשיר המקלט המרוחק שנבחר.
יש להשתמש בפלט משני כדי לשלוח תוכן למערכות מוזיקה או לתצוגות וידאו עם קישוריות אלחוטיות. כדי לאפשר את הגילוי
מבחר של המכשירים האלה, צריך להוסיף את
CATEGORY_LIVE_AUDIO
או
CATEGORY_LIVE_VIDEO
שליטה בקטגוריות ל-MediaRouteSelector. עליך גם ליצור תיבת דו-שיח משלך ב-Presentation
ולטפל בה.
הוספת הלחצן של נתיב המדיה לסרגל הפעולות
באמצעות התפריט של נתיב המדיה ו-MediaRouteSelector, אפשר עכשיו להוסיף את הלחצן של נתיב המדיה לפעילות.
כדי להוסיף אפשרויות, צריך לשנות את השיטה onCreateOptionsMenu()
לכל אחת מהפעילויות שלך
תפריט
Kotlin
override fun onCreateOptionsMenu(menu: Menu): Boolean { super.onCreateOptionsMenu(menu) // Inflate the menu and configure the media router action provider. menuInflater.inflate(R.menu.sample_media_router_menu, menu) // Attach the MediaRouteSelector to the menu item val mediaRouteMenuItem = menu.findItem(R.id.media_route_menu_item) val mediaRouteActionProvider = MenuItemCompat.getActionProvider(mediaRouteMenuItem) as MediaRouteActionProvider // Attach the MediaRouteSelector that you built in onCreate() selector?.also(mediaRouteActionProvider::setRouteSelector) // Return true to show the menu. return true }
Java
@Override public boolean onCreateOptionsMenu(Menu menu) { super.onCreateOptionsMenu(menu); // Inflate the menu and configure the media router action provider. getMenuInflater().inflate(R.menu.sample_media_router_menu, menu); // Attach the MediaRouteSelector to the menu item MenuItem mediaRouteMenuItem = menu.findItem(R.id.media_route_menu_item); MediaRouteActionProvider mediaRouteActionProvider = (MediaRouteActionProvider)MenuItemCompat.getActionProvider( mediaRouteMenuItem); // Attach the MediaRouteSelector that you built in onCreate() mediaRouteActionProvider.setRouteSelector(selector); // Return true to show the menu. return true; }
למידע נוסף על הטמעת סרגל הפעולות באפליקציה: עיון בסרגל הפעולות המדריך למפתחים.
אפשר גם להוסיף לחצן של נתיב מדיה כ-MediaRouteButton
בכל
צפייה. צריך לחבר MediaRouteSelector ללחצן באמצעות השיטה setRouteSelector()
. לצפייה
רשימת משימות לעיצוב של Google Cast
לקבלת הנחיות לשילוב הלחצן של נתיב המדיה באפליקציה.
התקשרות חזרה של MediaRouter
כל האפליקציות שפועלות באותו מכשיר חולקות מופע אחד של MediaRouter
והמסלולים שלו
(מסונן לפי אפליקציה על ידי MediaRouteSelector של האפליקציה). כל פעילות מתקשרת עם MediaRouter
באמצעות יישום משלו של MediaRouter.Callback
שיטות. MediaRouter קורא לשיטות הקריאה החוזרת בכל פעם שהמשתמש בוחר, משנה או מנתק מסלול.
יש מספר שיטות בקריאה החוזרת (callback) שאפשר לשנות כדי לקבל מידע עליהן
אירועי ניתוב. לכל הפחות, ההטמעה של המחלקה MediaRouter.Callback
צריכה לבטל
onRouteSelected()
והקבוצה
onRouteUnselected()
.
MediaRouter הוא משאב משותף, ולכן האפליקציה שלך צריכה לנהל את הקריאות החוזרות של MediaRouter בתגובה לקריאה החוזרת (callback) הרגילה של מחזור החיים של הפעילות:
- כשהפעילות נוצרת (
onCreate(Bundle)
), צריך לקחת את הסמן של העכבר מעל ה-MediaRouter
ולהחזיק בו כל משך החיים של האפליקציה. - יש לצרף ל-MediaRouter קריאות חוזרות (callback) כשהפעילות תהיה גלויה (
onStart()
) ולנתק אותן כשהיא מוסתרת (onStop()
).
דוגמת הקוד הבאה ממחישה איך
ליצור ולשמור את אובייקט הקריאה החוזרת,
לקבל מופע של MediaRouter
ואיך לנהל קריאות חוזרות.
חשוב לשים לב לשימוש בדגל CALLBACK_FLAG_REQUEST_DISCOVERY
כשמצרפים את הקריאות החוזרות ב-onStart()
.
הפעולה הזו מאפשרת ל-MediaRouteSelector לרענן את הלחצן של נתיב המדיה
רשימה של המסלולים הזמינים.
Kotlin
class MediaRouterPlaybackActivity : AppCompatActivity() { private var mediaRouter: MediaRouter? = null private var mSelector: MediaRouteSelector? = null // Variables to hold the currently selected route and its playback client private var mRoute: MediaRouter.RouteInfo? = null private var remotePlaybackClient: RemotePlaybackClient? = null // Define the Callback object and its methods, save the object in a class variable private val mediaRouterCallback = object : MediaRouter.Callback() { override fun onRouteSelected(router: MediaRouter, route: MediaRouter.RouteInfo) { Log.d(TAG, "onRouteSelected: route=$route") if (route.supportsControlCategory(MediaControlIntent.CATEGORY_REMOTE_PLAYBACK)) { // Stop local playback (if necessary) // ... // Save the new route mRoute = route // Attach a new playback client remotePlaybackClient = RemotePlaybackClient(this@MediaRouterPlaybackActivity, mRoute) // Start remote playback (if necessary) // ... } } override fun onRouteUnselected( router: MediaRouter, route: MediaRouter.RouteInfo, reason: Int ) { Log.d(TAG, "onRouteUnselected: route=$route") if (route.supportsControlCategory(MediaControlIntent.CATEGORY_REMOTE_PLAYBACK)) { // Changed route: tear down previous client mRoute?.also { remotePlaybackClient?.release() remotePlaybackClient = null } // Save the new route mRoute = route when (reason) { MediaRouter.UNSELECT_REASON_ROUTE_CHANGED -> { // Resume local playback (if necessary) // ... } } } } } // Retain a pointer to the MediaRouter override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) // Get the media router service. mediaRouter = MediaRouter.getInstance(this) ... } // Use this callback to run your MediaRouteSelector to generate the // list of available media routes override fun onStart() { mSelector?.also { selector -> mediaRouter?.addCallback(selector, mediaRouterCallback, MediaRouter.CALLBACK_FLAG_REQUEST_DISCOVERY) } super.onStart() } // Remove the selector on stop to tell the media router that it no longer // needs to discover routes for your app. override fun onStop() { mediaRouter?.removeCallback(mediaRouterCallback) super.onStop() } ... }
Java
public class MediaRouterPlaybackActivity extends AppCompatActivity { private MediaRouter mediaRouter; private MediaRouteSelector mSelector; // Variables to hold the currently selected route and its playback client private MediaRouter.RouteInfo mRoute; private RemotePlaybackClient remotePlaybackClient; // Define the Callback object and its methods, save the object in a class variable private final MediaRouter.Callback mediaRouterCallback = new MediaRouter.Callback() { @Override public void onRouteSelected(MediaRouter router, RouteInfo route) { Log.d(TAG, "onRouteSelected: route=" + route); if (route.supportsControlCategory( MediaControlIntent.CATEGORY_REMOTE_PLAYBACK)){ // Stop local playback (if necessary) // ... // Save the new route mRoute = route; // Attach a new playback client remotePlaybackClient = new RemotePlaybackClient(this, mRoute); // Start remote playback (if necessary) // ... } } @Override public void onRouteUnselected(MediaRouter router, RouteInfo route, int reason) { Log.d(TAG, "onRouteUnselected: route=" + route); if (route.supportsControlCategory( MediaControlIntent.CATEGORY_REMOTE_PLAYBACK)){ // Changed route: tear down previous client if (mRoute != null && remotePlaybackClient != null) { remotePlaybackClient.release(); remotePlaybackClient = null; } // Save the new route mRoute = route; if (reason != MediaRouter.UNSELECT_REASON_ROUTE_CHANGED) { // Resume local playback (if necessary) // ... } } } } // Retain a pointer to the MediaRouter @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // Get the media router service. mediaRouter = MediaRouter.getInstance(this); ... } // Use this callback to run your MediaRouteSelector to generate the list of available media routes @Override public void onStart() { mediaRouter.addCallback(mSelector, mediaRouterCallback, MediaRouter.CALLBACK_FLAG_REQUEST_DISCOVERY); super.onStart(); } // Remove the selector on stop to tell the media router that it no longer // needs to discover routes for your app. @Override public void onStop() { mediaRouter.removeCallback(mediaRouterCallback); super.onStop(); } ... }
ה-framework של נתב המדיה מספק גם
כיתה אחת (MediaRouteDiscoveryFragment
), שאחראית להוספה ולהוספה
הסרת הקריאה החוזרת לפעילות.
הערה: אם אתם כותבים אפליקציה להפעלת מוזיקה ורוצים שהיא תפעל
בזמן שהיא פועלת ברקע, עליך ליצור Service
להפעלה
ולקרוא ל-framework של נתב המדיה מהקריאות החוזרות (callback) במחזור החיים של השירות.
שליטה במסלול ההפעלה מרחוק
כשבוחרים מסלול להפעלה מרחוק, האפליקציה משמשת כשלט רחוק. המכשיר בקצה השני של המסלול
מטפל בכל הפונקציות לאחזור, פענוח וההפעלה של נתוני תוכן. הפקדים בממשק המשתמש של האפליקציה מתקשרים עם המכשיר המקבל באמצעות
אובייקט RemotePlaybackClient
.
בכיתה RemotePlaybackClient
יש שיטות נוספות
לניהול הפעלת תוכן. אלה כמה משיטות ההפעלה העיקריות בכיתה RemotePlaybackClient
:
play()
— הפעלת פריט ספציפי קובץ מדיה, שצוין באמצעותUri
.pause()
– משהים את טראק המדיה שמופעל עכשיו.resume()
– המשך השמעת הטראק הנוכחי לאחר פקודת השהיה.seek()
– העברה למאפיין ספציפי במיקום בטראק הנוכחי.release()
— יש להסיר את בחיבור בין האפליקציה למכשיר להפעלה מרחוק.
אפשר להשתמש בשיטות האלה כדי לצרף פעולות לפקדי ההפעלה שצוינו ב- אפליקציה. רוב השיטות האלה גם מאפשרות לכלול אובייקט של קריאה חוזרת (callback) כדי שתוכלו לעקוב את ההתקדמות של משימת ההפעלה או של בקשת הבקרה.
המחלקה RemotePlaybackClient
תומכת גם בתור
מספר פריטי מדיה להפעלה ולניהול של תור המדיה.
קוד לדוגמה
ה-Android BasicMediaRouter ו-MediaRouter דוגמאות נוספות מדגימות את השימוש ב-MediaRouter API.