SampleMediaRouterActivity.java revision 76d965dc41863b33f887db33d283cb7f1523f60d
1ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown/* 2ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown * Copyright (C) 2013 The Android Open Source Project 3ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown * 4ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown * Licensed under the Apache License, Version 2.0 (the "License"); 5ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown * you may not use this file except in compliance with the License. 6ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown * You may obtain a copy of the License at 7ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown * 8ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown * http://www.apache.org/licenses/LICENSE-2.0 9ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown * 10ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown * Unless required by applicable law or agreed to in writing, software 11ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown * distributed under the License is distributed on an "AS IS" BASIS, 12ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown * See the License for the specific language governing permissions and 14ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown * limitations under the License. 15ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown */ 16ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown 17ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brownpackage com.example.android.supportv7.media; 18ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown 19ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brownimport com.example.android.supportv7.R; 20ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown 2144d25261c2a38c81f1eea123de3986b453b9afeeChris Banesimport android.app.PendingIntent; 227578fad97dcd3b4b390652f37a30d805538980f5Chong Zhangimport android.content.ComponentName; 2357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhangimport android.content.Context; 245d429bc3a8195d6f37cf2f7da0935972950539b4RoboErikimport android.content.DialogInterface; 25ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brownimport android.content.Intent; 267578fad97dcd3b4b390652f37a30d805538980f5Chong Zhangimport android.media.AudioManager; 277578fad97dcd3b4b390652f37a30d805538980f5Chong Zhangimport android.media.AudioManager.OnAudioFocusChangeListener; 28ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brownimport android.net.Uri; 2944d25261c2a38c81f1eea123de3986b453b9afeeChris Banesimport android.os.Bundle; 3045ca8fb42505658590e808d4d30b57598689d9a8Jeff Brownimport android.os.Environment; 3157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhangimport android.os.Handler; 3257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhangimport android.os.SystemClock; 33f0dd451048100915f072423730a93d17c53fd899Jeff Brownimport android.support.v4.app.FragmentManager; 349a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErikimport android.support.v4.media.session.MediaSessionCompat; 3555e47d370890d3cbdab82857090c42df734ba276Jeff Brownimport android.support.v4.view.MenuItemCompat; 3644d25261c2a38c81f1eea123de3986b453b9afeeChris Banesimport android.support.v7.app.AppCompatActivity; 3755e47d370890d3cbdab82857090c42df734ba276Jeff Brownimport android.support.v7.app.MediaRouteActionProvider; 38cf61a6ed2bfa6141b832fdc40a9fbfb70af91416Chong Zhangimport android.support.v7.app.MediaRouteControllerDialog; 39cf61a6ed2bfa6141b832fdc40a9fbfb70af91416Chong Zhangimport android.support.v7.app.MediaRouteControllerDialogFragment; 40cf61a6ed2bfa6141b832fdc40a9fbfb70af91416Chong Zhangimport android.support.v7.app.MediaRouteDialogFactory; 4144d25261c2a38c81f1eea123de3986b453b9afeeChris Banesimport android.support.v7.app.MediaRouteDiscoveryFragment; 42ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brownimport android.support.v7.media.MediaControlIntent; 4344d25261c2a38c81f1eea123de3986b453b9afeeChris Banesimport android.support.v7.media.MediaItemStatus; 4444d25261c2a38c81f1eea123de3986b453b9afeeChris Banesimport android.support.v7.media.MediaRouteSelector; 45ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brownimport android.support.v7.media.MediaRouter; 46f0dd451048100915f072423730a93d17c53fd899Jeff Brownimport android.support.v7.media.MediaRouter.Callback; 47ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brownimport android.support.v7.media.MediaRouter.ProviderInfo; 4844d25261c2a38c81f1eea123de3986b453b9afeeChris Banesimport android.support.v7.media.MediaRouter.RouteInfo; 49ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brownimport android.util.Log; 507578fad97dcd3b4b390652f37a30d805538980f5Chong Zhangimport android.view.KeyEvent; 51ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brownimport android.view.Menu; 52ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brownimport android.view.MenuItem; 53ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brownimport android.view.View; 54ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brownimport android.view.View.OnClickListener; 5557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhangimport android.view.ViewGroup; 56ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brownimport android.widget.AdapterView; 5757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhangimport android.widget.AdapterView.OnItemClickListener; 58ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brownimport android.widget.ArrayAdapter; 5976d965dc41863b33f887db33d283cb7f1523f60dJae Seoimport android.widget.CheckBox; 6057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhangimport android.widget.ImageButton; 61ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brownimport android.widget.ListView; 6257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhangimport android.widget.SeekBar; 6357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhangimport android.widget.SeekBar.OnSeekBarChangeListener; 6444d25261c2a38c81f1eea123de3986b453b9afeeChris Banesimport android.widget.TabHost; 6544d25261c2a38c81f1eea123de3986b453b9afeeChris Banesimport android.widget.TabHost.OnTabChangeListener; 6644d25261c2a38c81f1eea123de3986b453b9afeeChris Banesimport android.widget.TabHost.TabSpec; 6744d25261c2a38c81f1eea123de3986b453b9afeeChris Banesimport android.widget.TextView; 685d429bc3a8195d6f37cf2f7da0935972950539b4RoboErik 6957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhangimport java.io.File; 70ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown 71ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown/** 72ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown * <h3>Media Router Support Activity</h3> 73ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown * 74ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown * <p> 75ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown * This demonstrates how to use the {@link MediaRouter} API to build an 76ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown * application that allows the user to send content to various rendering 77ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown * targets. 78ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown * </p> 79ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown */ 8044d25261c2a38c81f1eea123de3986b453b9afeeChris Banespublic class SampleMediaRouterActivity extends AppCompatActivity { 81a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang private static final String TAG = "SampleMediaRouterActivity"; 82f0dd451048100915f072423730a93d17c53fd899Jeff Brown private static final String DISCOVERY_FRAGMENT_TAG = "DiscoveryFragment"; 8376d965dc41863b33f887db33d283cb7f1523f60dJae Seo private static final boolean ENABLE_DEFAULT_CONTROL_CHECK_BOX = false; 84ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown 85ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown private MediaRouter mMediaRouter; 8655e47d370890d3cbdab82857090c42df734ba276Jeff Brown private MediaRouteSelector mSelector; 8757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang private LibraryAdapter mLibraryItems; 8857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang private PlaylistAdapter mPlayListItems; 89ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown private TextView mInfoTextView; 9057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang private ListView mLibraryView; 9157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang private ListView mPlayListView; 9276d965dc41863b33f887db33d283cb7f1523f60dJae Seo private CheckBox mUseDefaultControlCheckBox; 9357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang private ImageButton mPauseResumeButton; 9457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang private ImageButton mStopButton; 9557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang private SeekBar mSeekBar; 9657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang private boolean mNeedResume; 9757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang private boolean mSeeking; 9857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 9957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang private final Handler mHandler = new Handler(); 10057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang private final Runnable mUpdateSeekRunnable = new Runnable() { 10157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang @Override 10257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang public void run() { 103a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang updateProgress(); 10457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang // update Ui every 1 second 10557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang mHandler.postDelayed(this, 1000); 10657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 10757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang }; 10857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 109a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang private final SessionManager mSessionManager = new SessionManager("app"); 11057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang private Player mPlayer; 11157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 11257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang private final MediaRouter.Callback mMediaRouterCB = new MediaRouter.Callback() { 11357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang // Return a custom callback that will simply log all of the route events 11457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang // for demonstration purposes. 11557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang @Override 11657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang public void onRouteAdded(MediaRouter router, RouteInfo route) { 11757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang Log.d(TAG, "onRouteAdded: route=" + route); 11857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 11957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 12057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang @Override 12157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang public void onRouteChanged(MediaRouter router, RouteInfo route) { 12257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang Log.d(TAG, "onRouteChanged: route=" + route); 12357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 12457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 12557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang @Override 12657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang public void onRouteRemoved(MediaRouter router, RouteInfo route) { 12757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang Log.d(TAG, "onRouteRemoved: route=" + route); 12857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 12957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 13057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang @Override 13157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang public void onRouteSelected(MediaRouter router, RouteInfo route) { 13257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang Log.d(TAG, "onRouteSelected: route=" + route); 13357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 1349a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik mPlayer = Player.create(SampleMediaRouterActivity.this, route, mMediaSession); 135a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang mPlayer.updatePresentation(); 136a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang mSessionManager.setPlayer(mPlayer); 137a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang mSessionManager.unsuspend(); 13857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 13957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang updateUi(); 14057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 14157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 14257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang @Override 14357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang public void onRouteUnselected(MediaRouter router, RouteInfo route) { 14457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang Log.d(TAG, "onRouteUnselected: route=" + route); 1459a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik mMediaSession.setActive(false); 146a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang 147a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang PlaylistItem item = getCheckedPlaylistItem(); 148a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang if (item != null) { 149cf61a6ed2bfa6141b832fdc40a9fbfb70af91416Chong Zhang long pos = item.getPosition() + (mSessionManager.isPaused() ? 150a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang 0 : (SystemClock.elapsedRealtime() - item.getTimestamp())); 151a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang mSessionManager.suspend(pos); 152a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang } 153a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang mPlayer.updatePresentation(); 154a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang mPlayer.release(); 15557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 15657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 15757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang @Override 15857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang public void onRouteVolumeChanged(MediaRouter router, RouteInfo route) { 15957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang Log.d(TAG, "onRouteVolumeChanged: route=" + route); 16057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 16157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 16257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang @Override 16357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang public void onRoutePresentationDisplayChanged( 16457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang MediaRouter router, RouteInfo route) { 16557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang Log.d(TAG, "onRoutePresentationDisplayChanged: route=" + route); 166a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang mPlayer.updatePresentation(); 16757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 16857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 16957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang @Override 17057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang public void onProviderAdded(MediaRouter router, ProviderInfo provider) { 17157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang Log.d(TAG, "onRouteProviderAdded: provider=" + provider); 17257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 17357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 17457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang @Override 17557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang public void onProviderRemoved(MediaRouter router, ProviderInfo provider) { 17657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang Log.d(TAG, "onRouteProviderRemoved: provider=" + provider); 17757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 17857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 17957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang @Override 18057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang public void onProviderChanged(MediaRouter router, ProviderInfo provider) { 18157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang Log.d(TAG, "onRouteProviderChanged: provider=" + provider); 18257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 18357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang }; 18457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 1859a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik private MediaSessionCompat mMediaSession; 1867578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang private ComponentName mEventReceiver; 1877578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang private AudioManager mAudioManager; 1887578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang private PendingIntent mMediaPendingIntent; 1897578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang private final OnAudioFocusChangeListener mAfChangeListener = 1907578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang new OnAudioFocusChangeListener() { 1917578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang @Override 1927578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang public void onAudioFocusChange(int focusChange) { 1937578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang if (focusChange == AudioManager.AUDIOFOCUS_LOSS_TRANSIENT) { 1947578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang Log.d(TAG, "onAudioFocusChange: LOSS_TRANSIENT"); 1957578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang } else if (focusChange == AudioManager.AUDIOFOCUS_GAIN) { 1967578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang Log.d(TAG, "onAudioFocusChange: AUDIOFOCUS_GAIN"); 1977578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang } else if (focusChange == AudioManager.AUDIOFOCUS_LOSS) { 1987578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang Log.d(TAG, "onAudioFocusChange: AUDIOFOCUS_LOSS"); 1997578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang } 2007578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang } 2017578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang }; 2027578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang 203ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown @Override 204ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown protected void onCreate(Bundle savedInstanceState) { 205ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown // Be sure to call the super class. 206ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown super.onCreate(savedInstanceState); 207ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown 208ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown // Get the media router service. 209ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown mMediaRouter = MediaRouter.getInstance(this); 210ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown 21155e47d370890d3cbdab82857090c42df734ba276Jeff Brown // Create a route selector for the type of routes that we care about. 21255e47d370890d3cbdab82857090c42df734ba276Jeff Brown mSelector = new MediaRouteSelector.Builder() 21355e47d370890d3cbdab82857090c42df734ba276Jeff Brown .addControlCategory(MediaControlIntent.CATEGORY_LIVE_AUDIO) 21455e47d370890d3cbdab82857090c42df734ba276Jeff Brown .addControlCategory(MediaControlIntent.CATEGORY_LIVE_VIDEO) 21555e47d370890d3cbdab82857090c42df734ba276Jeff Brown .addControlCategory(MediaControlIntent.CATEGORY_REMOTE_PLAYBACK) 21655e47d370890d3cbdab82857090c42df734ba276Jeff Brown .addControlCategory(SampleMediaRouteProvider.CATEGORY_SAMPLE_ROUTE) 21755e47d370890d3cbdab82857090c42df734ba276Jeff Brown .build(); 21855e47d370890d3cbdab82857090c42df734ba276Jeff Brown 219f0dd451048100915f072423730a93d17c53fd899Jeff Brown // Add a fragment to take care of media route discovery. 220f0dd451048100915f072423730a93d17c53fd899Jeff Brown // This fragment automatically adds or removes a callback whenever the activity 221f0dd451048100915f072423730a93d17c53fd899Jeff Brown // is started or stopped. 222f0dd451048100915f072423730a93d17c53fd899Jeff Brown FragmentManager fm = getSupportFragmentManager(); 22357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang DiscoveryFragment fragment = (DiscoveryFragment)fm.findFragmentByTag( 22457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang DISCOVERY_FRAGMENT_TAG); 22557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang if (fragment == null) { 22657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang fragment = new DiscoveryFragment(mMediaRouterCB); 227f0dd451048100915f072423730a93d17c53fd899Jeff Brown fragment.setRouteSelector(mSelector); 228f0dd451048100915f072423730a93d17c53fd899Jeff Brown fm.beginTransaction() 229f0dd451048100915f072423730a93d17c53fd899Jeff Brown .add(fragment, DISCOVERY_FRAGMENT_TAG) 230f0dd451048100915f072423730a93d17c53fd899Jeff Brown .commit(); 23157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } else { 23257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang fragment.setCallback(mMediaRouterCB); 23357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang fragment.setRouteSelector(mSelector); 234f0dd451048100915f072423730a93d17c53fd899Jeff Brown } 235f0dd451048100915f072423730a93d17c53fd899Jeff Brown 23657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang // Populate an array adapter with streaming media items. 237ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown String[] mediaNames = getResources().getStringArray(R.array.media_names); 238ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown String[] mediaUris = getResources().getStringArray(R.array.media_uris); 23957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang mLibraryItems = new LibraryAdapter(); 240ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown for (int i = 0; i < mediaNames.length; i++) { 24157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang mLibraryItems.add(new MediaItem( 242a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang "[streaming] "+mediaNames[i], Uri.parse(mediaUris[i]), "video/mp4")); 243ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown } 244ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown 24545ca8fb42505658590e808d4d30b57598689d9a8Jeff Brown // Scan local external storage directory for media files. 24645ca8fb42505658590e808d4d30b57598689d9a8Jeff Brown File externalDir = Environment.getExternalStorageDirectory(); 24745ca8fb42505658590e808d4d30b57598689d9a8Jeff Brown if (externalDir != null) { 24845ca8fb42505658590e808d4d30b57598689d9a8Jeff Brown File list[] = externalDir.listFiles(); 24945ca8fb42505658590e808d4d30b57598689d9a8Jeff Brown if (list != null) { 25045ca8fb42505658590e808d4d30b57598689d9a8Jeff Brown for (int i = 0; i < list.length; i++) { 25145ca8fb42505658590e808d4d30b57598689d9a8Jeff Brown String filename = list[i].getName(); 25245ca8fb42505658590e808d4d30b57598689d9a8Jeff Brown if (filename.matches(".*\\.(m4v|mp4)")) { 25345ca8fb42505658590e808d4d30b57598689d9a8Jeff Brown mLibraryItems.add(new MediaItem("[local] " + filename, 254a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang Uri.fromFile(list[i]), "video/mp4")); 25545ca8fb42505658590e808d4d30b57598689d9a8Jeff Brown } 25645ca8fb42505658590e808d4d30b57598689d9a8Jeff Brown } 25757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 25857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 25957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 26057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang mPlayListItems = new PlaylistAdapter(); 26157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 262ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown // Initialize the layout. 263ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown setContentView(R.layout.sample_media_router); 264ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown 26557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang TabHost tabHost=(TabHost)findViewById(R.id.tabHost); 26657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang tabHost.setup(); 26757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang String tabName = getResources().getString(R.string.library_tab_text); 26857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang TabSpec spec1=tabHost.newTabSpec(tabName); 26957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang spec1.setContent(R.id.tab1); 27057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang spec1.setIndicator(tabName); 27157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 27257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang tabName = getResources().getString(R.string.playlist_tab_text); 27357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang TabSpec spec2=tabHost.newTabSpec(tabName); 27457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang spec2.setIndicator(tabName); 27557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang spec2.setContent(R.id.tab2); 27657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 277cf61a6ed2bfa6141b832fdc40a9fbfb70af91416Chong Zhang tabName = getResources().getString(R.string.info_tab_text); 27857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang TabSpec spec3=tabHost.newTabSpec(tabName); 27957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang spec3.setIndicator(tabName); 28057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang spec3.setContent(R.id.tab3); 28157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 28257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang tabHost.addTab(spec1); 28357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang tabHost.addTab(spec2); 28457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang tabHost.addTab(spec3); 28557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang tabHost.setOnTabChangedListener(new OnTabChangeListener() { 28657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang @Override 28757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang public void onTabChanged(String arg0) { 28857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang updateUi(); 28957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 29057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang }); 29157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 29257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang mLibraryView = (ListView) findViewById(R.id.media); 29357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang mLibraryView.setAdapter(mLibraryItems); 29457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang mLibraryView.setChoiceMode(ListView.CHOICE_MODE_SINGLE); 29557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang mLibraryView.setOnItemClickListener(new OnItemClickListener() { 29657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang @Override 29757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang public void onItemClick(AdapterView<?> parent, View view, int position, long id) { 29857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang updateButtons(); 29957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 30057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang }); 301ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown 30257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang mPlayListView = (ListView) findViewById(R.id.playlist); 30357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang mPlayListView.setAdapter(mPlayListItems); 30457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang mPlayListView.setChoiceMode(ListView.CHOICE_MODE_SINGLE); 30557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang mPlayListView.setOnItemClickListener(new OnItemClickListener() { 306ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown @Override 307ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown public void onItemClick(AdapterView<?> parent, View view, int position, long id) { 308ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown updateButtons(); 309ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown } 310ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown }); 311ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown 31257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang mInfoTextView = (TextView) findViewById(R.id.info); 31357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 31476d965dc41863b33f887db33d283cb7f1523f60dJae Seo mUseDefaultControlCheckBox = (CheckBox) findViewById(R.id.custom_control_view_checkbox); 31576d965dc41863b33f887db33d283cb7f1523f60dJae Seo if (ENABLE_DEFAULT_CONTROL_CHECK_BOX) { 31676d965dc41863b33f887db33d283cb7f1523f60dJae Seo mUseDefaultControlCheckBox.setVisibility(View.VISIBLE); 31776d965dc41863b33f887db33d283cb7f1523f60dJae Seo } 31857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang mPauseResumeButton = (ImageButton)findViewById(R.id.pause_resume_button); 31957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang mPauseResumeButton.setOnClickListener(new OnClickListener() { 320ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown @Override 321ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown public void onClick(View v) { 322cf61a6ed2bfa6141b832fdc40a9fbfb70af91416Chong Zhang if (mSessionManager.isPaused()) { 323a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang mSessionManager.resume(); 324cf61a6ed2bfa6141b832fdc40a9fbfb70af91416Chong Zhang } else { 325cf61a6ed2bfa6141b832fdc40a9fbfb70af91416Chong Zhang mSessionManager.pause(); 32657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 327ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown } 328ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown }); 329ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown 33057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang mStopButton = (ImageButton)findViewById(R.id.stop_button); 33157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang mStopButton.setOnClickListener(new OnClickListener() { 332ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown @Override 333ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown public void onClick(View v) { 334a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang mSessionManager.stop(); 335ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown } 336ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown }); 33757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 33857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang mSeekBar = (SeekBar) findViewById(R.id.seekbar); 33957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang mSeekBar.setOnSeekBarChangeListener(new OnSeekBarChangeListener() { 34057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang @Override 34157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { 342a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang PlaylistItem item = getCheckedPlaylistItem(); 343a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang if (fromUser && item != null && item.getDuration() > 0) { 344a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang long pos = progress * item.getDuration() / 100; 345a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang mSessionManager.seek(item.getItemId(), pos); 346a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang item.setPosition(pos); 347a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang item.setTimestamp(SystemClock.elapsedRealtime()); 34857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 34957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 35057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang @Override 35157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang public void onStartTrackingTouch(SeekBar seekBar) { 35257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang mSeeking = true; 35357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 35457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang @Override 35557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang public void onStopTrackingTouch(SeekBar seekBar) { 35657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang mSeeking = false; 35757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang updateUi(); 35857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 35957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang }); 36057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 36157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang // Schedule Ui update 36257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang mHandler.postDelayed(mUpdateSeekRunnable, 1000); 36357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 3647578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang // Build the PendingIntent for the remote control client 3657578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang mAudioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE); 3667578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang mEventReceiver = new ComponentName(getPackageName(), 3677578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang SampleMediaButtonReceiver.class.getName()); 3687578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang Intent mediaButtonIntent = new Intent(Intent.ACTION_MEDIA_BUTTON); 3697578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang mediaButtonIntent.setComponent(mEventReceiver); 3707578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang mMediaPendingIntent = PendingIntent.getBroadcast(this, 0, mediaButtonIntent, 0); 3717b95dd38981772983f00c5ed91aca4b30b782facJeff Brown 3727b95dd38981772983f00c5ed91aca4b30b782facJeff Brown // Create and register the remote control client 3739a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik createMediaSession(); 3749a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik mMediaRouter.setMediaSessionCompat(mMediaSession); 375a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang 376a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang // Set up playback manager and player 377a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang mPlayer = Player.create(SampleMediaRouterActivity.this, 3789a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik mMediaRouter.getSelectedRoute(), mMediaSession); 3795d429bc3a8195d6f37cf2f7da0935972950539b4RoboErik 380a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang mSessionManager.setPlayer(mPlayer); 381a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang mSessionManager.setCallback(new SessionManager.Callback() { 382a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang @Override 383a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang public void onStatusChanged() { 384a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang updateUi(); 385a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang } 386a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang 387a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang @Override 388a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang public void onItemChanged(PlaylistItem item) { 389a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang } 390a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang }); 391a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang 392a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang updateUi(); 3937578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang } 3947578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang 3959a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik private void createMediaSession() { 3969a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik // Create the MediaSession 3979a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik mMediaSession = new MediaSessionCompat(this, "SampleMediaRouter", mEventReceiver, 3989a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik mMediaPendingIntent); 3999a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik mMediaSession.setFlags(MediaSessionCompat.FLAG_HANDLES_MEDIA_BUTTONS 4009a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik | MediaSessionCompat.FLAG_HANDLES_TRANSPORT_CONTROLS); 4019a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik mMediaSession.setCallback(new MediaSessionCompat.Callback() { 4029a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik @Override 4039a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik public boolean onMediaButtonEvent(Intent mediaButtonEvent) { 4049a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik if (mediaButtonEvent != null) { 4059a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik return handleMediaKey( 4069a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik (KeyEvent) mediaButtonEvent.getParcelableExtra(Intent.EXTRA_KEY_EVENT)); 4079a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik } 4089a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik return super.onMediaButtonEvent(mediaButtonEvent); 4099a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik } 4107578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang 4119a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik @Override 4129a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik public void onPlay() { 4139a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik mSessionManager.resume(); 4149a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik } 4159a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik 4169a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik @Override 4179a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik public void onPause() { 4189a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik mSessionManager.pause(); 4199a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik } 4209a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik }); 4219a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik 4229a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik SampleMediaButtonReceiver.setActivity(SampleMediaRouterActivity.this); 4237578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang } 4247578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang 4257578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang public boolean handleMediaKey(KeyEvent event) { 4269a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik if (event != null && event.getAction() == KeyEvent.ACTION_DOWN 4279a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik && event.getRepeatCount() == 0) { 4287578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang switch (event.getKeyCode()) { 4297578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang case KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE: 4309a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik case KeyEvent.KEYCODE_HEADSETHOOK: 4317578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang { 4327578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang Log.d(TAG, "Received Play/Pause event from RemoteControlClient"); 433cf61a6ed2bfa6141b832fdc40a9fbfb70af91416Chong Zhang if (mSessionManager.isPaused()) { 434a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang mSessionManager.resume(); 435cf61a6ed2bfa6141b832fdc40a9fbfb70af91416Chong Zhang } else { 436cf61a6ed2bfa6141b832fdc40a9fbfb70af91416Chong Zhang mSessionManager.pause(); 4377578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang } 4387578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang return true; 4397578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang } 4407578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang case KeyEvent.KEYCODE_MEDIA_PLAY: 4417578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang { 4427578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang Log.d(TAG, "Received Play event from RemoteControlClient"); 443cf61a6ed2bfa6141b832fdc40a9fbfb70af91416Chong Zhang if (mSessionManager.isPaused()) { 444a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang mSessionManager.resume(); 4457578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang } 4467578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang return true; 4477578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang } 4487578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang case KeyEvent.KEYCODE_MEDIA_PAUSE: 4497578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang { 4507578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang Log.d(TAG, "Received Pause event from RemoteControlClient"); 451cf61a6ed2bfa6141b832fdc40a9fbfb70af91416Chong Zhang if (!mSessionManager.isPaused()) { 452a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang mSessionManager.pause(); 4537578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang } 4547578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang return true; 4557578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang } 4567578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang case KeyEvent.KEYCODE_MEDIA_STOP: 4577578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang { 4587578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang Log.d(TAG, "Received Stop event from RemoteControlClient"); 459a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang mSessionManager.stop(); 4607578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang return true; 4617578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang } 4627578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang default: 4637578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang break; 4647578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang } 4657578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang } 4667578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang return false; 4677578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang } 4687578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang 4697578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang @Override 4707578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang public boolean onKeyDown(int keyCode, KeyEvent event) { 4717578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang return handleMediaKey(event) || super.onKeyDown(keyCode, event); 4727578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang } 4737578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang 4747578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang @Override 4757578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang public boolean onKeyUp(int keyCode, KeyEvent event) { 4767578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang return handleMediaKey(event) || super.onKeyUp(keyCode, event); 477ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown } 478ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown 479ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown @Override 480f0dd451048100915f072423730a93d17c53fd899Jeff Brown public void onStart() { 481ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown // Be sure to call the super class. 482f0dd451048100915f072423730a93d17c53fd899Jeff Brown super.onStart(); 48357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 484ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown 48557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang @Override 48657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang public void onPause() { 48757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang // pause media player for local playback case only 488cf61a6ed2bfa6141b832fdc40a9fbfb70af91416Chong Zhang if (!mPlayer.isRemotePlayback() && !mSessionManager.isPaused()) { 48957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang mNeedResume = true; 490a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang mSessionManager.pause(); 49157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 49257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang super.onPause(); 49357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 49457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 49557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang @Override 49657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang public void onResume() { 49757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang // resume media player for local playback case only 498a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang if (!mPlayer.isRemotePlayback() && mNeedResume) { 499a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang mSessionManager.resume(); 50057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang mNeedResume = false; 50157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 50257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang super.onResume(); 50357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 50457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 50557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang @Override 50657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang public void onDestroy() { 507a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang mSessionManager.stop(); 508a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang mPlayer.release(); 5099a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik mMediaSession.release(); 51057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang super.onDestroy(); 511ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown } 512ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown 513ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown @Override 514ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown public boolean onCreateOptionsMenu(Menu menu) { 515ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown // Be sure to call the super class. 516ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown super.onCreateOptionsMenu(menu); 517ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown 518ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown // Inflate the menu and configure the media router action provider. 519ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown getMenuInflater().inflate(R.menu.sample_media_router_menu, menu); 520ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown 52155e47d370890d3cbdab82857090c42df734ba276Jeff Brown MenuItem mediaRouteMenuItem = menu.findItem(R.id.media_route_menu_item); 522ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown MediaRouteActionProvider mediaRouteActionProvider = 52355e47d370890d3cbdab82857090c42df734ba276Jeff Brown (MediaRouteActionProvider)MenuItemCompat.getActionProvider(mediaRouteMenuItem); 52455e47d370890d3cbdab82857090c42df734ba276Jeff Brown mediaRouteActionProvider.setRouteSelector(mSelector); 525cf61a6ed2bfa6141b832fdc40a9fbfb70af91416Chong Zhang mediaRouteActionProvider.setDialogFactory(new MediaRouteDialogFactory() { 526cf61a6ed2bfa6141b832fdc40a9fbfb70af91416Chong Zhang @Override 527cf61a6ed2bfa6141b832fdc40a9fbfb70af91416Chong Zhang public MediaRouteControllerDialogFragment onCreateControllerDialogFragment() { 52876d965dc41863b33f887db33d283cb7f1523f60dJae Seo return new ControllerDialogFragment(mPlayer, mUseDefaultControlCheckBox); 529cf61a6ed2bfa6141b832fdc40a9fbfb70af91416Chong Zhang } 530cf61a6ed2bfa6141b832fdc40a9fbfb70af91416Chong Zhang }); 531ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown 532ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown // Return true to show the menu. 533ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown return true; 534ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown } 535ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown 536a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang private void updateProgress() { 53757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang // Estimate content position from last status time and elapsed time. 53857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang // (Note this might be slightly out of sync with remote side, however 53957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang // it avoids frequent polling the MRP.) 54057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang int progress = 0; 541a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang PlaylistItem item = getCheckedPlaylistItem(); 542a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang if (item != null) { 543a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang int state = item.getState(); 544a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang long duration = item.getDuration(); 54557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang if (duration <= 0) { 54657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang if (state == MediaItemStatus.PLAYBACK_STATE_PLAYING 54757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang || state == MediaItemStatus.PLAYBACK_STATE_PAUSED) { 548a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang mSessionManager.updateStatus(); 54957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 55057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } else { 551a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang long position = item.getPosition(); 552cf61a6ed2bfa6141b832fdc40a9fbfb70af91416Chong Zhang long timeDelta = mSessionManager.isPaused() ? 0 : 553a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang (SystemClock.elapsedRealtime() - item.getTimestamp()); 55457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang progress = (int)(100.0 * (position + timeDelta) / duration); 55557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 556ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown } 55757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang mSeekBar.setProgress(progress); 55857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 559ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown 56057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang private void updateUi() { 56157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang updatePlaylist(); 562a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang updateRouteDescription(); 56357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang updateButtons(); 5645d429bc3a8195d6f37cf2f7da0935972950539b4RoboErik if (mPlayer != null) { 5655d429bc3a8195d6f37cf2f7da0935972950539b4RoboErik mPlayer.updateMetadata(); 566cf61a6ed2bfa6141b832fdc40a9fbfb70af91416Chong Zhang } 567ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown } 568ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown 56957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang private void updatePlaylist() { 57057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang mPlayListItems.clear(); 571a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang for (PlaylistItem item : mSessionManager.getPlaylist()) { 572a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang mPlayListItems.add(item); 573a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang } 57457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang mPlayListView.invalidate(); 575a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang } 576ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown 577a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang private void updateRouteDescription() { 578a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang RouteInfo route = mMediaRouter.getSelectedRoute(); 579a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang mInfoTextView.setText("Currently selected route:" 580a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang + "\nName: " + route.getName() 581a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang + "\nProvider: " + route.getProvider().getPackageName() 582cf61a6ed2bfa6141b832fdc40a9fbfb70af91416Chong Zhang + "\nDescription: " + route.getDescription()); 58357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 584fcb6a9d1caaf43ae41f859ebb58a4483b12475a1Jeff Brown 585a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang private void updateButtons() { 586a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang MediaRouter.RouteInfo route = mMediaRouter.getSelectedRoute(); 587a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang // show pause or resume icon depending on current state 588cf61a6ed2bfa6141b832fdc40a9fbfb70af91416Chong Zhang mPauseResumeButton.setImageResource(mSessionManager.isPaused() ? 589a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang R.drawable.ic_media_play : R.drawable.ic_media_pause); 590a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang // only enable seek bar when duration is known 591a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang PlaylistItem item = getCheckedPlaylistItem(); 592a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang mSeekBar.setEnabled(item != null && item.getDuration() > 0); 59357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 594ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown 595a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang private PlaylistItem getCheckedPlaylistItem() { 59657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang int count = mPlayListView.getCount(); 59757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang int index = mPlayListView.getCheckedItemPosition(); 59857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang if (count > 0) { 59957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang if (index < 0 || index >= count) { 60057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang index = 0; 60157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang mPlayListView.setItemChecked(0, true); 60257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 60357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang return mPlayListItems.getItem(index); 604ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown } 60557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang return null; 606ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown } 607ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown 60857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang public static final class DiscoveryFragment extends MediaRouteDiscoveryFragment { 60957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang private static final String TAG = "DiscoveryFragment"; 61057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang private Callback mCallback; 61157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 61257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang public DiscoveryFragment() { 61357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang mCallback = null; 61457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 61557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 61657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang public DiscoveryFragment(Callback cb) { 61757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang mCallback = cb; 61857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 61957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 62057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang public void setCallback(Callback cb) { 62157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang mCallback = cb; 62257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 62357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 62457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang @Override 62557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang public Callback onCreateCallback() { 62657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang return mCallback; 627ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown } 62855e47d370890d3cbdab82857090c42df734ba276Jeff Brown 62955e47d370890d3cbdab82857090c42df734ba276Jeff Brown @Override 630f0dd451048100915f072423730a93d17c53fd899Jeff Brown public int onPrepareCallbackFlags() { 631f0dd451048100915f072423730a93d17c53fd899Jeff Brown // Add the CALLBACK_FLAG_UNFILTERED_EVENTS flag to ensure that we will 632f0dd451048100915f072423730a93d17c53fd899Jeff Brown // observe and log all route events including those that are for routes 633f0dd451048100915f072423730a93d17c53fd899Jeff Brown // that do not match our selector. This is only for demonstration purposes 634f0dd451048100915f072423730a93d17c53fd899Jeff Brown // and should not be needed by most applications. 635f0dd451048100915f072423730a93d17c53fd899Jeff Brown return super.onPrepareCallbackFlags() 636f0dd451048100915f072423730a93d17c53fd899Jeff Brown | MediaRouter.CALLBACK_FLAG_UNFILTERED_EVENTS; 63755e47d370890d3cbdab82857090c42df734ba276Jeff Brown } 638f0dd451048100915f072423730a93d17c53fd899Jeff Brown } 639ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown 640ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown private static final class MediaItem { 641ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown public final String mName; 642ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown public final Uri mUri; 643a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang public final String mMime; 644ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown 645a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang public MediaItem(String name, Uri uri, String mime) { 646ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown mName = name; 647ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown mUri = uri; 648a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang mMime = mime; 649ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown } 650ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown 651ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown @Override 652ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown public String toString() { 653ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown return mName; 654ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown } 655ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown } 65655e47d370890d3cbdab82857090c42df734ba276Jeff Brown 65757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang private final class LibraryAdapter extends ArrayAdapter<MediaItem> { 65857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang public LibraryAdapter() { 65957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang super(SampleMediaRouterActivity.this, R.layout.media_item); 66057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 66157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 66257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang @Override 66357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang public View getView(int position, View convertView, ViewGroup parent) { 66457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang final View v; 66557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang if (convertView == null) { 66657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang v = getLayoutInflater().inflate(R.layout.media_item, null); 66757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } else { 66857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang v = convertView; 66957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 67057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 67157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang final MediaItem item = getItem(position); 67257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 67357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang TextView tv = (TextView)v.findViewById(R.id.item_text); 67457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang tv.setText(item.mName); 67557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 67657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang ImageButton b = (ImageButton)v.findViewById(R.id.item_action); 67757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang b.setImageResource(R.drawable.ic_menu_add); 67857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang b.setTag(item); 67957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang b.setOnClickListener(new OnClickListener() { 68057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang @Override 68157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang public void onClick(View v) { 68257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang if (item != null) { 683a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang mSessionManager.add(item.mUri, item.mMime); 68457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 68557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 68657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang }); 68757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 68857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang return v; 68957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 69057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 69157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 692a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang private final class PlaylistAdapter extends ArrayAdapter<PlaylistItem> { 69357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang public PlaylistAdapter() { 69457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang super(SampleMediaRouterActivity.this, R.layout.media_item); 69557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 69657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 69757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang @Override 69857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang public View getView(int position, View convertView, ViewGroup parent) { 69957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang final View v; 70057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang if (convertView == null) { 70157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang v = getLayoutInflater().inflate(R.layout.media_item, null); 70257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } else { 70357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang v = convertView; 70457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 70557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 706a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang final PlaylistItem item = getItem(position); 70757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 70857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang TextView tv = (TextView)v.findViewById(R.id.item_text); 70957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang tv.setText(item.toString()); 71057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 71157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang ImageButton b = (ImageButton)v.findViewById(R.id.item_action); 71257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang b.setImageResource(R.drawable.ic_menu_delete); 71357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang b.setTag(item); 71457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang b.setOnClickListener(new OnClickListener() { 71557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang @Override 71657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang public void onClick(View v) { 71757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang if (item != null) { 718a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang mSessionManager.remove(item.getItemId()); 71957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 72057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 72157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang }); 72257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 72357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang return v; 72457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 72557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 72657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 72755e47d370890d3cbdab82857090c42df734ba276Jeff Brown /** 72855e47d370890d3cbdab82857090c42df734ba276Jeff Brown * Trivial subclass of this activity used to provide another copy of the 72955e47d370890d3cbdab82857090c42df734ba276Jeff Brown * same activity using a light theme instead of the dark theme. 73055e47d370890d3cbdab82857090c42df734ba276Jeff Brown */ 73155e47d370890d3cbdab82857090c42df734ba276Jeff Brown public static class Light extends SampleMediaRouterActivity { 73255e47d370890d3cbdab82857090c42df734ba276Jeff Brown } 73355e47d370890d3cbdab82857090c42df734ba276Jeff Brown 73455e47d370890d3cbdab82857090c42df734ba276Jeff Brown /** 73555e47d370890d3cbdab82857090c42df734ba276Jeff Brown * Trivial subclass of this activity used to provide another copy of the 73655e47d370890d3cbdab82857090c42df734ba276Jeff Brown * same activity using a light theme with dark action bar instead of the dark theme. 73755e47d370890d3cbdab82857090c42df734ba276Jeff Brown */ 73855e47d370890d3cbdab82857090c42df734ba276Jeff Brown public static class LightWithDarkActionBar extends SampleMediaRouterActivity { 73955e47d370890d3cbdab82857090c42df734ba276Jeff Brown } 7405d429bc3a8195d6f37cf2f7da0935972950539b4RoboErik 7415d429bc3a8195d6f37cf2f7da0935972950539b4RoboErik public static class ControllerDialogFragment extends MediaRouteControllerDialogFragment { 7425d429bc3a8195d6f37cf2f7da0935972950539b4RoboErik private MediaRouteControllerDialog mControllerDialog; 7435d429bc3a8195d6f37cf2f7da0935972950539b4RoboErik private Player mPlayer; 74476d965dc41863b33f887db33d283cb7f1523f60dJae Seo private CheckBox mUseDefaultControlCheckBox; 7455d429bc3a8195d6f37cf2f7da0935972950539b4RoboErik 7465d429bc3a8195d6f37cf2f7da0935972950539b4RoboErik public ControllerDialogFragment() { 7475d429bc3a8195d6f37cf2f7da0935972950539b4RoboErik super(); 7485d429bc3a8195d6f37cf2f7da0935972950539b4RoboErik } 7495d429bc3a8195d6f37cf2f7da0935972950539b4RoboErik 75076d965dc41863b33f887db33d283cb7f1523f60dJae Seo public ControllerDialogFragment(Player player, CheckBox customControlViewCheckBox) { 7515d429bc3a8195d6f37cf2f7da0935972950539b4RoboErik mPlayer = player; 75276d965dc41863b33f887db33d283cb7f1523f60dJae Seo this.mUseDefaultControlCheckBox = customControlViewCheckBox; 7535d429bc3a8195d6f37cf2f7da0935972950539b4RoboErik } 7545d429bc3a8195d6f37cf2f7da0935972950539b4RoboErik 7555d429bc3a8195d6f37cf2f7da0935972950539b4RoboErik @Override 7565d429bc3a8195d6f37cf2f7da0935972950539b4RoboErik public MediaRouteControllerDialog onCreateControllerDialog( 7575d429bc3a8195d6f37cf2f7da0935972950539b4RoboErik Context context, Bundle savedInstanceState) { 75876d965dc41863b33f887db33d283cb7f1523f60dJae Seo mControllerDialog = this.mUseDefaultControlCheckBox.isChecked() 75976d965dc41863b33f887db33d283cb7f1523f60dJae Seo ? super.onCreateControllerDialog(context, savedInstanceState) 76076d965dc41863b33f887db33d283cb7f1523f60dJae Seo : new MyMediaRouteControllerDialog(context); 7615d429bc3a8195d6f37cf2f7da0935972950539b4RoboErik mControllerDialog.setOnDismissListener(new DialogInterface.OnDismissListener() { 7625d429bc3a8195d6f37cf2f7da0935972950539b4RoboErik @Override 7635d429bc3a8195d6f37cf2f7da0935972950539b4RoboErik public void onDismiss(DialogInterface dialog) { 7645d429bc3a8195d6f37cf2f7da0935972950539b4RoboErik mControllerDialog = null; 7655d429bc3a8195d6f37cf2f7da0935972950539b4RoboErik } 7665d429bc3a8195d6f37cf2f7da0935972950539b4RoboErik }); 7675d429bc3a8195d6f37cf2f7da0935972950539b4RoboErik return mControllerDialog; 7685d429bc3a8195d6f37cf2f7da0935972950539b4RoboErik } 7695d429bc3a8195d6f37cf2f7da0935972950539b4RoboErik 7705d429bc3a8195d6f37cf2f7da0935972950539b4RoboErik public void setPlayer(Player player) { 7715d429bc3a8195d6f37cf2f7da0935972950539b4RoboErik mPlayer = player; 7725d429bc3a8195d6f37cf2f7da0935972950539b4RoboErik } 7735d429bc3a8195d6f37cf2f7da0935972950539b4RoboErik } 774ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown} 775