PageRenderTime 58ms CodeModel.GetById 24ms RepoModel.GetById 0ms app.codeStats 1ms

/sdk/extras/android/support/samples/Support7Demos/src/com/example/android/supportv7/media/SampleMediaRouterActivity.java

https://bitbucket.org/rimmer/android_tools
Java | 774 lines | 614 code | 96 blank | 64 comment | 72 complexity | 173c309326704b56dc1a1b39cc8a71c3 MD5 | raw file
Possible License(s): Apache-2.0, GPL-2.0, BSD-3-Clause
  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. package com.example.android.supportv7.media;
  17. import com.example.android.supportv7.R;
  18. import android.app.PendingIntent;
  19. import android.content.ComponentName;
  20. import android.content.Context;
  21. import android.content.DialogInterface;
  22. import android.content.Intent;
  23. import android.media.AudioManager;
  24. import android.media.AudioManager.OnAudioFocusChangeListener;
  25. import android.net.Uri;
  26. import android.os.Bundle;
  27. import android.os.Environment;
  28. import android.os.Handler;
  29. import android.os.SystemClock;
  30. import android.support.v4.app.FragmentManager;
  31. import android.support.v4.media.session.MediaSessionCompat;
  32. import android.support.v4.view.MenuItemCompat;
  33. import android.support.v7.app.AppCompatActivity;
  34. import android.support.v7.app.MediaRouteActionProvider;
  35. import android.support.v7.app.MediaRouteControllerDialog;
  36. import android.support.v7.app.MediaRouteControllerDialogFragment;
  37. import android.support.v7.app.MediaRouteDialogFactory;
  38. import android.support.v7.app.MediaRouteDiscoveryFragment;
  39. import android.support.v7.media.MediaControlIntent;
  40. import android.support.v7.media.MediaItemStatus;
  41. import android.support.v7.media.MediaRouteSelector;
  42. import android.support.v7.media.MediaRouter;
  43. import android.support.v7.media.MediaRouter.Callback;
  44. import android.support.v7.media.MediaRouter.ProviderInfo;
  45. import android.support.v7.media.MediaRouter.RouteInfo;
  46. import android.util.Log;
  47. import android.view.KeyEvent;
  48. import android.view.Menu;
  49. import android.view.MenuItem;
  50. import android.view.View;
  51. import android.view.View.OnClickListener;
  52. import android.view.ViewGroup;
  53. import android.widget.AdapterView;
  54. import android.widget.AdapterView.OnItemClickListener;
  55. import android.widget.ArrayAdapter;
  56. import android.widget.CheckBox;
  57. import android.widget.ImageButton;
  58. import android.widget.ListView;
  59. import android.widget.SeekBar;
  60. import android.widget.SeekBar.OnSeekBarChangeListener;
  61. import android.widget.TabHost;
  62. import android.widget.TabHost.OnTabChangeListener;
  63. import android.widget.TabHost.TabSpec;
  64. import android.widget.TextView;
  65. import java.io.File;
  66. /**
  67. * <h3>Media Router Support Activity</h3>
  68. *
  69. * <p>
  70. * This demonstrates how to use the {@link MediaRouter} API to build an
  71. * application that allows the user to send content to various rendering
  72. * targets.
  73. * </p>
  74. */
  75. public class SampleMediaRouterActivity extends AppCompatActivity {
  76. private static final String TAG = "SampleMediaRouterActivity";
  77. private static final String DISCOVERY_FRAGMENT_TAG = "DiscoveryFragment";
  78. private static final boolean ENABLE_DEFAULT_CONTROL_CHECK_BOX = false;
  79. private MediaRouter mMediaRouter;
  80. private MediaRouteSelector mSelector;
  81. private LibraryAdapter mLibraryItems;
  82. private PlaylistAdapter mPlayListItems;
  83. private TextView mInfoTextView;
  84. private ListView mLibraryView;
  85. private ListView mPlayListView;
  86. private CheckBox mUseDefaultControlCheckBox;
  87. private ImageButton mPauseResumeButton;
  88. private ImageButton mStopButton;
  89. private SeekBar mSeekBar;
  90. private boolean mNeedResume;
  91. private boolean mSeeking;
  92. private final Handler mHandler = new Handler();
  93. private final Runnable mUpdateSeekRunnable = new Runnable() {
  94. @Override
  95. public void run() {
  96. updateProgress();
  97. // update Ui every 1 second
  98. mHandler.postDelayed(this, 1000);
  99. }
  100. };
  101. private final SessionManager mSessionManager = new SessionManager("app");
  102. private Player mPlayer;
  103. private final MediaRouter.Callback mMediaRouterCB = new MediaRouter.Callback() {
  104. // Return a custom callback that will simply log all of the route events
  105. // for demonstration purposes.
  106. @Override
  107. public void onRouteAdded(MediaRouter router, RouteInfo route) {
  108. Log.d(TAG, "onRouteAdded: route=" + route);
  109. }
  110. @Override
  111. public void onRouteChanged(MediaRouter router, RouteInfo route) {
  112. Log.d(TAG, "onRouteChanged: route=" + route);
  113. }
  114. @Override
  115. public void onRouteRemoved(MediaRouter router, RouteInfo route) {
  116. Log.d(TAG, "onRouteRemoved: route=" + route);
  117. }
  118. @Override
  119. public void onRouteSelected(MediaRouter router, RouteInfo route) {
  120. Log.d(TAG, "onRouteSelected: route=" + route);
  121. mPlayer = Player.create(SampleMediaRouterActivity.this, route, mMediaSession);
  122. mPlayer.updatePresentation();
  123. mSessionManager.setPlayer(mPlayer);
  124. mSessionManager.unsuspend();
  125. updateUi();
  126. }
  127. @Override
  128. public void onRouteUnselected(MediaRouter router, RouteInfo route) {
  129. Log.d(TAG, "onRouteUnselected: route=" + route);
  130. mMediaSession.setActive(false);
  131. PlaylistItem item = getCheckedPlaylistItem();
  132. if (item != null) {
  133. long pos = item.getPosition() + (mSessionManager.isPaused() ?
  134. 0 : (SystemClock.elapsedRealtime() - item.getTimestamp()));
  135. mSessionManager.suspend(pos);
  136. }
  137. mPlayer.updatePresentation();
  138. mPlayer.release();
  139. }
  140. @Override
  141. public void onRouteVolumeChanged(MediaRouter router, RouteInfo route) {
  142. Log.d(TAG, "onRouteVolumeChanged: route=" + route);
  143. }
  144. @Override
  145. public void onRoutePresentationDisplayChanged(
  146. MediaRouter router, RouteInfo route) {
  147. Log.d(TAG, "onRoutePresentationDisplayChanged: route=" + route);
  148. mPlayer.updatePresentation();
  149. }
  150. @Override
  151. public void onProviderAdded(MediaRouter router, ProviderInfo provider) {
  152. Log.d(TAG, "onRouteProviderAdded: provider=" + provider);
  153. }
  154. @Override
  155. public void onProviderRemoved(MediaRouter router, ProviderInfo provider) {
  156. Log.d(TAG, "onRouteProviderRemoved: provider=" + provider);
  157. }
  158. @Override
  159. public void onProviderChanged(MediaRouter router, ProviderInfo provider) {
  160. Log.d(TAG, "onRouteProviderChanged: provider=" + provider);
  161. }
  162. };
  163. private MediaSessionCompat mMediaSession;
  164. private ComponentName mEventReceiver;
  165. private AudioManager mAudioManager;
  166. private PendingIntent mMediaPendingIntent;
  167. private final OnAudioFocusChangeListener mAfChangeListener =
  168. new OnAudioFocusChangeListener() {
  169. @Override
  170. public void onAudioFocusChange(int focusChange) {
  171. if (focusChange == AudioManager.AUDIOFOCUS_LOSS_TRANSIENT) {
  172. Log.d(TAG, "onAudioFocusChange: LOSS_TRANSIENT");
  173. } else if (focusChange == AudioManager.AUDIOFOCUS_GAIN) {
  174. Log.d(TAG, "onAudioFocusChange: AUDIOFOCUS_GAIN");
  175. } else if (focusChange == AudioManager.AUDIOFOCUS_LOSS) {
  176. Log.d(TAG, "onAudioFocusChange: AUDIOFOCUS_LOSS");
  177. }
  178. }
  179. };
  180. @Override
  181. protected void onCreate(Bundle savedInstanceState) {
  182. // Be sure to call the super class.
  183. super.onCreate(savedInstanceState);
  184. // Get the media router service.
  185. mMediaRouter = MediaRouter.getInstance(this);
  186. // Create a route selector for the type of routes that we care about.
  187. mSelector = new MediaRouteSelector.Builder()
  188. .addControlCategory(MediaControlIntent.CATEGORY_LIVE_AUDIO)
  189. .addControlCategory(MediaControlIntent.CATEGORY_LIVE_VIDEO)
  190. .addControlCategory(MediaControlIntent.CATEGORY_REMOTE_PLAYBACK)
  191. .addControlCategory(SampleMediaRouteProvider.CATEGORY_SAMPLE_ROUTE)
  192. .build();
  193. // Add a fragment to take care of media route discovery.
  194. // This fragment automatically adds or removes a callback whenever the activity
  195. // is started or stopped.
  196. FragmentManager fm = getSupportFragmentManager();
  197. DiscoveryFragment fragment = (DiscoveryFragment)fm.findFragmentByTag(
  198. DISCOVERY_FRAGMENT_TAG);
  199. if (fragment == null) {
  200. fragment = new DiscoveryFragment(mMediaRouterCB);
  201. fragment.setRouteSelector(mSelector);
  202. fm.beginTransaction()
  203. .add(fragment, DISCOVERY_FRAGMENT_TAG)
  204. .commit();
  205. } else {
  206. fragment.setCallback(mMediaRouterCB);
  207. fragment.setRouteSelector(mSelector);
  208. }
  209. // Populate an array adapter with streaming media items.
  210. String[] mediaNames = getResources().getStringArray(R.array.media_names);
  211. String[] mediaUris = getResources().getStringArray(R.array.media_uris);
  212. mLibraryItems = new LibraryAdapter();
  213. for (int i = 0; i < mediaNames.length; i++) {
  214. mLibraryItems.add(new MediaItem(
  215. "[streaming] "+mediaNames[i], Uri.parse(mediaUris[i]), "video/mp4"));
  216. }
  217. // Scan local external storage directory for media files.
  218. File externalDir = Environment.getExternalStorageDirectory();
  219. if (externalDir != null) {
  220. File list[] = externalDir.listFiles();
  221. if (list != null) {
  222. for (int i = 0; i < list.length; i++) {
  223. String filename = list[i].getName();
  224. if (filename.matches(".*\\.(m4v|mp4)")) {
  225. mLibraryItems.add(new MediaItem("[local] " + filename,
  226. Uri.fromFile(list[i]), "video/mp4"));
  227. }
  228. }
  229. }
  230. }
  231. mPlayListItems = new PlaylistAdapter();
  232. // Initialize the layout.
  233. setContentView(R.layout.sample_media_router);
  234. TabHost tabHost=(TabHost)findViewById(R.id.tabHost);
  235. tabHost.setup();
  236. String tabName = getResources().getString(R.string.library_tab_text);
  237. TabSpec spec1=tabHost.newTabSpec(tabName);
  238. spec1.setContent(R.id.tab1);
  239. spec1.setIndicator(tabName);
  240. tabName = getResources().getString(R.string.playlist_tab_text);
  241. TabSpec spec2=tabHost.newTabSpec(tabName);
  242. spec2.setIndicator(tabName);
  243. spec2.setContent(R.id.tab2);
  244. tabName = getResources().getString(R.string.info_tab_text);
  245. TabSpec spec3=tabHost.newTabSpec(tabName);
  246. spec3.setIndicator(tabName);
  247. spec3.setContent(R.id.tab3);
  248. tabHost.addTab(spec1);
  249. tabHost.addTab(spec2);
  250. tabHost.addTab(spec3);
  251. tabHost.setOnTabChangedListener(new OnTabChangeListener() {
  252. @Override
  253. public void onTabChanged(String arg0) {
  254. updateUi();
  255. }
  256. });
  257. mLibraryView = (ListView) findViewById(R.id.media);
  258. mLibraryView.setAdapter(mLibraryItems);
  259. mLibraryView.setChoiceMode(ListView.CHOICE_MODE_SINGLE);
  260. mLibraryView.setOnItemClickListener(new OnItemClickListener() {
  261. @Override
  262. public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
  263. updateButtons();
  264. }
  265. });
  266. mPlayListView = (ListView) findViewById(R.id.playlist);
  267. mPlayListView.setAdapter(mPlayListItems);
  268. mPlayListView.setChoiceMode(ListView.CHOICE_MODE_SINGLE);
  269. mPlayListView.setOnItemClickListener(new OnItemClickListener() {
  270. @Override
  271. public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
  272. updateButtons();
  273. }
  274. });
  275. mInfoTextView = (TextView) findViewById(R.id.info);
  276. mUseDefaultControlCheckBox = (CheckBox) findViewById(R.id.custom_control_view_checkbox);
  277. if (ENABLE_DEFAULT_CONTROL_CHECK_BOX) {
  278. mUseDefaultControlCheckBox.setVisibility(View.VISIBLE);
  279. }
  280. mPauseResumeButton = (ImageButton)findViewById(R.id.pause_resume_button);
  281. mPauseResumeButton.setOnClickListener(new OnClickListener() {
  282. @Override
  283. public void onClick(View v) {
  284. if (mSessionManager.isPaused()) {
  285. mSessionManager.resume();
  286. } else {
  287. mSessionManager.pause();
  288. }
  289. }
  290. });
  291. mStopButton = (ImageButton)findViewById(R.id.stop_button);
  292. mStopButton.setOnClickListener(new OnClickListener() {
  293. @Override
  294. public void onClick(View v) {
  295. mSessionManager.stop();
  296. }
  297. });
  298. mSeekBar = (SeekBar) findViewById(R.id.seekbar);
  299. mSeekBar.setOnSeekBarChangeListener(new OnSeekBarChangeListener() {
  300. @Override
  301. public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
  302. PlaylistItem item = getCheckedPlaylistItem();
  303. if (fromUser && item != null && item.getDuration() > 0) {
  304. long pos = progress * item.getDuration() / 100;
  305. mSessionManager.seek(item.getItemId(), pos);
  306. item.setPosition(pos);
  307. item.setTimestamp(SystemClock.elapsedRealtime());
  308. }
  309. }
  310. @Override
  311. public void onStartTrackingTouch(SeekBar seekBar) {
  312. mSeeking = true;
  313. }
  314. @Override
  315. public void onStopTrackingTouch(SeekBar seekBar) {
  316. mSeeking = false;
  317. updateUi();
  318. }
  319. });
  320. // Schedule Ui update
  321. mHandler.postDelayed(mUpdateSeekRunnable, 1000);
  322. // Build the PendingIntent for the remote control client
  323. mAudioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
  324. mEventReceiver = new ComponentName(getPackageName(),
  325. SampleMediaButtonReceiver.class.getName());
  326. Intent mediaButtonIntent = new Intent(Intent.ACTION_MEDIA_BUTTON);
  327. mediaButtonIntent.setComponent(mEventReceiver);
  328. mMediaPendingIntent = PendingIntent.getBroadcast(this, 0, mediaButtonIntent, 0);
  329. // Create and register the remote control client
  330. createMediaSession();
  331. mMediaRouter.setMediaSessionCompat(mMediaSession);
  332. // Set up playback manager and player
  333. mPlayer = Player.create(SampleMediaRouterActivity.this,
  334. mMediaRouter.getSelectedRoute(), mMediaSession);
  335. mSessionManager.setPlayer(mPlayer);
  336. mSessionManager.setCallback(new SessionManager.Callback() {
  337. @Override
  338. public void onStatusChanged() {
  339. updateUi();
  340. }
  341. @Override
  342. public void onItemChanged(PlaylistItem item) {
  343. }
  344. });
  345. updateUi();
  346. }
  347. private void createMediaSession() {
  348. // Create the MediaSession
  349. mMediaSession = new MediaSessionCompat(this, "SampleMediaRouter", mEventReceiver,
  350. mMediaPendingIntent);
  351. mMediaSession.setFlags(MediaSessionCompat.FLAG_HANDLES_MEDIA_BUTTONS
  352. | MediaSessionCompat.FLAG_HANDLES_TRANSPORT_CONTROLS);
  353. mMediaSession.setCallback(new MediaSessionCompat.Callback() {
  354. @Override
  355. public boolean onMediaButtonEvent(Intent mediaButtonEvent) {
  356. if (mediaButtonEvent != null) {
  357. return handleMediaKey(
  358. (KeyEvent) mediaButtonEvent.getParcelableExtra(Intent.EXTRA_KEY_EVENT));
  359. }
  360. return super.onMediaButtonEvent(mediaButtonEvent);
  361. }
  362. @Override
  363. public void onPlay() {
  364. mSessionManager.resume();
  365. }
  366. @Override
  367. public void onPause() {
  368. mSessionManager.pause();
  369. }
  370. });
  371. SampleMediaButtonReceiver.setActivity(SampleMediaRouterActivity.this);
  372. }
  373. public boolean handleMediaKey(KeyEvent event) {
  374. if (event != null && event.getAction() == KeyEvent.ACTION_DOWN
  375. && event.getRepeatCount() == 0) {
  376. switch (event.getKeyCode()) {
  377. case KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE:
  378. case KeyEvent.KEYCODE_HEADSETHOOK:
  379. {
  380. Log.d(TAG, "Received Play/Pause event from RemoteControlClient");
  381. if (mSessionManager.isPaused()) {
  382. mSessionManager.resume();
  383. } else {
  384. mSessionManager.pause();
  385. }
  386. return true;
  387. }
  388. case KeyEvent.KEYCODE_MEDIA_PLAY:
  389. {
  390. Log.d(TAG, "Received Play event from RemoteControlClient");
  391. if (mSessionManager.isPaused()) {
  392. mSessionManager.resume();
  393. }
  394. return true;
  395. }
  396. case KeyEvent.KEYCODE_MEDIA_PAUSE:
  397. {
  398. Log.d(TAG, "Received Pause event from RemoteControlClient");
  399. if (!mSessionManager.isPaused()) {
  400. mSessionManager.pause();
  401. }
  402. return true;
  403. }
  404. case KeyEvent.KEYCODE_MEDIA_STOP:
  405. {
  406. Log.d(TAG, "Received Stop event from RemoteControlClient");
  407. mSessionManager.stop();
  408. return true;
  409. }
  410. default:
  411. break;
  412. }
  413. }
  414. return false;
  415. }
  416. @Override
  417. public boolean onKeyDown(int keyCode, KeyEvent event) {
  418. return handleMediaKey(event) || super.onKeyDown(keyCode, event);
  419. }
  420. @Override
  421. public boolean onKeyUp(int keyCode, KeyEvent event) {
  422. return handleMediaKey(event) || super.onKeyUp(keyCode, event);
  423. }
  424. @Override
  425. public void onStart() {
  426. // Be sure to call the super class.
  427. super.onStart();
  428. }
  429. @Override
  430. public void onPause() {
  431. // pause media player for local playback case only
  432. if (!mPlayer.isRemotePlayback() && !mSessionManager.isPaused()) {
  433. mNeedResume = true;
  434. mSessionManager.pause();
  435. }
  436. super.onPause();
  437. }
  438. @Override
  439. public void onResume() {
  440. // resume media player for local playback case only
  441. if (!mPlayer.isRemotePlayback() && mNeedResume) {
  442. mSessionManager.resume();
  443. mNeedResume = false;
  444. }
  445. super.onResume();
  446. }
  447. @Override
  448. public void onDestroy() {
  449. mSessionManager.stop();
  450. mPlayer.release();
  451. mMediaSession.release();
  452. super.onDestroy();
  453. }
  454. @Override
  455. public boolean onCreateOptionsMenu(Menu menu) {
  456. // Be sure to call the super class.
  457. super.onCreateOptionsMenu(menu);
  458. // Inflate the menu and configure the media router action provider.
  459. getMenuInflater().inflate(R.menu.sample_media_router_menu, menu);
  460. MenuItem mediaRouteMenuItem = menu.findItem(R.id.media_route_menu_item);
  461. MediaRouteActionProvider mediaRouteActionProvider =
  462. (MediaRouteActionProvider)MenuItemCompat.getActionProvider(mediaRouteMenuItem);
  463. mediaRouteActionProvider.setRouteSelector(mSelector);
  464. mediaRouteActionProvider.setDialogFactory(new MediaRouteDialogFactory() {
  465. @Override
  466. public MediaRouteControllerDialogFragment onCreateControllerDialogFragment() {
  467. return new ControllerDialogFragment(mPlayer, mUseDefaultControlCheckBox);
  468. }
  469. });
  470. // Return true to show the menu.
  471. return true;
  472. }
  473. private void updateProgress() {
  474. // Estimate content position from last status time and elapsed time.
  475. // (Note this might be slightly out of sync with remote side, however
  476. // it avoids frequent polling the MRP.)
  477. int progress = 0;
  478. PlaylistItem item = getCheckedPlaylistItem();
  479. if (item != null) {
  480. int state = item.getState();
  481. long duration = item.getDuration();
  482. if (duration <= 0) {
  483. if (state == MediaItemStatus.PLAYBACK_STATE_PLAYING
  484. || state == MediaItemStatus.PLAYBACK_STATE_PAUSED) {
  485. mSessionManager.updateStatus();
  486. }
  487. } else {
  488. long position = item.getPosition();
  489. long timeDelta = mSessionManager.isPaused() ? 0 :
  490. (SystemClock.elapsedRealtime() - item.getTimestamp());
  491. progress = (int)(100.0 * (position + timeDelta) / duration);
  492. }
  493. }
  494. mSeekBar.setProgress(progress);
  495. }
  496. private void updateUi() {
  497. updatePlaylist();
  498. updateRouteDescription();
  499. updateButtons();
  500. if (mPlayer != null) {
  501. mPlayer.updateMetadata();
  502. }
  503. }
  504. private void updatePlaylist() {
  505. mPlayListItems.clear();
  506. for (PlaylistItem item : mSessionManager.getPlaylist()) {
  507. mPlayListItems.add(item);
  508. }
  509. mPlayListView.invalidate();
  510. }
  511. private void updateRouteDescription() {
  512. RouteInfo route = mMediaRouter.getSelectedRoute();
  513. mInfoTextView.setText("Currently selected route:"
  514. + "\nName: " + route.getName()
  515. + "\nProvider: " + route.getProvider().getPackageName()
  516. + "\nDescription: " + route.getDescription());
  517. }
  518. private void updateButtons() {
  519. MediaRouter.RouteInfo route = mMediaRouter.getSelectedRoute();
  520. // show pause or resume icon depending on current state
  521. mPauseResumeButton.setImageResource(mSessionManager.isPaused() ?
  522. R.drawable.ic_media_play : R.drawable.ic_media_pause);
  523. // only enable seek bar when duration is known
  524. PlaylistItem item = getCheckedPlaylistItem();
  525. mSeekBar.setEnabled(item != null && item.getDuration() > 0);
  526. }
  527. private PlaylistItem getCheckedPlaylistItem() {
  528. int count = mPlayListView.getCount();
  529. int index = mPlayListView.getCheckedItemPosition();
  530. if (count > 0) {
  531. if (index < 0 || index >= count) {
  532. index = 0;
  533. mPlayListView.setItemChecked(0, true);
  534. }
  535. return mPlayListItems.getItem(index);
  536. }
  537. return null;
  538. }
  539. public static final class DiscoveryFragment extends MediaRouteDiscoveryFragment {
  540. private static final String TAG = "DiscoveryFragment";
  541. private Callback mCallback;
  542. public DiscoveryFragment() {
  543. mCallback = null;
  544. }
  545. public DiscoveryFragment(Callback cb) {
  546. mCallback = cb;
  547. }
  548. public void setCallback(Callback cb) {
  549. mCallback = cb;
  550. }
  551. @Override
  552. public Callback onCreateCallback() {
  553. return mCallback;
  554. }
  555. @Override
  556. public int onPrepareCallbackFlags() {
  557. // Add the CALLBACK_FLAG_UNFILTERED_EVENTS flag to ensure that we will
  558. // observe and log all route events including those that are for routes
  559. // that do not match our selector. This is only for demonstration purposes
  560. // and should not be needed by most applications.
  561. return super.onPrepareCallbackFlags()
  562. | MediaRouter.CALLBACK_FLAG_UNFILTERED_EVENTS;
  563. }
  564. }
  565. private static final class MediaItem {
  566. public final String mName;
  567. public final Uri mUri;
  568. public final String mMime;
  569. public MediaItem(String name, Uri uri, String mime) {
  570. mName = name;
  571. mUri = uri;
  572. mMime = mime;
  573. }
  574. @Override
  575. public String toString() {
  576. return mName;
  577. }
  578. }
  579. private final class LibraryAdapter extends ArrayAdapter<MediaItem> {
  580. public LibraryAdapter() {
  581. super(SampleMediaRouterActivity.this, R.layout.media_item);
  582. }
  583. @Override
  584. public View getView(int position, View convertView, ViewGroup parent) {
  585. final View v;
  586. if (convertView == null) {
  587. v = getLayoutInflater().inflate(R.layout.media_item, null);
  588. } else {
  589. v = convertView;
  590. }
  591. final MediaItem item = getItem(position);
  592. TextView tv = (TextView)v.findViewById(R.id.item_text);
  593. tv.setText(item.mName);
  594. ImageButton b = (ImageButton)v.findViewById(R.id.item_action);
  595. b.setImageResource(R.drawable.ic_menu_add);
  596. b.setTag(item);
  597. b.setOnClickListener(new OnClickListener() {
  598. @Override
  599. public void onClick(View v) {
  600. if (item != null) {
  601. mSessionManager.add(item.mUri, item.mMime);
  602. }
  603. }
  604. });
  605. return v;
  606. }
  607. }
  608. private final class PlaylistAdapter extends ArrayAdapter<PlaylistItem> {
  609. public PlaylistAdapter() {
  610. super(SampleMediaRouterActivity.this, R.layout.media_item);
  611. }
  612. @Override
  613. public View getView(int position, View convertView, ViewGroup parent) {
  614. final View v;
  615. if (convertView == null) {
  616. v = getLayoutInflater().inflate(R.layout.media_item, null);
  617. } else {
  618. v = convertView;
  619. }
  620. final PlaylistItem item = getItem(position);
  621. TextView tv = (TextView)v.findViewById(R.id.item_text);
  622. tv.setText(item.toString());
  623. ImageButton b = (ImageButton)v.findViewById(R.id.item_action);
  624. b.setImageResource(R.drawable.ic_menu_delete);
  625. b.setTag(item);
  626. b.setOnClickListener(new OnClickListener() {
  627. @Override
  628. public void onClick(View v) {
  629. if (item != null) {
  630. mSessionManager.remove(item.getItemId());
  631. }
  632. }
  633. });
  634. return v;
  635. }
  636. }
  637. /**
  638. * Trivial subclass of this activity used to provide another copy of the
  639. * same activity using a light theme instead of the dark theme.
  640. */
  641. public static class Light extends SampleMediaRouterActivity {
  642. }
  643. /**
  644. * Trivial subclass of this activity used to provide another copy of the
  645. * same activity using a light theme with dark action bar instead of the dark theme.
  646. */
  647. public static class LightWithDarkActionBar extends SampleMediaRouterActivity {
  648. }
  649. public static class ControllerDialogFragment extends MediaRouteControllerDialogFragment {
  650. private MediaRouteControllerDialog mControllerDialog;
  651. private Player mPlayer;
  652. private CheckBox mUseDefaultControlCheckBox;
  653. public ControllerDialogFragment() {
  654. super();
  655. }
  656. public ControllerDialogFragment(Player player, CheckBox customControlViewCheckBox) {
  657. mPlayer = player;
  658. this.mUseDefaultControlCheckBox = customControlViewCheckBox;
  659. }
  660. @Override
  661. public MediaRouteControllerDialog onCreateControllerDialog(
  662. Context context, Bundle savedInstanceState) {
  663. mControllerDialog = this.mUseDefaultControlCheckBox.isChecked()
  664. ? super.onCreateControllerDialog(context, savedInstanceState)
  665. : new MyMediaRouteControllerDialog(context);
  666. mControllerDialog.setOnDismissListener(new DialogInterface.OnDismissListener() {
  667. @Override
  668. public void onDismiss(DialogInterface dialog) {
  669. mControllerDialog = null;
  670. }
  671. });
  672. return mControllerDialog;
  673. }
  674. public void setPlayer(Player player) {
  675. mPlayer = player;
  676. }
  677. }
  678. }