Samples for media router support library.
Change-Id: I3c578f61e310b552b0dd372dc27c709c35193bbd
diff --git a/samples/Support4Demos/AndroidManifest.xml b/samples/Support4Demos/AndroidManifest.xml
index 0cb5442..603093f 100644
--- a/samples/Support4Demos/AndroidManifest.xml
+++ b/samples/Support4Demos/AndroidManifest.xml
@@ -301,5 +301,22 @@
</provider>
<!-- END_INCLUDE(file_provider_declaration) -->
+ <!-- MediaRouter Support Samples -->
+
+ <activity android:name=".media.SampleMediaRouterActivity"
+ android:label="@string/sample_media_router_activity">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="com.example.android.supportv4.SUPPORT4_SAMPLE_CODE" />
+ </intent-filter>
+ </activity>
+
+ <service android:name=".media.SampleMediaRouteProviderService"
+ android:label="@string/sample_media_route_provider_service"
+ android:process=":mediarouteprovider">
+ <intent-filter>
+ <action android:name="android.media.MediaRouteProviderService" />
+ </intent-filter>
+ </service>
</application>
</manifest>
diff --git a/samples/Support4Demos/res/drawable-hdpi/media_route_icon.png b/samples/Support4Demos/res/drawable-hdpi/media_route_icon.png
new file mode 100755
index 0000000..66a1984
--- /dev/null
+++ b/samples/Support4Demos/res/drawable-hdpi/media_route_icon.png
Binary files differ
diff --git a/samples/Support4Demos/res/drawable-mdpi/media_route_icon.png b/samples/Support4Demos/res/drawable-mdpi/media_route_icon.png
new file mode 100644
index 0000000..5ae7701
--- /dev/null
+++ b/samples/Support4Demos/res/drawable-mdpi/media_route_icon.png
Binary files differ
diff --git a/samples/Support4Demos/res/layout/sample_media_router.xml b/samples/Support4Demos/res/layout/sample_media_router.xml
new file mode 100644
index 0000000..a8b08b1
--- /dev/null
+++ b/samples/Support4Demos/res/layout/sample_media_router.xml
@@ -0,0 +1,64 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2013 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<!-- See corresponding Java code SampleMediaRouterActivity.java. -->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="vertical">
+
+ <!-- Message to show to use. -->
+ <TextView android:id="@+id/text"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_weight="0"
+ android:gravity="center_vertical|center_horizontal"
+ android:textAppearance="?android:attr/textAppearanceMedium"
+ android:text="@string/sample_media_router_text"/>
+
+ <!-- Some information about what's going on. -->
+ <TextView android:id="@+id/info"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_weight="0"
+ android:gravity="center_vertical|center_horizontal"
+ android:textAppearance="?android:attr/textAppearanceMedium"/>
+
+ <!-- Some media to play. -->
+ <ListView android:id="@+id/media"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_weight="1"/>
+
+ <!-- Control buttons for the currently selected route. -->
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_weight="0">
+ <Button android:id="@+id/play_button"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_weight="0"
+ android:text="@string/play_button_text" />
+
+ <Button android:id="@+id/statistics_button"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_weight="0"
+ android:text="@string/statistics_button_text" />
+ </LinearLayout>
+</LinearLayout>
diff --git a/samples/Support4Demos/res/menu/sample_media_router_menu.xml b/samples/Support4Demos/res/menu/sample_media_router_menu.xml
new file mode 100644
index 0000000..404654f
--- /dev/null
+++ b/samples/Support4Demos/res/menu/sample_media_router_menu.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2012 Google Inc.
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<menu xmlns:android="http://schemas.android.com/apk/res/android">
+<!-- TODO: Use MediaRouter support library -->
+ <item android:id="@+id/menu_media_route"
+ android:title="@string/sample_media_router_play_on"
+ android:showAsAction="always"
+ android:orderInCategory="1"
+ android:actionProviderClass="android.app.MediaRouteActionProvider"/>
+</menu>
diff --git a/samples/Support4Demos/res/values/arrays.xml b/samples/Support4Demos/res/values/arrays.xml
new file mode 100644
index 0000000..f5616a1
--- /dev/null
+++ b/samples/Support4Demos/res/values/arrays.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2013 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<resources>
+ <string-array name="media_names">
+ <item>My favorite video of cats</item>
+ <item>Cats on parade</item>
+ <item>Cats with hats</item>
+ <item>Hats on cats</item>
+ <item>Cats on mats</item>
+ </string-array>
+
+ <string-array name="media_uris">
+ <item>http://cats.example.com/favorite-cats.mp4</item>
+ <item>http://cats.example.com/cats-on-parade.mp4</item>
+ <item>http://cats.example.com/cats-with-hats.mp4</item>
+ <item>http://cats.example.com/hats-on-cats.mp4</item>
+ <item>http://cats.example.com/cats-on-mats.mp4</item>
+ </string-array>
+</resources>
diff --git a/samples/Support4Demos/res/values/strings.xml b/samples/Support4Demos/res/values/strings.xml
index 1ac30aa..4882f76 100644
--- a/samples/Support4Demos/res/values/strings.xml
+++ b/samples/Support4Demos/res/values/strings.xml
@@ -136,4 +136,17 @@
<string name="file_provider_example">FileProvider example</string>
+ <!-- MediaRouter -->
+
+ <string name="sample_media_router_activity">Media/MediaRouter</string>
+ <string name="sample_media_router_text">This activity demonstrates how to
+ use MediaRouter from the support library. Select a route from the action bar.</string>
+ <string name="sample_media_router_play_on">Play on...</string>
+
+ <string name="play_button_text">Play</string>
+ <string name="statistics_button_text">Show Statistics</string>
+
+ <string name="sample_media_route_provider_service">Media Route Provider Service Support Library Sample</string>
+ <string name="fixed_volume_route_name">Fixed Volume Remote Playback Route</string>
+ <string name="variable_volume_route_name">Variable Volume Remote Playback Route</string>
</resources>
diff --git a/samples/Support4Demos/src/com/example/android/supportv4/media/SampleMediaRouteProvider.java b/samples/Support4Demos/src/com/example/android/supportv4/media/SampleMediaRouteProvider.java
new file mode 100644
index 0000000..7dc1913
--- /dev/null
+++ b/samples/Support4Demos/src/com/example/android/supportv4/media/SampleMediaRouteProvider.java
@@ -0,0 +1,218 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.supportv4.media;
+
+import com.example.android.supportv4.R;
+
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.IntentFilter.MalformedMimeTypeException;
+import android.content.res.Resources;
+import android.media.MediaRouter;
+import android.net.Uri;
+import android.os.Bundle;
+import android.support.v4.media.MediaControlIntent;
+import android.support.v4.media.MediaRouteProvider;
+import android.support.v4.media.MediaRouter.ControlRequestCallback;
+import android.util.Log;
+import android.widget.Toast;
+
+/**
+ * Demonstrates how to create a custom media route provider.
+ *
+ * @see SampleMediaRouteProviderService
+ */
+final class SampleMediaRouteProvider extends MediaRouteProvider {
+ private static final String TAG = "SampleMediaRouteProvider";
+
+ private static final String FIXED_VOLUME_ROUTE_ID = "fixed";
+ private static final String VARIABLE_VOLUME_ROUTE_ID = "variable";
+ private static final int VOLUME_MAX = 10;
+
+ /**
+ * A custom media control intent category for special requests that are
+ * supported by this provider's routes.
+ */
+ public static final String CATEGORY_SAMPLE_ROUTE =
+ "com.example.android.supportv4.media.CATEGORY_SAMPLE_ROUTE";
+
+ /**
+ * A custom media control intent action for special requests that are
+ * supported by this provider's routes.
+ * <p>
+ * This particular request is designed to return a bundle of not very
+ * interesting statistics for demonstration purposes.
+ * </p>
+ *
+ * @see #DATA_PLAYBACK_COUNT
+ */
+ public static final String ACTION_GET_STATISTICS =
+ "com.example.android.supportv4.media.ACTION_GET_STATISTICS";
+
+ /**
+ * {@link #ACTION_GET_STATISTICS} result data: Number of times the
+ * playback action was invoked.
+ */
+ public static final String DATA_PLAYBACK_COUNT =
+ "com.example.android.supportv4.media.EXTRA_PLAYBACK_COUNT";
+
+ private static final IntentFilter[] CONTROL_FILTERS;
+ static {
+ CONTROL_FILTERS = new IntentFilter[2];
+
+ CONTROL_FILTERS[0] = new IntentFilter();
+ CONTROL_FILTERS[0].addCategory(CATEGORY_SAMPLE_ROUTE);
+ CONTROL_FILTERS[0].addAction(ACTION_GET_STATISTICS);
+
+ CONTROL_FILTERS[1] = new IntentFilter();
+ CONTROL_FILTERS[1].addCategory(MediaControlIntent.CATEGORY_REMOTE_PLAYBACK);
+ CONTROL_FILTERS[1].addAction(MediaControlIntent.ACTION_PLAY);
+ CONTROL_FILTERS[1].addDataScheme("http");
+ CONTROL_FILTERS[1].addDataScheme("https");
+ addDataTypeUnchecked(CONTROL_FILTERS[1], "video/*");
+ }
+
+ private static void addDataTypeUnchecked(IntentFilter filter, String type) {
+ try {
+ filter.addDataType(type);
+ } catch (MalformedMimeTypeException ex) {
+ throw new RuntimeException(ex);
+ }
+ }
+
+ private int mVolume = 5;
+ private int mPlaybackCount;
+
+ public SampleMediaRouteProvider(Context context) {
+ super(context);
+
+ publishRoutes();
+ }
+
+ @Override
+ public RouteController onCreateRouteController(String routeId) {
+ return new SampleRouteController(routeId);
+ }
+
+ private void publishRoutes() {
+ Resources r = getContext().getResources();
+
+ RouteDescriptor routeDescriptor1 = new RouteDescriptor(
+ FIXED_VOLUME_ROUTE_ID,
+ r.getString(R.string.fixed_volume_route_name));
+ routeDescriptor1.setControlFilters(CONTROL_FILTERS);
+ routeDescriptor1.setIconResource(R.drawable.media_route_icon);
+ routeDescriptor1.setPlaybackType(MediaRouter.RouteInfo.PLAYBACK_TYPE_REMOTE);
+ routeDescriptor1.setVolumeHandling(MediaRouter.RouteInfo.PLAYBACK_VOLUME_FIXED);
+ routeDescriptor1.setVolume(VOLUME_MAX);
+
+ RouteDescriptor routeDescriptor2 = new RouteDescriptor(
+ VARIABLE_VOLUME_ROUTE_ID,
+ r.getString(R.string.variable_volume_route_name));
+ routeDescriptor2.setControlFilters(CONTROL_FILTERS);
+ routeDescriptor2.setIconResource(R.drawable.media_route_icon);
+ routeDescriptor2.setPlaybackType(MediaRouter.RouteInfo.PLAYBACK_TYPE_REMOTE);
+ routeDescriptor2.setVolumeHandling(MediaRouter.RouteInfo.PLAYBACK_VOLUME_VARIABLE);
+ routeDescriptor2.setVolumeMax(VOLUME_MAX);
+ routeDescriptor2.setVolume(mVolume);
+
+ ProviderDescriptor providerDescriptor = new ProviderDescriptor();
+ providerDescriptor.setRoutes(new RouteDescriptor[] {
+ routeDescriptor1, routeDescriptor2
+ });
+ setDescriptor(providerDescriptor);
+ }
+
+ private final class SampleRouteController extends MediaRouteProvider.RouteController {
+ private final String mRouteId;
+
+ public SampleRouteController(String routeId) {
+ mRouteId = routeId;
+ Log.d(TAG, mRouteId + ": Controller created");
+ }
+
+ @Override
+ public void release() {
+ Log.d(TAG, mRouteId + ": Controller released");
+ }
+
+ @Override
+ public void select() {
+ Log.d(TAG, mRouteId + ": Selected");
+ }
+
+ @Override
+ public void unselect() {
+ Log.d(TAG, mRouteId + ": Unselected");
+ }
+
+ @Override
+ public void setVolume(int volume) {
+ Log.d(TAG, mRouteId + ": Set volume to " + volume);
+ if (mRouteId.equals(VARIABLE_VOLUME_ROUTE_ID)) {
+ setVolumeInternal(volume);
+ }
+ }
+
+ @Override
+ public void updateVolume(int delta) {
+ Log.d(TAG, mRouteId + ": Update volume by " + delta);
+ if (mRouteId.equals(VARIABLE_VOLUME_ROUTE_ID)) {
+ setVolumeInternal(mVolume + delta);
+ }
+ }
+
+ private void setVolumeInternal(int volume) {
+ if (volume >= 0 && volume <= VOLUME_MAX) {
+ mVolume = volume;
+ Log.d(TAG, mRouteId + ": New volume is " + mVolume);
+ publishRoutes();
+ }
+ }
+
+ @Override
+ public boolean sendControlRequest(Intent intent, ControlRequestCallback callback) {
+ Log.d(TAG, mRouteId + ": Received control request " + intent);
+ if (intent.getAction().equals(MediaControlIntent.ACTION_PLAY)
+ && intent.hasCategory(MediaControlIntent.CATEGORY_REMOTE_PLAYBACK)
+ && intent.getData() != null) {
+ mPlaybackCount +=1;
+
+ Uri uri = intent.getData();
+ Log.d(TAG, mRouteId + ": Received play request, uri=" + uri);
+ Toast.makeText(getContext(), "Route received play request: uri=" + uri,
+ Toast.LENGTH_LONG).show();
+ if (callback != null) {
+ callback.onResult(ControlRequestCallback.REQUEST_SUCCEEDED, null);
+ }
+ return true;
+ }
+
+ if (intent.getAction().equals(ACTION_GET_STATISTICS)
+ && intent.hasCategory(CATEGORY_SAMPLE_ROUTE)) {
+ Bundle data = new Bundle();
+ data.putInt(DATA_PLAYBACK_COUNT, mPlaybackCount);
+ if (callback != null) {
+ callback.onResult(ControlRequestCallback.REQUEST_SUCCEEDED, data);
+ }
+ return true;
+ }
+ return false;
+ }
+ }
+}
\ No newline at end of file
diff --git a/samples/Support4Demos/src/com/example/android/supportv4/media/SampleMediaRouteProviderService.java b/samples/Support4Demos/src/com/example/android/supportv4/media/SampleMediaRouteProviderService.java
new file mode 100644
index 0000000..4528e39
--- /dev/null
+++ b/samples/Support4Demos/src/com/example/android/supportv4/media/SampleMediaRouteProviderService.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.supportv4.media;
+
+import android.support.v4.media.MediaRouteProvider;
+import android.support.v4.media.MediaRouteProviderService;
+
+/**
+ * Demonstrates how to register a custom media route provider service
+ * using the support library.
+ *
+ * @see SampleMediaRouteProvider
+ */
+public class SampleMediaRouteProviderService extends MediaRouteProviderService {
+ @Override
+ public MediaRouteProvider onCreateMediaRouteProvider() {
+ return new SampleMediaRouteProvider(this);
+ }
+}
diff --git a/samples/Support4Demos/src/com/example/android/supportv4/media/SampleMediaRouterActivity.java b/samples/Support4Demos/src/com/example/android/supportv4/media/SampleMediaRouterActivity.java
new file mode 100644
index 0000000..48afad2
--- /dev/null
+++ b/samples/Support4Demos/src/com/example/android/supportv4/media/SampleMediaRouterActivity.java
@@ -0,0 +1,340 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.supportv4.media;
+
+import com.example.android.supportv4.R;
+
+import android.app.Activity;
+import android.app.MediaRouteActionProvider;
+import android.content.Intent;
+import android.net.Uri;
+import android.os.Bundle;
+import android.support.v4.media.MediaControlIntent;
+import android.support.v4.media.MediaRouter;
+import android.support.v4.media.MediaRouter.RouteInfo;
+import android.support.v4.media.MediaRouter.ProviderInfo;
+import android.util.Log;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.widget.AdapterView.OnItemClickListener;
+import android.widget.AdapterView;
+import android.widget.ArrayAdapter;
+import android.widget.Button;
+import android.widget.ListView;
+import android.widget.TextView;
+import android.widget.Toast;
+
+/**
+ * <h3>Media Router Support Activity</h3>
+ *
+ * <p>
+ * This demonstrates how to use the {@link MediaRouter} API to build an
+ * application that allows the user to send content to various rendering
+ * targets.
+ * </p>
+ */
+public class SampleMediaRouterActivity extends Activity {
+ private final String TAG = "MediaRouterSupport";
+
+ private MediaRouter mMediaRouter;
+ private ArrayAdapter<MediaItem> mMediaItems;
+ private TextView mInfoTextView;
+ private ListView mMediaListView;
+ private Button mPlayButton;
+ private Button mStatisticsButton;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ // Be sure to call the super class.
+ super.onCreate(savedInstanceState);
+
+ // Get the media router service.
+ mMediaRouter = MediaRouter.getInstance(this);
+
+ // Populate an array adapter with fake media items.
+ String[] mediaNames = getResources().getStringArray(R.array.media_names);
+ String[] mediaUris = getResources().getStringArray(R.array.media_uris);
+ mMediaItems = new ArrayAdapter<MediaItem>(this,
+ android.R.layout.simple_list_item_single_choice, android.R.id.text1);
+ for (int i = 0; i < mediaNames.length; i++) {
+ mMediaItems.add(new MediaItem(mediaNames[i], Uri.parse(mediaUris[i])));
+ }
+
+ // Initialize the layout.
+ setContentView(R.layout.sample_media_router);
+
+ mInfoTextView = (TextView)findViewById(R.id.info);
+
+ mMediaListView = (ListView)findViewById(R.id.media);
+ mMediaListView.setAdapter(mMediaItems);
+ mMediaListView.setChoiceMode(ListView.CHOICE_MODE_SINGLE);
+ mMediaListView.setOnItemClickListener(new OnItemClickListener() {
+ @Override
+ public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
+ updateButtons();
+ }
+ });
+
+ mPlayButton = (Button)findViewById(R.id.play_button);
+ mPlayButton.setOnClickListener(new OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ play();
+ }
+ });
+
+ mStatisticsButton = (Button)findViewById(R.id.statistics_button);
+ mStatisticsButton.setOnClickListener(new OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ showStatistics();
+ }
+ });
+ }
+
+ @Override
+ protected void onResume() {
+ // Be sure to call the super class.
+ super.onResume();
+
+ // Listen for changes to media routes.
+ mMediaRouter.addCallback(mMediaRouterCallback);
+ updateRouteStatus();
+ }
+
+ @Override
+ protected void onPause() {
+ // Be sure to call the super class.
+ super.onPause();
+
+ // Stop listening for changes to media routes.
+ mMediaRouter.removeCallback(mMediaRouterCallback);
+ }
+
+ // TODO: Use ActionBar support library.
+ @Override
+ public boolean onCreateOptionsMenu(Menu menu) {
+ // Be sure to call the super class.
+ super.onCreateOptionsMenu(menu);
+
+ // Inflate the menu and configure the media router action provider.
+ getMenuInflater().inflate(R.menu.sample_media_router_menu, menu);
+
+ // TODO: Use support library media route action provider.
+ MenuItem mediaRouteMenuItem = menu.findItem(R.id.menu_media_route);
+ MediaRouteActionProvider mediaRouteActionProvider =
+ (MediaRouteActionProvider)mediaRouteMenuItem.getActionProvider();
+ mediaRouteActionProvider.setRouteTypes(
+ android.media.MediaRouter.ROUTE_TYPE_LIVE_AUDIO
+ | android.media.MediaRouter.ROUTE_TYPE_LIVE_VIDEO
+ | android.media.MediaRouter.ROUTE_TYPE_USER);
+
+ // Return true to show the menu.
+ return true;
+ }
+
+ private void updateRouteStatus() {
+ RouteInfo route = mMediaRouter.getSelectedRoute();
+ mInfoTextView.setText("Currently selected route: " + route.getName()
+ + " from provider " + route.getProvider().getPackageName()
+ + ", status: " + route.getStatus());
+ updateButtons();
+ }
+
+ private void updateButtons() {
+ MediaRouter.RouteInfo route = mMediaRouter.getSelectedRoute();
+
+ MediaItem item = getCheckedMediaItem();
+ if (item != null) {
+ mPlayButton.setEnabled(route.supportsControlRequest(makePlayIntent(item)));
+ } else {
+ mPlayButton.setEnabled(false);
+ }
+
+ mStatisticsButton.setEnabled(route.supportsControlRequest(makeStatisticsIntent()));
+ }
+
+ private void play() {
+ final MediaItem item = getCheckedMediaItem();
+ if (item == null) {
+ return;
+ }
+
+ MediaRouter.RouteInfo route = mMediaRouter.getSelectedRoute();
+ Intent intent = makePlayIntent(item);
+ if (route.supportsControlRequest(intent)) {
+ MediaRouter.ControlRequestCallback callback =
+ new MediaRouter.ControlRequestCallback() {
+ @Override
+ public void onResult(int result, Bundle data) {
+ switch (result) {
+ case REQUEST_SUCCEEDED:
+ Log.d(TAG, "Play request succeeded: data=" + data);
+ Toast.makeText(SampleMediaRouterActivity.this,
+ "Now playing " + item.mName,
+ Toast.LENGTH_LONG).show();
+ break;
+
+ case REQUEST_FAILED:
+ Log.d(TAG, "Play request failed: data=" + data);
+ Toast.makeText(SampleMediaRouterActivity.this,
+ "Unable to play " + item.mName,
+ Toast.LENGTH_LONG).show();
+ break;
+ }
+ }
+ };
+
+ Log.d(TAG, "Sending play request: intent=" + intent);
+ route.sendControlRequest(intent, callback);
+ } else {
+ Log.d(TAG, "Play request not supported: intent=" + intent);
+ Toast.makeText(SampleMediaRouterActivity.this,
+ "Play not supported for " + item.mName, Toast.LENGTH_LONG).show();
+ }
+ }
+
+ private void showStatistics() {
+ MediaRouter.RouteInfo route = mMediaRouter.getSelectedRoute();
+ Intent intent = makeStatisticsIntent();
+ if (route.supportsControlRequest(intent)) {
+ MediaRouter.ControlRequestCallback callback = new MediaRouter.ControlRequestCallback() {
+ @Override
+ public void onResult(int result, Bundle data) {
+ switch (result) {
+ case REQUEST_SUCCEEDED:
+ Log.d(TAG, "Statistics request succeeded: data=" + data);
+ if (data != null) {
+ int playbackCount = data.getInt(
+ SampleMediaRouteProvider.DATA_PLAYBACK_COUNT, -1);
+ Toast.makeText(SampleMediaRouterActivity.this,
+ "Total playback count: " + playbackCount,
+ Toast.LENGTH_LONG).show();
+ } else {
+ Toast.makeText(SampleMediaRouterActivity.this,
+ "Statistics query did not return any data",
+ Toast.LENGTH_LONG).show();
+ }
+ break;
+
+ case REQUEST_FAILED:
+ Log.d(TAG, "Statistics request failed: data=" + data);
+ Toast.makeText(SampleMediaRouterActivity.this,
+ "Unable to query statistics.",
+ Toast.LENGTH_LONG).show();
+ break;
+ }
+ }
+ };
+
+ Log.d(TAG, "Sent statistics request: intent=" + intent);
+ route.sendControlRequest(intent, callback);
+ } else {
+ Log.d(TAG, "Statistics request not supported: intent=" + intent);
+ Toast.makeText(SampleMediaRouterActivity.this,
+ "Statistics not supported.", Toast.LENGTH_LONG).show();
+ }
+ }
+
+ private Intent makePlayIntent(MediaItem item) {
+ Intent intent = new Intent(MediaControlIntent.ACTION_PLAY);
+ intent.addCategory(MediaControlIntent.CATEGORY_REMOTE_PLAYBACK);
+ intent.setDataAndType(item.mUri, "video/mp4");
+ return intent;
+ }
+
+ private Intent makeStatisticsIntent() {
+ Intent intent = new Intent(SampleMediaRouteProvider.ACTION_GET_STATISTICS);
+ intent.addCategory(SampleMediaRouteProvider.CATEGORY_SAMPLE_ROUTE);
+ return intent;
+ }
+
+ private MediaItem getCheckedMediaItem() {
+ int index = mMediaListView.getCheckedItemPosition();
+ if (index >= 0 && index < mMediaItems.getCount()) {
+ return mMediaItems.getItem(index);
+ }
+ return null;
+ }
+
+ private final MediaRouter.Callback mMediaRouterCallback = new MediaRouter.Callback() {
+ @Override
+ public void onRouteAdded(MediaRouter router, RouteInfo route) {
+ Log.d(TAG, "onRouteAdded: route=" + route);
+ }
+
+ @Override
+ public void onRouteChanged(MediaRouter router, RouteInfo route) {
+ Log.d(TAG, "onRouteChanged: route=" + route);
+ updateRouteStatus();
+ }
+
+ @Override
+ public void onRouteRemoved(MediaRouter router, RouteInfo route) {
+ Log.d(TAG, "onRouteRemoved: route=" + route);
+ }
+
+ @Override
+ public void onRouteSelected(MediaRouter router, RouteInfo route) {
+ Log.d(TAG, "onRouteSelected: route=" + route);
+ updateRouteStatus();
+ }
+
+ @Override
+ public void onRouteUnselected(MediaRouter router, RouteInfo route) {
+ Log.d(TAG, "onRouteUnselected: route=" + route);
+ updateRouteStatus();
+ }
+
+ @Override
+ public void onRouteVolumeChanged(MediaRouter router, RouteInfo route) {
+ Log.d(TAG, "onRouteVolumeChanged: route=" + route);
+ }
+
+ @Override
+ public void onRoutePresentationDisplayChanged(MediaRouter router, RouteInfo route) {
+ Log.d(TAG, "onRoutePresentationDisplayChanged: route=" + route);
+ }
+
+ @Override
+ public void onProviderAdded(MediaRouter router, ProviderInfo provider) {
+ Log.d(TAG, "onRouteProviderAdded: provider=" + provider);
+ }
+
+ @Override
+ public void onProviderRemoved(MediaRouter router, ProviderInfo provider) {
+ Log.d(TAG, "onRouteProviderRemoved: provider=" + provider);
+ }
+ };
+
+ private static final class MediaItem {
+ public final String mName;
+ public final Uri mUri;
+
+ public MediaItem(String name, Uri uri) {
+ mName = name;
+ mUri = uri;
+ }
+
+ @Override
+ public String toString() {
+ return mName;
+ }
+ }
+}