Fields Summary |
---|
private static final String | TAG |
private static final boolean | DEBUG |
public static final int | UNSELECT_REASON_UNKNOWNPassed to {@link android.support.v7.media.MediaRouteProvider.RouteController#onUnselect(int)}
when the reason the route was unselected is unknown. |
public static final int | UNSELECT_REASON_DISCONNECTEDPassed to {@link android.support.v7.media.MediaRouteProvider.RouteController#onUnselect(int)}
when the user pressed the disconnect button to disconnect and keep playing.
|
public static final int | UNSELECT_REASON_STOPPEDPassed to {@link android.support.v7.media.MediaRouteProvider.RouteController#onUnselect(int)}
when the user pressed the stop casting button. |
public static final int | UNSELECT_REASON_ROUTE_CHANGEDPassed to {@link android.support.v7.media.MediaRouteProvider.RouteController#onUnselect(int)}
when the user selected a different route. |
static GlobalMediaRouter | sGlobal |
final android.content.Context | mContext |
final ArrayList | mCallbackRecords |
public static final int | CALLBACK_FLAG_PERFORM_ACTIVE_SCANFlag for {@link #addCallback}: Actively scan for routes while this callback
is registered.
When this flag is specified, the media router will actively scan for new
routes. Certain routes, such as wifi display routes, may not be discoverable
except when actively scanning. This flag is typically used when the route picker
dialog has been opened by the user to ensure that the route information is
up to date.
Active scanning may consume a significant amount of power and may have intrusive
effects on wireless connectivity. Therefore it is important that active scanning
only be requested when it is actually needed to satisfy a user request to
discover and select a new route.
This flag implies {@link #CALLBACK_FLAG_REQUEST_DISCOVERY} but performing
active scans is much more expensive than a normal discovery request.
|
public static final int | CALLBACK_FLAG_UNFILTERED_EVENTSFlag for {@link #addCallback}: Do not filter route events.
When this flag is specified, the callback will be invoked for events that affect any
route even if they do not match the callback's filter.
|
public static final int | CALLBACK_FLAG_REQUEST_DISCOVERYFlag for {@link #addCallback}: Request passive route discovery while this
callback is registered, except on {@link ActivityManager#isLowRamDevice low-RAM devices}.
When this flag is specified, the media router will try to discover routes.
Although route discovery is intended to be efficient, checking for new routes may
result in some network activity and could slowly drain the battery. Therefore
applications should only specify {@link #CALLBACK_FLAG_REQUEST_DISCOVERY} when
they are running in the foreground and would like to provide the user with the
option of connecting to new routes.
Applications should typically add a callback using this flag in the
{@link android.app.Activity activity's} {@link android.app.Activity#onStart onStart}
method and remove it in the {@link android.app.Activity#onStop onStop} method.
The {@link android.support.v7.app.MediaRouteDiscoveryFragment} fragment may
also be used for this purpose.
On {@link ActivityManager#isLowRamDevice low-RAM devices} this flag
will be ignored. Refer to
{@link #addCallback(MediaRouteSelector, Callback, int) addCallback} for details.
|
public static final int | CALLBACK_FLAG_FORCE_DISCOVERYFlag for {@link #addCallback}: Request passive route discovery while this
callback is registered, even on {@link ActivityManager#isLowRamDevice low-RAM devices}.
This flag has a significant performance impact on low-RAM devices
since it may cause many media route providers to be started simultaneously.
It is much better to use {@link #CALLBACK_FLAG_REQUEST_DISCOVERY} instead to avoid
performing passive discovery on these devices altogether. Refer to
{@link #addCallback(MediaRouteSelector, Callback, int) addCallback} for details.
|
public static final int | AVAILABILITY_FLAG_IGNORE_DEFAULT_ROUTEFlag for {@link #isRouteAvailable}: Ignore the default route.
This flag is used to determine whether a matching non-default route is available.
This constraint may be used to decide whether to offer the route chooser dialog
to the user. There is no point offering the chooser if there are no
non-default choices.
|
public static final int | AVAILABILITY_FLAG_REQUIRE_MATCHFlag for {@link #isRouteAvailable}: Require an actual route to be matched.
If this flag is not set, then {@link #isRouteAvailable} will return true
if it is possible to discover a matching route even if discovery is not in
progress or if no matching route has yet been found. This feature is used to
save resources by removing the need to perform passive route discovery on
{@link ActivityManager#isLowRamDevice low-RAM devices}.
If this flag is set, then {@link #isRouteAvailable} will only return true if
a matching route has actually been discovered.
|
Methods Summary |
---|
public void | addCallback(MediaRouteSelector selector, android.support.v7.media.MediaRouter$Callback callback)Registers a callback to discover routes that match the selector and to receive
events when they change.
This is a convenience method that has the same effect as calling
{@link #addCallback(MediaRouteSelector, Callback, int)} without flags.
addCallback(selector, callback, 0);
|
public void | addCallback(MediaRouteSelector selector, android.support.v7.media.MediaRouter$Callback callback, int flags)Registers a callback to discover routes that match the selector and to receive
events when they change.
The selector describes the kinds of routes that the application wants to
discover. For example, if the application wants to use
live audio routes then it should include the
{@link MediaControlIntent#CATEGORY_LIVE_AUDIO live audio media control intent category}
in its selector when it adds a callback to the media router.
The selector may include any number of categories.
If the callback has already been registered, then the selector is added to
the set of selectors being monitored by the callback.
By default, the callback will only be invoked for events that affect routes
that match the specified selector. Event filtering may be disabled by specifying
the {@link #CALLBACK_FLAG_UNFILTERED_EVENTS} flag when the callback is registered.
Applications should use the {@link #isRouteAvailable} method to determine
whether is it possible to discover a route with the desired capabilities
and therefore whether the media route button should be shown to the user.
The {@link #CALLBACK_FLAG_REQUEST_DISCOVERY} flag should be used while the application
is in the foreground to request that passive discovery be performed if there are
sufficient resources to allow continuous passive discovery.
On {@link ActivityManager#isLowRamDevice low-RAM devices} this flag will be
ignored to conserve resources.
The {@link #CALLBACK_FLAG_FORCE_DISCOVERY} flag should be used when
passive discovery absolutely must be performed, even on low-RAM devices.
This flag has a significant performance impact on low-RAM devices
since it may cause many media route providers to be started simultaneously.
It is much better to use {@link #CALLBACK_FLAG_REQUEST_DISCOVERY} instead to avoid
performing passive discovery on these devices altogether.
The {@link #CALLBACK_FLAG_PERFORM_ACTIVE_SCAN} flag should be used when the
media route chooser dialog is showing to confirm the presence of available
routes that the user may connect to. This flag may use substantially more
power.
Example
public class MyActivity extends Activity {
private MediaRouter mRouter;
private MediaRouter.Callback mCallback;
private MediaRouteSelector mSelector;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mRouter = Mediarouter.getInstance(this);
mCallback = new MyCallback();
mSelector = new MediaRouteSelector.Builder()
.addControlCategory(MediaControlIntent.CATEGORY_LIVE_AUDIO)
.addControlCategory(MediaControlIntent.CATEGORY_REMOTE_PLAYBACK)
.build();
}
// Add the callback on start to tell the media router what kinds of routes
// the application is interested in so that it can try to discover suitable ones.
public void onStart() {
super.onStart();
mediaRouter.addCallback(mSelector, mCallback,
MediaRouter.CALLBACK_FLAG_REQUEST_DISCOVERY);
MediaRouter.RouteInfo route = mediaRouter.updateSelectedRoute(mSelector);
// do something with the route...
}
// Remove the selector on stop to tell the media router that it no longer
// needs to invest effort trying to discover routes of these kinds for now.
public void onStop() {
super.onStop();
mediaRouter.removeCallback(mCallback);
}
private final class MyCallback extends MediaRouter.Callback {
// Implement callback methods as needed.
}
}
if (selector == null) {
throw new IllegalArgumentException("selector must not be null");
}
if (callback == null) {
throw new IllegalArgumentException("callback must not be null");
}
checkCallingThread();
if (DEBUG) {
Log.d(TAG, "addCallback: selector=" + selector
+ ", callback=" + callback + ", flags=" + Integer.toHexString(flags));
}
CallbackRecord record;
int index = findCallbackRecord(callback);
if (index < 0) {
record = new CallbackRecord(this, callback);
mCallbackRecords.add(record);
} else {
record = mCallbackRecords.get(index);
}
boolean updateNeeded = false;
if ((flags & ~record.mFlags) != 0) {
record.mFlags |= flags;
updateNeeded = true;
}
if (!record.mSelector.contains(selector)) {
record.mSelector = new MediaRouteSelector.Builder(record.mSelector)
.addSelector(selector)
.build();
updateNeeded = true;
}
if (updateNeeded) {
sGlobal.updateDiscoveryRequest();
}
|
public void | addProvider(MediaRouteProvider providerInstance)Registers a media route provider within this application process.
The provider will be added to the list of providers that all {@link MediaRouter}
instances within this process can use to discover routes.
if (providerInstance == null) {
throw new IllegalArgumentException("providerInstance must not be null");
}
checkCallingThread();
if (DEBUG) {
Log.d(TAG, "addProvider: " + providerInstance);
}
sGlobal.addProvider(providerInstance);
|
public void | addRemoteControlClient(java.lang.Object remoteControlClient)Adds a remote control client to enable remote control of the volume
of the selected route.
The remote control client must have previously been registered with
the audio manager using the {@link android.media.AudioManager#registerRemoteControlClient
AudioManager.registerRemoteControlClient} method.
if (remoteControlClient == null) {
throw new IllegalArgumentException("remoteControlClient must not be null");
}
checkCallingThread();
if (DEBUG) {
Log.d(TAG, "addRemoteControlClient: " + remoteControlClient);
}
sGlobal.addRemoteControlClient(remoteControlClient);
|
static void | checkCallingThread()Ensures that calls into the media router are on the correct thread.
It pays to be a little paranoid when global state invariants are at risk.
if (Looper.myLooper() != Looper.getMainLooper()) {
throw new IllegalStateException("The media router service must only be "
+ "accessed on the application's main thread.");
}
|
static boolean | equal(T a, T b)
return a == b || (a != null && b != null && a.equals(b));
|
private int | findCallbackRecord(android.support.v7.media.MediaRouter$Callback callback)
final int count = mCallbackRecords.size();
for (int i = 0; i < count; i++) {
if (mCallbackRecords.get(i).mCallback == callback) {
return i;
}
}
return -1;
|
public android.support.v7.media.MediaRouter$RouteInfo | getDefaultRoute()Gets the default route for playing media content on the system.
The system always provides a default route.
checkCallingThread();
return sGlobal.getDefaultRoute();
|
public static android.support.v7.media.MediaRouter | getInstance(android.content.Context context)Gets an instance of the media router service associated with the context.
The application is responsible for holding a strong reference to the returned
{@link MediaRouter} instance, such as by storing the instance in a field of
the {@link android.app.Activity}, to ensure that the media router remains alive
as long as the application is using its features.
In other words, the support library only holds a {@link WeakReference weak reference}
to each media router instance. When there are no remaining strong references to the
media router instance, all of its callbacks will be removed and route discovery
will no longer be performed on its behalf.
if (context == null) {
throw new IllegalArgumentException("context must not be null");
}
checkCallingThread();
if (sGlobal == null) {
sGlobal = new GlobalMediaRouter(context.getApplicationContext());
sGlobal.start();
}
return sGlobal.getRouter(context);
|
public MediaSessionCompat.Token | getMediaSessionToken()
return sGlobal.getMediaSessionToken();
|
public java.util.List | getProviders()Gets information about the {@link MediaRouter.ProviderInfo route providers}
currently known to this media router.
checkCallingThread();
return sGlobal.getProviders();
|
public java.util.List | getRoutes()Gets information about the {@link MediaRouter.RouteInfo routes} currently known to
this media router.
checkCallingThread();
return sGlobal.getRoutes();
|
public android.support.v7.media.MediaRouter$RouteInfo | getSelectedRoute()Gets the currently selected route.
The application should examine the route's
{@link RouteInfo#getControlFilters media control intent filters} to assess the
capabilities of the route before attempting to use it.
Example
public boolean playMovie() {
MediaRouter mediaRouter = MediaRouter.getInstance(context);
MediaRouter.RouteInfo route = mediaRouter.getSelectedRoute();
// First try using the remote playback interface, if supported.
if (route.supportsControlCategory(MediaControlIntent.CATEGORY_REMOTE_PLAYBACK)) {
// The route supports remote playback.
// Try to send it the Uri of the movie to play.
Intent intent = new Intent(MediaControlIntent.ACTION_PLAY);
intent.addCategory(MediaControlIntent.CATEGORY_REMOTE_PLAYBACK);
intent.setDataAndType("http://example.com/videos/movie.mp4", "video/mp4");
if (route.supportsControlRequest(intent)) {
route.sendControlRequest(intent, null);
return true; // sent the request to play the movie
}
}
// If remote playback was not possible, then play locally.
if (route.supportsControlCategory(MediaControlIntent.CATEGORY_LIVE_VIDEO)) {
// The route supports live video streaming.
// Prepare to play content locally in a window or in a presentation.
return playMovieInWindow();
}
// Neither interface is supported, so we can't play the movie to this route.
return false;
}
checkCallingThread();
return sGlobal.getSelectedRoute();
|
public boolean | isRouteAvailable(MediaRouteSelector selector, int flags)Returns true if there is a route that matches the specified selector.
This method returns true if there are any available routes that match the
selector regardless of whether they are enabled or disabled. If the
{@link #AVAILABILITY_FLAG_IGNORE_DEFAULT_ROUTE} flag is specified, then
the method will only consider non-default routes.
On {@link ActivityManager#isLowRamDevice low-RAM devices} this method
will return true if it is possible to discover a matching route even if
discovery is not in progress or if no matching route has yet been found.
Use {@link #AVAILABILITY_FLAG_REQUIRE_MATCH} to require an actual match.
if (selector == null) {
throw new IllegalArgumentException("selector must not be null");
}
checkCallingThread();
return sGlobal.isRouteAvailable(selector, flags);
|
public void | removeCallback(android.support.v7.media.MediaRouter$Callback callback)Removes the specified callback. It will no longer receive events about
changes to media routes.
if (callback == null) {
throw new IllegalArgumentException("callback must not be null");
}
checkCallingThread();
if (DEBUG) {
Log.d(TAG, "removeCallback: callback=" + callback);
}
int index = findCallbackRecord(callback);
if (index >= 0) {
mCallbackRecords.remove(index);
sGlobal.updateDiscoveryRequest();
}
|
public void | removeProvider(MediaRouteProvider providerInstance)Unregisters a media route provider within this application process.
The provider will be removed from the list of providers that all {@link MediaRouter}
instances within this process can use to discover routes.
if (providerInstance == null) {
throw new IllegalArgumentException("providerInstance must not be null");
}
checkCallingThread();
if (DEBUG) {
Log.d(TAG, "removeProvider: " + providerInstance);
}
sGlobal.removeProvider(providerInstance);
|
public void | removeRemoteControlClient(java.lang.Object remoteControlClient)Removes a remote control client.
if (remoteControlClient == null) {
throw new IllegalArgumentException("remoteControlClient must not be null");
}
if (DEBUG) {
Log.d(TAG, "removeRemoteControlClient: " + remoteControlClient);
}
sGlobal.removeRemoteControlClient(remoteControlClient);
|
public void | selectRoute(android.support.v7.media.MediaRouter$RouteInfo route)Selects the specified route.
if (route == null) {
throw new IllegalArgumentException("route must not be null");
}
checkCallingThread();
if (DEBUG) {
Log.d(TAG, "selectRoute: " + route);
}
sGlobal.selectRoute(route);
|
public void | setMediaSession(java.lang.Object mediaSession)Sets the media session to enable remote control of the volume of the
selected route. This should be used instead of
{@link #addRemoteControlClient} when using media sessions. Set the
session to null to clear it.
if (DEBUG) {
Log.d(TAG, "addMediaSession: " + mediaSession);
}
sGlobal.setMediaSession(mediaSession);
|
public void | setMediaSessionCompat(android.support.v4.media.session.MediaSessionCompat mediaSession)Sets a compat media session to enable remote control of the volume of the
selected route. This should be used instead of
{@link #addRemoteControlClient} when using {@link MediaSessionCompat}.
Set the session to null to clear it.
if (DEBUG) {
Log.d(TAG, "addMediaSessionCompat: " + mediaSession);
}
sGlobal.setMediaSessionCompat(mediaSession);
|
public void | unselect(int reason)Unselects the current round and selects the default route instead.
The reason given must be one of:
- {@link MediaRouter#UNSELECT_REASON_UNKNOWN}
- {@link MediaRouter#UNSELECT_REASON_DISCONNECTED}
- {@link MediaRouter#UNSELECT_REASON_STOPPED}
- {@link MediaRouter#UNSELECT_REASON_ROUTE_CHANGED}
if (reason < MediaRouter.UNSELECT_REASON_UNKNOWN ||
reason > MediaRouter.UNSELECT_REASON_ROUTE_CHANGED) {
throw new IllegalArgumentException("Unsupported reason to unselect route");
}
checkCallingThread();
sGlobal.selectRoute(getDefaultRoute(), reason);
|
public android.support.v7.media.MediaRouter$RouteInfo | updateSelectedRoute(MediaRouteSelector selector)Returns the selected route if it matches the specified selector, otherwise
selects the default route and returns it.
if (selector == null) {
throw new IllegalArgumentException("selector must not be null");
}
checkCallingThread();
if (DEBUG) {
Log.d(TAG, "updateSelectedRoute: " + selector);
}
RouteInfo route = sGlobal.getSelectedRoute();
if (!route.isDefault() && !route.matchesSelector(selector)) {
route = sGlobal.getDefaultRoute();
sGlobal.selectRoute(route);
}
return route;
|