SampleMediaRouterActivity.java revision 55e47d370890d3cbdab82857090c42df734ba276
1/* 2 * Copyright (C) 2013 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package com.example.android.supportv7.media; 18 19import com.example.android.supportv7.R; 20 21import android.content.Intent; 22import android.net.Uri; 23import android.os.Bundle; 24import android.support.v4.view.MenuItemCompat; 25import android.support.v7.app.ActionBarActivity; 26import android.support.v7.app.MediaRouteActionProvider; 27import android.support.v7.media.MediaControlIntent; 28import android.support.v7.media.MediaRouter; 29import android.support.v7.media.MediaRouter.RouteInfo; 30import android.support.v7.media.MediaRouter.ProviderInfo; 31import android.support.v7.media.MediaRouteSelector; 32import android.util.Log; 33import android.view.Menu; 34import android.view.MenuItem; 35import android.view.View; 36import android.view.View.OnClickListener; 37import android.widget.AdapterView.OnItemClickListener; 38import android.widget.AdapterView; 39import android.widget.ArrayAdapter; 40import android.widget.Button; 41import android.widget.ListView; 42import android.widget.TextView; 43import android.widget.Toast; 44 45/** 46 * <h3>Media Router Support Activity</h3> 47 * 48 * <p> 49 * This demonstrates how to use the {@link MediaRouter} API to build an 50 * application that allows the user to send content to various rendering 51 * targets. 52 * </p> 53 */ 54public class SampleMediaRouterActivity extends ActionBarActivity { 55 private final String TAG = "MediaRouterSupport"; 56 57 private MediaRouter mMediaRouter; 58 private MediaRouteSelector mSelector; 59 private ArrayAdapter<MediaItem> mMediaItems; 60 private TextView mInfoTextView; 61 private ListView mMediaListView; 62 private Button mPlayButton; 63 private Button mStatisticsButton; 64 65 @Override 66 protected void onCreate(Bundle savedInstanceState) { 67 // Be sure to call the super class. 68 super.onCreate(savedInstanceState); 69 70 // Get the media router service. 71 mMediaRouter = MediaRouter.getInstance(this); 72 73 // Create a route selector for the type of routes that we care about. 74 mSelector = new MediaRouteSelector.Builder() 75 .addControlCategory(MediaControlIntent.CATEGORY_LIVE_AUDIO) 76 .addControlCategory(MediaControlIntent.CATEGORY_LIVE_VIDEO) 77 .addControlCategory(MediaControlIntent.CATEGORY_REMOTE_PLAYBACK) 78 .addControlCategory(SampleMediaRouteProvider.CATEGORY_SAMPLE_ROUTE) 79 .build(); 80 81 // Populate an array adapter with fake media items. 82 String[] mediaNames = getResources().getStringArray(R.array.media_names); 83 String[] mediaUris = getResources().getStringArray(R.array.media_uris); 84 mMediaItems = new ArrayAdapter<MediaItem>(this, 85 android.R.layout.simple_list_item_single_choice, android.R.id.text1); 86 for (int i = 0; i < mediaNames.length; i++) { 87 mMediaItems.add(new MediaItem(mediaNames[i], Uri.parse(mediaUris[i]))); 88 } 89 90 // Initialize the layout. 91 setContentView(R.layout.sample_media_router); 92 93 mInfoTextView = (TextView)findViewById(R.id.info); 94 95 mMediaListView = (ListView)findViewById(R.id.media); 96 mMediaListView.setAdapter(mMediaItems); 97 mMediaListView.setChoiceMode(ListView.CHOICE_MODE_SINGLE); 98 mMediaListView.setOnItemClickListener(new OnItemClickListener() { 99 @Override 100 public void onItemClick(AdapterView<?> parent, View view, int position, long id) { 101 updateButtons(); 102 } 103 }); 104 105 mPlayButton = (Button)findViewById(R.id.play_button); 106 mPlayButton.setOnClickListener(new OnClickListener() { 107 @Override 108 public void onClick(View v) { 109 play(); 110 } 111 }); 112 113 mStatisticsButton = (Button)findViewById(R.id.statistics_button); 114 mStatisticsButton.setOnClickListener(new OnClickListener() { 115 @Override 116 public void onClick(View v) { 117 showStatistics(); 118 } 119 }); 120 } 121 122 @Override 123 protected void onResume() { 124 // Be sure to call the super class. 125 super.onResume(); 126 127 // Listen for changes to media routes. 128 mMediaRouter.addCallback(mSelector, mCallback, 129 MediaRouter.CALLBACK_FLAG_UNFILTERED_EVENTS); 130 updateRouteStatus(); 131 } 132 133 @Override 134 protected void onPause() { 135 // Be sure to call the super class. 136 super.onPause(); 137 138 // Stop listening for changes to media routes. 139 mMediaRouter.removeCallback(mCallback); 140 } 141 142 @Override 143 public boolean onCreateOptionsMenu(Menu menu) { 144 // Be sure to call the super class. 145 super.onCreateOptionsMenu(menu); 146 147 // Inflate the menu and configure the media router action provider. 148 getMenuInflater().inflate(R.menu.sample_media_router_menu, menu); 149 150 MenuItem mediaRouteMenuItem = menu.findItem(R.id.media_route_menu_item); 151 MediaRouteActionProvider mediaRouteActionProvider = 152 (MediaRouteActionProvider)MenuItemCompat.getActionProvider(mediaRouteMenuItem); 153 mediaRouteActionProvider.setRouteSelector(mSelector); 154 155 // Return true to show the menu. 156 return true; 157 } 158 159 private void updateRouteStatus() { 160 RouteInfo route = mMediaRouter.getSelectedRoute(); 161 mInfoTextView.setText("Currently selected route: " + route.getName() 162 + " from provider " + route.getProvider().getPackageName() 163 + ", status: " + route.getStatus()); 164 updateButtons(); 165 } 166 167 private void updateButtons() { 168 MediaRouter.RouteInfo route = mMediaRouter.getSelectedRoute(); 169 170 MediaItem item = getCheckedMediaItem(); 171 if (item != null) { 172 mPlayButton.setEnabled(route.supportsControlRequest(makePlayIntent(item))); 173 } else { 174 mPlayButton.setEnabled(false); 175 } 176 177 mStatisticsButton.setEnabled(route.supportsControlRequest(makeStatisticsIntent())); 178 } 179 180 private void play() { 181 final MediaItem item = getCheckedMediaItem(); 182 if (item == null) { 183 return; 184 } 185 186 MediaRouter.RouteInfo route = mMediaRouter.getSelectedRoute(); 187 Intent intent = makePlayIntent(item); 188 if (route.supportsControlRequest(intent)) { 189 MediaRouter.ControlRequestCallback callback = 190 new MediaRouter.ControlRequestCallback() { 191 @Override 192 public void onResult(int result, Bundle data) { 193 switch (result) { 194 case REQUEST_SUCCEEDED: { 195 String streamId = data != null ? data.getString( 196 MediaControlIntent.EXTRA_ITEM_ID) : null; 197 198 Log.d(TAG, "Play request succeeded: streamId=" + streamId); 199 Toast.makeText(SampleMediaRouterActivity.this, 200 "Now playing " + item.mName, 201 Toast.LENGTH_LONG).show(); 202 break; 203 } 204 205 case REQUEST_FAILED: 206 Log.d(TAG, "Play request failed."); 207 Toast.makeText(SampleMediaRouterActivity.this, 208 "Unable to play " + item.mName, 209 Toast.LENGTH_LONG).show(); 210 break; 211 } 212 } 213 }; 214 215 Log.d(TAG, "Sending play request: intent=" + intent); 216 route.sendControlRequest(intent, callback); 217 } else { 218 Log.d(TAG, "Play request not supported: intent=" + intent); 219 Toast.makeText(SampleMediaRouterActivity.this, 220 "Play not supported for " + item.mName, Toast.LENGTH_LONG).show(); 221 } 222 } 223 224 private void showStatistics() { 225 MediaRouter.RouteInfo route = mMediaRouter.getSelectedRoute(); 226 Intent intent = makeStatisticsIntent(); 227 if (route.supportsControlRequest(intent)) { 228 MediaRouter.ControlRequestCallback callback = new MediaRouter.ControlRequestCallback() { 229 @Override 230 public void onResult(int result, Bundle data) { 231 switch (result) { 232 case REQUEST_SUCCEEDED: 233 Log.d(TAG, "Statistics request succeeded: data=" + data); 234 if (data != null) { 235 int playbackCount = data.getInt( 236 SampleMediaRouteProvider.DATA_PLAYBACK_COUNT, -1); 237 Toast.makeText(SampleMediaRouterActivity.this, 238 "Total playback count: " + playbackCount, 239 Toast.LENGTH_LONG).show(); 240 } else { 241 Toast.makeText(SampleMediaRouterActivity.this, 242 "Statistics query did not return any data", 243 Toast.LENGTH_LONG).show(); 244 } 245 break; 246 247 case REQUEST_FAILED: 248 Log.d(TAG, "Statistics request failed: data=" + data); 249 Toast.makeText(SampleMediaRouterActivity.this, 250 "Unable to query statistics.", 251 Toast.LENGTH_LONG).show(); 252 break; 253 } 254 } 255 }; 256 257 Log.d(TAG, "Sent statistics request: intent=" + intent); 258 route.sendControlRequest(intent, callback); 259 } else { 260 Log.d(TAG, "Statistics request not supported: intent=" + intent); 261 Toast.makeText(SampleMediaRouterActivity.this, 262 "Statistics not supported.", Toast.LENGTH_LONG).show(); 263 } 264 } 265 266 private Intent makePlayIntent(MediaItem item) { 267 Intent intent = new Intent(MediaControlIntent.ACTION_PLAY); 268 intent.addCategory(MediaControlIntent.CATEGORY_REMOTE_PLAYBACK); 269 intent.setDataAndType(item.mUri, "video/mp4"); 270 return intent; 271 } 272 273 private Intent makeStatisticsIntent() { 274 Intent intent = new Intent(SampleMediaRouteProvider.ACTION_GET_STATISTICS); 275 intent.addCategory(SampleMediaRouteProvider.CATEGORY_SAMPLE_ROUTE); 276 return intent; 277 } 278 279 private MediaItem getCheckedMediaItem() { 280 int index = mMediaListView.getCheckedItemPosition(); 281 if (index >= 0 && index < mMediaItems.getCount()) { 282 return mMediaItems.getItem(index); 283 } 284 return null; 285 } 286 287 private final MediaRouter.Callback mCallback = new MediaRouter.Callback() { 288 @Override 289 public void onRouteAdded(MediaRouter router, RouteInfo route) { 290 Log.d(TAG, "onRouteAdded: route=" + route); 291 } 292 293 @Override 294 public void onRouteChanged(MediaRouter router, RouteInfo route) { 295 Log.d(TAG, "onRouteChanged: route=" + route); 296 updateRouteStatus(); 297 } 298 299 @Override 300 public void onRouteRemoved(MediaRouter router, RouteInfo route) { 301 Log.d(TAG, "onRouteRemoved: route=" + route); 302 } 303 304 @Override 305 public void onRouteSelected(MediaRouter router, RouteInfo route) { 306 Log.d(TAG, "onRouteSelected: route=" + route); 307 updateRouteStatus(); 308 } 309 310 @Override 311 public void onRouteUnselected(MediaRouter router, RouteInfo route) { 312 Log.d(TAG, "onRouteUnselected: route=" + route); 313 updateRouteStatus(); 314 } 315 316 @Override 317 public void onRouteVolumeChanged(MediaRouter router, RouteInfo route) { 318 Log.d(TAG, "onRouteVolumeChanged: route=" + route); 319 } 320 321 @Override 322 public void onRoutePresentationDisplayChanged(MediaRouter router, RouteInfo route) { 323 Log.d(TAG, "onRoutePresentationDisplayChanged: route=" + route); 324 } 325 326 @Override 327 public void onProviderAdded(MediaRouter router, ProviderInfo provider) { 328 Log.d(TAG, "onRouteProviderAdded: provider=" + provider); 329 } 330 331 @Override 332 public void onProviderRemoved(MediaRouter router, ProviderInfo provider) { 333 Log.d(TAG, "onRouteProviderRemoved: provider=" + provider); 334 } 335 336 @Override 337 public void onProviderChanged(MediaRouter router, ProviderInfo provider) { 338 Log.d(TAG, "onRouteProviderChanged: provider=" + provider); 339 } 340 }; 341 342 private static final class MediaItem { 343 public final String mName; 344 public final Uri mUri; 345 346 public MediaItem(String name, Uri uri) { 347 mName = name; 348 mUri = uri; 349 } 350 351 @Override 352 public String toString() { 353 return mName; 354 } 355 } 356 357 /** 358 * Trivial subclass of this activity used to provide another copy of the 359 * same activity using a light theme instead of the dark theme. 360 */ 361 public static class Light extends SampleMediaRouterActivity { 362 } 363 364 /** 365 * Trivial subclass of this activity used to provide another copy of the 366 * same activity using a light theme with dark action bar instead of the dark theme. 367 */ 368 public static class LightWithDarkActionBar extends SampleMediaRouterActivity { 369 } 370} 371