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 1944d25261c2a38c81f1eea123de3986b453b9afeeChris Banesimport android.app.PendingIntent; 207578fad97dcd3b4b390652f37a30d805538980f5Chong Zhangimport android.content.ComponentName; 2157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhangimport android.content.Context; 225d429bc3a8195d6f37cf2f7da0935972950539b4RoboErikimport android.content.DialogInterface; 23ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brownimport android.content.Intent; 247578fad97dcd3b4b390652f37a30d805538980f5Chong Zhangimport android.media.AudioManager; 257578fad97dcd3b4b390652f37a30d805538980f5Chong Zhangimport android.media.AudioManager.OnAudioFocusChangeListener; 26ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brownimport android.net.Uri; 2761636870e0a12db5909955eca58e0070357dde42Donghyun Choimport android.os.Build; 2844d25261c2a38c81f1eea123de3986b453b9afeeChris Banesimport android.os.Bundle; 2945ca8fb42505658590e808d4d30b57598689d9a8Jeff Brownimport android.os.Environment; 3057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhangimport android.os.Handler; 3157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhangimport android.os.SystemClock; 32f796be9c80d6a62de61853a0cb1d98b440a3586fSungsooimport android.support.v4.app.FragmentManager; 339a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErikimport android.support.v4.media.session.MediaSessionCompat; 3455e47d370890d3cbdab82857090c42df734ba276Jeff Brownimport android.support.v4.view.MenuItemCompat; 3544d25261c2a38c81f1eea123de3986b453b9afeeChris Banesimport android.support.v7.app.AppCompatActivity; 3655e47d370890d3cbdab82857090c42df734ba276Jeff Brownimport android.support.v7.app.MediaRouteActionProvider; 37cf61a6ed2bfa6141b832fdc40a9fbfb70af91416Chong Zhangimport android.support.v7.app.MediaRouteControllerDialog; 38cf61a6ed2bfa6141b832fdc40a9fbfb70af91416Chong Zhangimport android.support.v7.app.MediaRouteControllerDialogFragment; 39cf61a6ed2bfa6141b832fdc40a9fbfb70af91416Chong Zhangimport android.support.v7.app.MediaRouteDialogFactory; 40f796be9c80d6a62de61853a0cb1d98b440a3586fSungsooimport android.support.v7.app.MediaRouteDiscoveryFragment; 41ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brownimport android.support.v7.media.MediaControlIntent; 4244d25261c2a38c81f1eea123de3986b453b9afeeChris Banesimport android.support.v7.media.MediaItemStatus; 4344d25261c2a38c81f1eea123de3986b453b9afeeChris Banesimport android.support.v7.media.MediaRouteSelector; 44ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brownimport android.support.v7.media.MediaRouter; 45f796be9c80d6a62de61853a0cb1d98b440a3586fSungsooimport android.support.v7.media.MediaRouter.Callback; 46ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brownimport android.support.v7.media.MediaRouter.ProviderInfo; 4744d25261c2a38c81f1eea123de3986b453b9afeeChris Banesimport android.support.v7.media.MediaRouter.RouteInfo; 48ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brownimport android.util.Log; 497578fad97dcd3b4b390652f37a30d805538980f5Chong Zhangimport android.view.KeyEvent; 50ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brownimport android.view.Menu; 51ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brownimport android.view.MenuItem; 52ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brownimport android.view.View; 53ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brownimport android.view.View.OnClickListener; 5457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhangimport android.view.ViewGroup; 55ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brownimport android.widget.AdapterView; 5657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhangimport android.widget.AdapterView.OnItemClickListener; 57ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brownimport android.widget.ArrayAdapter; 5876d965dc41863b33f887db33d283cb7f1523f60dJae Seoimport android.widget.CheckBox; 5957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhangimport android.widget.ImageButton; 60ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brownimport android.widget.ListView; 6157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhangimport android.widget.SeekBar; 6257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhangimport android.widget.SeekBar.OnSeekBarChangeListener; 6344d25261c2a38c81f1eea123de3986b453b9afeeChris Banesimport android.widget.TabHost; 6444d25261c2a38c81f1eea123de3986b453b9afeeChris Banesimport android.widget.TabHost.OnTabChangeListener; 6544d25261c2a38c81f1eea123de3986b453b9afeeChris Banesimport android.widget.TabHost.TabSpec; 6644d25261c2a38c81f1eea123de3986b453b9afeeChris Banesimport android.widget.TextView; 675d429bc3a8195d6f37cf2f7da0935972950539b4RoboErik 68c1a24039658cc52f34046800790de302b7db075bSungsoo Limimport com.example.android.supportv7.R; 69c1a24039658cc52f34046800790de302b7db075bSungsoo Lim 7057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhangimport java.io.File; 71ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown 72ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown/** 73ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown * <h3>Media Router Support Activity</h3> 74ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown * 75ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown * <p> 76ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown * This demonstrates how to use the {@link MediaRouter} API to build an 77ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown * application that allows the user to send content to various rendering 78ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown * targets. 79ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown * </p> 80ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown */ 8144d25261c2a38c81f1eea123de3986b453b9afeeChris Banespublic class SampleMediaRouterActivity extends AppCompatActivity { 82a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang private static final String TAG = "SampleMediaRouterActivity"; 83f0dd451048100915f072423730a93d17c53fd899Jeff Brown private static final String DISCOVERY_FRAGMENT_TAG = "DiscoveryFragment"; 8476d965dc41863b33f887db33d283cb7f1523f60dJae Seo private static final boolean ENABLE_DEFAULT_CONTROL_CHECK_BOX = false; 85ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown 86ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown private MediaRouter mMediaRouter; 8755e47d370890d3cbdab82857090c42df734ba276Jeff Brown private MediaRouteSelector mSelector; 8857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang private LibraryAdapter mLibraryItems; 8957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang private PlaylistAdapter mPlayListItems; 90ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown private TextView mInfoTextView; 9157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang private ListView mLibraryView; 9257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang private ListView mPlayListView; 9376d965dc41863b33f887db33d283cb7f1523f60dJae Seo private CheckBox mUseDefaultControlCheckBox; 9457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang private ImageButton mPauseResumeButton; 9557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang private ImageButton mStopButton; 9657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang private SeekBar mSeekBar; 9757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang private boolean mNeedResume; 9857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang private boolean mSeeking; 9957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 10057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang private final Handler mHandler = new Handler(); 10157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang private final Runnable mUpdateSeekRunnable = new Runnable() { 10257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang @Override 10357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang public void run() { 104a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang updateProgress(); 10557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang // update Ui every 1 second 10657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang mHandler.postDelayed(this, 1000); 10757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 10857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang }; 10957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 110a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang private final SessionManager mSessionManager = new SessionManager("app"); 11157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang private Player mPlayer; 11257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 11357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang private final MediaRouter.Callback mMediaRouterCB = new MediaRouter.Callback() { 11457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang // Return a custom callback that will simply log all of the route events 11557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang // for demonstration purposes. 11657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang @Override 11757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang public void onRouteAdded(MediaRouter router, RouteInfo route) { 11857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang Log.d(TAG, "onRouteAdded: route=" + route); 11957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 12057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 12157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang @Override 12257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang public void onRouteChanged(MediaRouter router, RouteInfo route) { 12357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang Log.d(TAG, "onRouteChanged: route=" + route); 12457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 12557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 12657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang @Override 12757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang public void onRouteRemoved(MediaRouter router, RouteInfo route) { 12857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang Log.d(TAG, "onRouteRemoved: route=" + route); 12957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 13057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 13157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang @Override 13257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang public void onRouteSelected(MediaRouter router, RouteInfo route) { 13357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang Log.d(TAG, "onRouteSelected: route=" + route); 13457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 1359a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik mPlayer = Player.create(SampleMediaRouterActivity.this, route, mMediaSession); 13661636870e0a12db5909955eca58e0070357dde42Donghyun Cho if (isPresentationApiSupported()) { 13761636870e0a12db5909955eca58e0070357dde42Donghyun Cho mPlayer.updatePresentation(); 13861636870e0a12db5909955eca58e0070357dde42Donghyun Cho } 139a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang mSessionManager.setPlayer(mPlayer); 140a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang mSessionManager.unsuspend(); 14157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 14257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang updateUi(); 14357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 14457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 14557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang @Override 14657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang public void onRouteUnselected(MediaRouter router, RouteInfo route) { 14757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang Log.d(TAG, "onRouteUnselected: route=" + route); 1489a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik mMediaSession.setActive(false); 149a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang 150a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang PlaylistItem item = getCheckedPlaylistItem(); 151a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang if (item != null) { 152cf61a6ed2bfa6141b832fdc40a9fbfb70af91416Chong Zhang long pos = item.getPosition() + (mSessionManager.isPaused() ? 153a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang 0 : (SystemClock.elapsedRealtime() - item.getTimestamp())); 154a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang mSessionManager.suspend(pos); 155a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang } 15661636870e0a12db5909955eca58e0070357dde42Donghyun Cho if (isPresentationApiSupported()) { 15761636870e0a12db5909955eca58e0070357dde42Donghyun Cho mPlayer.updatePresentation(); 15861636870e0a12db5909955eca58e0070357dde42Donghyun Cho } 159a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang mPlayer.release(); 16057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 16157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 16257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang @Override 16357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang public void onRouteVolumeChanged(MediaRouter router, RouteInfo route) { 16457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang Log.d(TAG, "onRouteVolumeChanged: route=" + route); 16557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 16657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 16757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang @Override 16857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang public void onRoutePresentationDisplayChanged( 16957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang MediaRouter router, RouteInfo route) { 17057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang Log.d(TAG, "onRoutePresentationDisplayChanged: route=" + route); 17161636870e0a12db5909955eca58e0070357dde42Donghyun Cho if (isPresentationApiSupported()) { 17261636870e0a12db5909955eca58e0070357dde42Donghyun Cho mPlayer.updatePresentation(); 17361636870e0a12db5909955eca58e0070357dde42Donghyun Cho } 17457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 17557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 17657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang @Override 17757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang public void onProviderAdded(MediaRouter router, ProviderInfo provider) { 17857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang Log.d(TAG, "onRouteProviderAdded: provider=" + provider); 17957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 18057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 18157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang @Override 18257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang public void onProviderRemoved(MediaRouter router, ProviderInfo provider) { 18357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang Log.d(TAG, "onRouteProviderRemoved: provider=" + provider); 18457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 18557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 18657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang @Override 18757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang public void onProviderChanged(MediaRouter router, ProviderInfo provider) { 18857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang Log.d(TAG, "onRouteProviderChanged: provider=" + provider); 18957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 19061636870e0a12db5909955eca58e0070357dde42Donghyun Cho 19161636870e0a12db5909955eca58e0070357dde42Donghyun Cho private boolean isPresentationApiSupported() { 19261636870e0a12db5909955eca58e0070357dde42Donghyun Cho return Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1; 19361636870e0a12db5909955eca58e0070357dde42Donghyun Cho } 19457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang }; 19557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 1969a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik private MediaSessionCompat mMediaSession; 1977578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang private ComponentName mEventReceiver; 1987578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang private AudioManager mAudioManager; 1997578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang private PendingIntent mMediaPendingIntent; 2007578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang private final OnAudioFocusChangeListener mAfChangeListener = 2017578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang new OnAudioFocusChangeListener() { 2027578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang @Override 2037578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang public void onAudioFocusChange(int focusChange) { 2047578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang if (focusChange == AudioManager.AUDIOFOCUS_LOSS_TRANSIENT) { 2057578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang Log.d(TAG, "onAudioFocusChange: LOSS_TRANSIENT"); 2067578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang } else if (focusChange == AudioManager.AUDIOFOCUS_GAIN) { 2077578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang Log.d(TAG, "onAudioFocusChange: AUDIOFOCUS_GAIN"); 2087578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang } else if (focusChange == AudioManager.AUDIOFOCUS_LOSS) { 2097578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang Log.d(TAG, "onAudioFocusChange: AUDIOFOCUS_LOSS"); 2107578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang } 2117578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang } 2127578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang }; 2137578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang 214ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown @Override 215ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown protected void onCreate(Bundle savedInstanceState) { 216ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown // Be sure to call the super class. 217ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown super.onCreate(savedInstanceState); 218ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown 219ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown // Get the media router service. 220ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown mMediaRouter = MediaRouter.getInstance(this); 221ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown 22255e47d370890d3cbdab82857090c42df734ba276Jeff Brown // Create a route selector for the type of routes that we care about. 22355e47d370890d3cbdab82857090c42df734ba276Jeff Brown mSelector = new MediaRouteSelector.Builder() 22455e47d370890d3cbdab82857090c42df734ba276Jeff Brown .addControlCategory(MediaControlIntent.CATEGORY_LIVE_AUDIO) 22555e47d370890d3cbdab82857090c42df734ba276Jeff Brown .addControlCategory(MediaControlIntent.CATEGORY_LIVE_VIDEO) 22655e47d370890d3cbdab82857090c42df734ba276Jeff Brown .addControlCategory(MediaControlIntent.CATEGORY_REMOTE_PLAYBACK) 22755e47d370890d3cbdab82857090c42df734ba276Jeff Brown .addControlCategory(SampleMediaRouteProvider.CATEGORY_SAMPLE_ROUTE) 22855e47d370890d3cbdab82857090c42df734ba276Jeff Brown .build(); 229f796be9c80d6a62de61853a0cb1d98b440a3586fSungsoo 230f796be9c80d6a62de61853a0cb1d98b440a3586fSungsoo // Add a fragment to take care of media route discovery. 231f796be9c80d6a62de61853a0cb1d98b440a3586fSungsoo // This fragment automatically adds or removes a callback whenever the activity 232f796be9c80d6a62de61853a0cb1d98b440a3586fSungsoo // is started or stopped. 233f796be9c80d6a62de61853a0cb1d98b440a3586fSungsoo FragmentManager fm = getSupportFragmentManager(); 234f796be9c80d6a62de61853a0cb1d98b440a3586fSungsoo DiscoveryFragment fragment = (DiscoveryFragment) fm.findFragmentByTag( 235f796be9c80d6a62de61853a0cb1d98b440a3586fSungsoo DISCOVERY_FRAGMENT_TAG); 236f796be9c80d6a62de61853a0cb1d98b440a3586fSungsoo if (fragment == null) { 23711cd4963ab66125d66342bde773559da74611cd5Donghyun Cho fragment = new DiscoveryFragment(); 238f796be9c80d6a62de61853a0cb1d98b440a3586fSungsoo fm.beginTransaction() 239f796be9c80d6a62de61853a0cb1d98b440a3586fSungsoo .add(fragment, DISCOVERY_FRAGMENT_TAG) 240f796be9c80d6a62de61853a0cb1d98b440a3586fSungsoo .commit(); 241f796be9c80d6a62de61853a0cb1d98b440a3586fSungsoo } 24211cd4963ab66125d66342bde773559da74611cd5Donghyun Cho fragment.setCallback(mMediaRouterCB); 24311cd4963ab66125d66342bde773559da74611cd5Donghyun Cho fragment.setRouteSelector(mSelector); 244f0dd451048100915f072423730a93d17c53fd899Jeff Brown 24557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang // Populate an array adapter with streaming media items. 246ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown String[] mediaNames = getResources().getStringArray(R.array.media_names); 247ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown String[] mediaUris = getResources().getStringArray(R.array.media_uris); 24857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang mLibraryItems = new LibraryAdapter(); 249ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown for (int i = 0; i < mediaNames.length; i++) { 25057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang mLibraryItems.add(new MediaItem( 251a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang "[streaming] "+mediaNames[i], Uri.parse(mediaUris[i]), "video/mp4")); 252ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown } 253ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown 25445ca8fb42505658590e808d4d30b57598689d9a8Jeff Brown // Scan local external storage directory for media files. 25545ca8fb42505658590e808d4d30b57598689d9a8Jeff Brown File externalDir = Environment.getExternalStorageDirectory(); 25645ca8fb42505658590e808d4d30b57598689d9a8Jeff Brown if (externalDir != null) { 25745ca8fb42505658590e808d4d30b57598689d9a8Jeff Brown File list[] = externalDir.listFiles(); 25845ca8fb42505658590e808d4d30b57598689d9a8Jeff Brown if (list != null) { 25945ca8fb42505658590e808d4d30b57598689d9a8Jeff Brown for (int i = 0; i < list.length; i++) { 26045ca8fb42505658590e808d4d30b57598689d9a8Jeff Brown String filename = list[i].getName(); 26145ca8fb42505658590e808d4d30b57598689d9a8Jeff Brown if (filename.matches(".*\\.(m4v|mp4)")) { 26245ca8fb42505658590e808d4d30b57598689d9a8Jeff Brown mLibraryItems.add(new MediaItem("[local] " + filename, 263a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang Uri.fromFile(list[i]), "video/mp4")); 26445ca8fb42505658590e808d4d30b57598689d9a8Jeff Brown } 26545ca8fb42505658590e808d4d30b57598689d9a8Jeff Brown } 26657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 26757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 26857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 26957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang mPlayListItems = new PlaylistAdapter(); 27057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 271ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown // Initialize the layout. 272ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown setContentView(R.layout.sample_media_router); 273ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown 27457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang TabHost tabHost=(TabHost)findViewById(R.id.tabHost); 27557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang tabHost.setup(); 27657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang String tabName = getResources().getString(R.string.library_tab_text); 27757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang TabSpec spec1=tabHost.newTabSpec(tabName); 27857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang spec1.setContent(R.id.tab1); 27957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang spec1.setIndicator(tabName); 28057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 28157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang tabName = getResources().getString(R.string.playlist_tab_text); 28257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang TabSpec spec2=tabHost.newTabSpec(tabName); 28357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang spec2.setIndicator(tabName); 28457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang spec2.setContent(R.id.tab2); 28557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 286cf61a6ed2bfa6141b832fdc40a9fbfb70af91416Chong Zhang tabName = getResources().getString(R.string.info_tab_text); 28757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang TabSpec spec3=tabHost.newTabSpec(tabName); 28857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang spec3.setIndicator(tabName); 28957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang spec3.setContent(R.id.tab3); 29057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 29157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang tabHost.addTab(spec1); 29257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang tabHost.addTab(spec2); 29357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang tabHost.addTab(spec3); 29457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang tabHost.setOnTabChangedListener(new OnTabChangeListener() { 29557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang @Override 29657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang public void onTabChanged(String arg0) { 29757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang updateUi(); 29857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 29957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang }); 30057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 301fa2e2acf79d791a90410025daad438968550d18cAlan Viverette mLibraryView = findViewById(R.id.media); 30257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang mLibraryView.setAdapter(mLibraryItems); 30357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang mLibraryView.setChoiceMode(ListView.CHOICE_MODE_SINGLE); 30457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang mLibraryView.setOnItemClickListener(new OnItemClickListener() { 30557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang @Override 30657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang public void onItemClick(AdapterView<?> parent, View view, int position, long id) { 30757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang updateButtons(); 30857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 30957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang }); 310ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown 311fa2e2acf79d791a90410025daad438968550d18cAlan Viverette mPlayListView = findViewById(R.id.playlist); 31257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang mPlayListView.setAdapter(mPlayListItems); 31357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang mPlayListView.setChoiceMode(ListView.CHOICE_MODE_SINGLE); 31457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang mPlayListView.setOnItemClickListener(new OnItemClickListener() { 315ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown @Override 316ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown public void onItemClick(AdapterView<?> parent, View view, int position, long id) { 317ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown updateButtons(); 318ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown } 319ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown }); 320ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown 321fa2e2acf79d791a90410025daad438968550d18cAlan Viverette mInfoTextView = findViewById(R.id.info); 32257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 323fa2e2acf79d791a90410025daad438968550d18cAlan Viverette mUseDefaultControlCheckBox = findViewById(R.id.custom_control_view_checkbox); 32476d965dc41863b33f887db33d283cb7f1523f60dJae Seo if (ENABLE_DEFAULT_CONTROL_CHECK_BOX) { 32576d965dc41863b33f887db33d283cb7f1523f60dJae Seo mUseDefaultControlCheckBox.setVisibility(View.VISIBLE); 32676d965dc41863b33f887db33d283cb7f1523f60dJae Seo } 32757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang mPauseResumeButton = (ImageButton)findViewById(R.id.pause_resume_button); 32857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang mPauseResumeButton.setOnClickListener(new OnClickListener() { 329ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown @Override 330ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown public void onClick(View v) { 331cf61a6ed2bfa6141b832fdc40a9fbfb70af91416Chong Zhang if (mSessionManager.isPaused()) { 332a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang mSessionManager.resume(); 333cf61a6ed2bfa6141b832fdc40a9fbfb70af91416Chong Zhang } else { 334cf61a6ed2bfa6141b832fdc40a9fbfb70af91416Chong Zhang mSessionManager.pause(); 33557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 336ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown } 337ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown }); 338ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown 33957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang mStopButton = (ImageButton)findViewById(R.id.stop_button); 34057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang mStopButton.setOnClickListener(new OnClickListener() { 341ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown @Override 342ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown public void onClick(View v) { 343a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang mSessionManager.stop(); 344ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown } 345ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown }); 34657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 347fa2e2acf79d791a90410025daad438968550d18cAlan Viverette mSeekBar = findViewById(R.id.seekbar); 34857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang mSeekBar.setOnSeekBarChangeListener(new OnSeekBarChangeListener() { 34957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang @Override 35057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { 351a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang PlaylistItem item = getCheckedPlaylistItem(); 352a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang if (fromUser && item != null && item.getDuration() > 0) { 353a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang long pos = progress * item.getDuration() / 100; 354a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang mSessionManager.seek(item.getItemId(), pos); 355a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang item.setPosition(pos); 356a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang item.setTimestamp(SystemClock.elapsedRealtime()); 35757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 35857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 35957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang @Override 36057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang public void onStartTrackingTouch(SeekBar seekBar) { 36157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang mSeeking = true; 36257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 36357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang @Override 36457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang public void onStopTrackingTouch(SeekBar seekBar) { 36557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang mSeeking = false; 36657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang updateUi(); 36757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 36857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang }); 36957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 37057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang // Schedule Ui update 37157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang mHandler.postDelayed(mUpdateSeekRunnable, 1000); 37257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 3737578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang // Build the PendingIntent for the remote control client 3747578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang mAudioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE); 3757578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang mEventReceiver = new ComponentName(getPackageName(), 3767578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang SampleMediaButtonReceiver.class.getName()); 3777578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang Intent mediaButtonIntent = new Intent(Intent.ACTION_MEDIA_BUTTON); 3787578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang mediaButtonIntent.setComponent(mEventReceiver); 3797578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang mMediaPendingIntent = PendingIntent.getBroadcast(this, 0, mediaButtonIntent, 0); 3807b95dd38981772983f00c5ed91aca4b30b782facJeff Brown 3817b95dd38981772983f00c5ed91aca4b30b782facJeff Brown // Create and register the remote control client 3829a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik createMediaSession(); 3839a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik mMediaRouter.setMediaSessionCompat(mMediaSession); 384a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang 385a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang // Set up playback manager and player 386a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang mPlayer = Player.create(SampleMediaRouterActivity.this, 3879a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik mMediaRouter.getSelectedRoute(), mMediaSession); 3885d429bc3a8195d6f37cf2f7da0935972950539b4RoboErik 389a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang mSessionManager.setPlayer(mPlayer); 390a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang mSessionManager.setCallback(new SessionManager.Callback() { 391a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang @Override 392a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang public void onStatusChanged() { 393a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang updateUi(); 394a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang } 395a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang 396a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang @Override 397a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang public void onItemChanged(PlaylistItem item) { 398a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang } 399a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang }); 400a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang 401a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang updateUi(); 4027578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang } 4037578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang 4049a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik private void createMediaSession() { 4059a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik // Create the MediaSession 4069a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik mMediaSession = new MediaSessionCompat(this, "SampleMediaRouter", mEventReceiver, 4079a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik mMediaPendingIntent); 4089a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik mMediaSession.setFlags(MediaSessionCompat.FLAG_HANDLES_MEDIA_BUTTONS 4099a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik | MediaSessionCompat.FLAG_HANDLES_TRANSPORT_CONTROLS); 4109a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik mMediaSession.setCallback(new MediaSessionCompat.Callback() { 4119a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik @Override 4129a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik public boolean onMediaButtonEvent(Intent mediaButtonEvent) { 4139a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik if (mediaButtonEvent != null) { 4149a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik return handleMediaKey( 4159a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik (KeyEvent) mediaButtonEvent.getParcelableExtra(Intent.EXTRA_KEY_EVENT)); 4169a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik } 4179a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik return super.onMediaButtonEvent(mediaButtonEvent); 4189a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik } 4197578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang 4209a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik @Override 4219a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik public void onPlay() { 4229a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik mSessionManager.resume(); 4239a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik } 4249a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik 4259a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik @Override 4269a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik public void onPause() { 4279a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik mSessionManager.pause(); 4289a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik } 4299a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik }); 4309a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik 4319a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik SampleMediaButtonReceiver.setActivity(SampleMediaRouterActivity.this); 4327578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang } 4337578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang 4347578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang public boolean handleMediaKey(KeyEvent event) { 4359a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik if (event != null && event.getAction() == KeyEvent.ACTION_DOWN 4369a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik && event.getRepeatCount() == 0) { 4377578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang switch (event.getKeyCode()) { 4387578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang case KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE: 4399a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik case KeyEvent.KEYCODE_HEADSETHOOK: 4407578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang { 4417578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang Log.d(TAG, "Received Play/Pause event from RemoteControlClient"); 442cf61a6ed2bfa6141b832fdc40a9fbfb70af91416Chong Zhang if (mSessionManager.isPaused()) { 443a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang mSessionManager.resume(); 444cf61a6ed2bfa6141b832fdc40a9fbfb70af91416Chong Zhang } else { 445cf61a6ed2bfa6141b832fdc40a9fbfb70af91416Chong Zhang mSessionManager.pause(); 4467578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang } 4477578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang return true; 4487578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang } 4497578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang case KeyEvent.KEYCODE_MEDIA_PLAY: 4507578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang { 4517578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang Log.d(TAG, "Received Play event from RemoteControlClient"); 452cf61a6ed2bfa6141b832fdc40a9fbfb70af91416Chong Zhang if (mSessionManager.isPaused()) { 453a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang mSessionManager.resume(); 4547578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang } 4557578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang return true; 4567578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang } 4577578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang case KeyEvent.KEYCODE_MEDIA_PAUSE: 4587578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang { 4597578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang Log.d(TAG, "Received Pause event from RemoteControlClient"); 460cf61a6ed2bfa6141b832fdc40a9fbfb70af91416Chong Zhang if (!mSessionManager.isPaused()) { 461a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang mSessionManager.pause(); 4627578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang } 4637578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang return true; 4647578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang } 4657578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang case KeyEvent.KEYCODE_MEDIA_STOP: 4667578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang { 4677578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang Log.d(TAG, "Received Stop event from RemoteControlClient"); 468a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang mSessionManager.stop(); 4697578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang return true; 4707578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang } 4717578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang default: 4727578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang break; 4737578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang } 4747578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang } 4757578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang return false; 4767578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang } 4777578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang 4787578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang @Override 4797578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang public boolean onKeyDown(int keyCode, KeyEvent event) { 4807578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang return handleMediaKey(event) || super.onKeyDown(keyCode, event); 4817578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang } 4827578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang 4837578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang @Override 4847578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang public boolean onKeyUp(int keyCode, KeyEvent event) { 4857578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang return handleMediaKey(event) || super.onKeyUp(keyCode, event); 486ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown } 487ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown 488ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown @Override 489f0dd451048100915f072423730a93d17c53fd899Jeff Brown public void onStart() { 490ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown // Be sure to call the super class. 491f0dd451048100915f072423730a93d17c53fd899Jeff Brown super.onStart(); 49257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 493ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown 49457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang @Override 49557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang public void onPause() { 49657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang // pause media player for local playback case only 497cf61a6ed2bfa6141b832fdc40a9fbfb70af91416Chong Zhang if (!mPlayer.isRemotePlayback() && !mSessionManager.isPaused()) { 49857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang mNeedResume = true; 499a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang mSessionManager.pause(); 50057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 50157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang super.onPause(); 50257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 50357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 50457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang @Override 50557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang public void onResume() { 50657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang // resume media player for local playback case only 507a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang if (!mPlayer.isRemotePlayback() && mNeedResume) { 508a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang mSessionManager.resume(); 50957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang mNeedResume = false; 51057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 51157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang super.onResume(); 51257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 51357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 51457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang @Override 51557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang public void onDestroy() { 516a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang mSessionManager.stop(); 517a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang mPlayer.release(); 5189a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik mMediaSession.release(); 51957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang super.onDestroy(); 520ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown } 521ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown 522ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown @Override 523ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown public boolean onCreateOptionsMenu(Menu menu) { 524ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown // Be sure to call the super class. 525ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown super.onCreateOptionsMenu(menu); 526ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown 527ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown // Inflate the menu and configure the media router action provider. 528ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown getMenuInflater().inflate(R.menu.sample_media_router_menu, menu); 529ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown 53055e47d370890d3cbdab82857090c42df734ba276Jeff Brown MenuItem mediaRouteMenuItem = menu.findItem(R.id.media_route_menu_item); 531f796be9c80d6a62de61853a0cb1d98b440a3586fSungsoo MediaRouteActionProvider mediaRouteActionProvider = 532f796be9c80d6a62de61853a0cb1d98b440a3586fSungsoo (MediaRouteActionProvider) MenuItemCompat.getActionProvider(mediaRouteMenuItem); 53355e47d370890d3cbdab82857090c42df734ba276Jeff Brown mediaRouteActionProvider.setRouteSelector(mSelector); 534cf61a6ed2bfa6141b832fdc40a9fbfb70af91416Chong Zhang mediaRouteActionProvider.setDialogFactory(new MediaRouteDialogFactory() { 535cf61a6ed2bfa6141b832fdc40a9fbfb70af91416Chong Zhang @Override 536cf61a6ed2bfa6141b832fdc40a9fbfb70af91416Chong Zhang public MediaRouteControllerDialogFragment onCreateControllerDialogFragment() { 53776d965dc41863b33f887db33d283cb7f1523f60dJae Seo return new ControllerDialogFragment(mPlayer, mUseDefaultControlCheckBox); 538cf61a6ed2bfa6141b832fdc40a9fbfb70af91416Chong Zhang } 539cf61a6ed2bfa6141b832fdc40a9fbfb70af91416Chong Zhang }); 540ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown 541ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown // Return true to show the menu. 542ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown return true; 543ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown } 544ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown 545a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang private void updateProgress() { 54657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang // Estimate content position from last status time and elapsed time. 54757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang // (Note this might be slightly out of sync with remote side, however 54857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang // it avoids frequent polling the MRP.) 54957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang int progress = 0; 550a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang PlaylistItem item = getCheckedPlaylistItem(); 551a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang if (item != null) { 552a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang int state = item.getState(); 553a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang long duration = item.getDuration(); 55457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang if (duration <= 0) { 55557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang if (state == MediaItemStatus.PLAYBACK_STATE_PLAYING 55657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang || state == MediaItemStatus.PLAYBACK_STATE_PAUSED) { 557a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang mSessionManager.updateStatus(); 55857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 55957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } else { 560a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang long position = item.getPosition(); 561cf61a6ed2bfa6141b832fdc40a9fbfb70af91416Chong Zhang long timeDelta = mSessionManager.isPaused() ? 0 : 562a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang (SystemClock.elapsedRealtime() - item.getTimestamp()); 56357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang progress = (int)(100.0 * (position + timeDelta) / duration); 56457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 565ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown } 56657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang mSeekBar.setProgress(progress); 56757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 568ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown 56957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang private void updateUi() { 57057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang updatePlaylist(); 571a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang updateRouteDescription(); 57257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang updateButtons(); 57370f3627685b55b2bc1b3f0c17c9c30aa3a7fd062Donghyun Cho if (mPlayer != null && mSessionManager != null) { 57470f3627685b55b2bc1b3f0c17c9c30aa3a7fd062Donghyun Cho PlaylistItem currentItem = mSessionManager.getCurrentItem(); 57570f3627685b55b2bc1b3f0c17c9c30aa3a7fd062Donghyun Cho if (currentItem != null) { 57670f3627685b55b2bc1b3f0c17c9c30aa3a7fd062Donghyun Cho mPlayer.updateMetadata(currentItem); 57770f3627685b55b2bc1b3f0c17c9c30aa3a7fd062Donghyun Cho int currentItemState = Player.STATE_IDLE; 57870f3627685b55b2bc1b3f0c17c9c30aa3a7fd062Donghyun Cho switch(currentItem.getState()) { 57970f3627685b55b2bc1b3f0c17c9c30aa3a7fd062Donghyun Cho case MediaItemStatus.PLAYBACK_STATE_PLAYING: 58070f3627685b55b2bc1b3f0c17c9c30aa3a7fd062Donghyun Cho currentItemState = Player.STATE_PLAYING; 58170f3627685b55b2bc1b3f0c17c9c30aa3a7fd062Donghyun Cho break; 58270f3627685b55b2bc1b3f0c17c9c30aa3a7fd062Donghyun Cho case MediaItemStatus.PLAYBACK_STATE_PAUSED: 58370f3627685b55b2bc1b3f0c17c9c30aa3a7fd062Donghyun Cho currentItemState = Player.STATE_PAUSED; 58470f3627685b55b2bc1b3f0c17c9c30aa3a7fd062Donghyun Cho break; 58570f3627685b55b2bc1b3f0c17c9c30aa3a7fd062Donghyun Cho case MediaItemStatus.PLAYBACK_STATE_PENDING: 58670f3627685b55b2bc1b3f0c17c9c30aa3a7fd062Donghyun Cho case MediaItemStatus.PLAYBACK_STATE_BUFFERING: 58770f3627685b55b2bc1b3f0c17c9c30aa3a7fd062Donghyun Cho currentItemState = Player.STATE_PREPARING_FOR_PLAY; 58870f3627685b55b2bc1b3f0c17c9c30aa3a7fd062Donghyun Cho break; 58970f3627685b55b2bc1b3f0c17c9c30aa3a7fd062Donghyun Cho } 59070f3627685b55b2bc1b3f0c17c9c30aa3a7fd062Donghyun Cho mPlayer.publishState(currentItemState); 59170f3627685b55b2bc1b3f0c17c9c30aa3a7fd062Donghyun Cho } 592cf61a6ed2bfa6141b832fdc40a9fbfb70af91416Chong Zhang } 593ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown } 594ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown 59557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang private void updatePlaylist() { 59657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang mPlayListItems.clear(); 597a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang for (PlaylistItem item : mSessionManager.getPlaylist()) { 598a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang mPlayListItems.add(item); 599a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang } 60057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang mPlayListView.invalidate(); 601a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang } 602ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown 603a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang private void updateRouteDescription() { 604a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang RouteInfo route = mMediaRouter.getSelectedRoute(); 605a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang mInfoTextView.setText("Currently selected route:" 606a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang + "\nName: " + route.getName() 60770f3627685b55b2bc1b3f0c17c9c30aa3a7fd062Donghyun Cho + "\nProvider: " + route.getProvider().getPackageName()); 60857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 609fcb6a9d1caaf43ae41f859ebb58a4483b12475a1Jeff Brown 610a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang private void updateButtons() { 611a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang MediaRouter.RouteInfo route = mMediaRouter.getSelectedRoute(); 612a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang // show pause or resume icon depending on current state 613cf61a6ed2bfa6141b832fdc40a9fbfb70af91416Chong Zhang mPauseResumeButton.setImageResource(mSessionManager.isPaused() ? 614a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang R.drawable.ic_media_play : R.drawable.ic_media_pause); 615a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang // only enable seek bar when duration is known 616a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang PlaylistItem item = getCheckedPlaylistItem(); 617a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang mSeekBar.setEnabled(item != null && item.getDuration() > 0); 61857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 619ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown 620a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang private PlaylistItem getCheckedPlaylistItem() { 62157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang int count = mPlayListView.getCount(); 62257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang int index = mPlayListView.getCheckedItemPosition(); 62357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang if (count > 0) { 62457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang if (index < 0 || index >= count) { 62557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang index = 0; 62657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang mPlayListView.setItemChecked(0, true); 62757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 62857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang return mPlayListItems.getItem(index); 629ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown } 63057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang return null; 631ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown } 632ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown 633f796be9c80d6a62de61853a0cb1d98b440a3586fSungsoo /** 634f796be9c80d6a62de61853a0cb1d98b440a3586fSungsoo * Media route discovery fragment. 635f796be9c80d6a62de61853a0cb1d98b440a3586fSungsoo */ 636f796be9c80d6a62de61853a0cb1d98b440a3586fSungsoo public static final class DiscoveryFragment extends MediaRouteDiscoveryFragment { 637f796be9c80d6a62de61853a0cb1d98b440a3586fSungsoo private static final String TAG = "DiscoveryFragment"; 638f796be9c80d6a62de61853a0cb1d98b440a3586fSungsoo private Callback mCallback; 639f796be9c80d6a62de61853a0cb1d98b440a3586fSungsoo 640f796be9c80d6a62de61853a0cb1d98b440a3586fSungsoo public void setCallback(Callback cb) { 641f796be9c80d6a62de61853a0cb1d98b440a3586fSungsoo mCallback = cb; 642f796be9c80d6a62de61853a0cb1d98b440a3586fSungsoo } 643f796be9c80d6a62de61853a0cb1d98b440a3586fSungsoo 644f796be9c80d6a62de61853a0cb1d98b440a3586fSungsoo @Override 645f796be9c80d6a62de61853a0cb1d98b440a3586fSungsoo public Callback onCreateCallback() { 646f796be9c80d6a62de61853a0cb1d98b440a3586fSungsoo return mCallback; 647f796be9c80d6a62de61853a0cb1d98b440a3586fSungsoo } 648f796be9c80d6a62de61853a0cb1d98b440a3586fSungsoo 649f796be9c80d6a62de61853a0cb1d98b440a3586fSungsoo @Override 650f796be9c80d6a62de61853a0cb1d98b440a3586fSungsoo public int onPrepareCallbackFlags() { 651f796be9c80d6a62de61853a0cb1d98b440a3586fSungsoo // Add the CALLBACK_FLAG_UNFILTERED_EVENTS flag to ensure that we will 652f796be9c80d6a62de61853a0cb1d98b440a3586fSungsoo // observe and log all route events including those that are for routes 653f796be9c80d6a62de61853a0cb1d98b440a3586fSungsoo // that do not match our selector. This is only for demonstration purposes 654f796be9c80d6a62de61853a0cb1d98b440a3586fSungsoo // and should not be needed by most applications. 655f796be9c80d6a62de61853a0cb1d98b440a3586fSungsoo return super.onPrepareCallbackFlags() 656f796be9c80d6a62de61853a0cb1d98b440a3586fSungsoo | MediaRouter.CALLBACK_FLAG_UNFILTERED_EVENTS; 657f796be9c80d6a62de61853a0cb1d98b440a3586fSungsoo } 658f796be9c80d6a62de61853a0cb1d98b440a3586fSungsoo } 659f796be9c80d6a62de61853a0cb1d98b440a3586fSungsoo 660ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown private static final class MediaItem { 661ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown public final String mName; 662ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown public final Uri mUri; 663a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang public final String mMime; 664ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown 665a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang public MediaItem(String name, Uri uri, String mime) { 666ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown mName = name; 667ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown mUri = uri; 668a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang mMime = mime; 669ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown } 670ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown 671ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown @Override 672ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown public String toString() { 673ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown return mName; 674ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown } 675ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown } 67655e47d370890d3cbdab82857090c42df734ba276Jeff Brown 67757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang private final class LibraryAdapter extends ArrayAdapter<MediaItem> { 67857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang public LibraryAdapter() { 67957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang super(SampleMediaRouterActivity.this, R.layout.media_item); 68057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 68157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 68257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang @Override 68357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang public View getView(int position, View convertView, ViewGroup parent) { 68457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang final View v; 68557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang if (convertView == null) { 68657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang v = getLayoutInflater().inflate(R.layout.media_item, null); 68757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } else { 68857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang v = convertView; 68957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 69057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 69157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang final MediaItem item = getItem(position); 69257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 69357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang TextView tv = (TextView)v.findViewById(R.id.item_text); 69457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang tv.setText(item.mName); 69557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 69657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang ImageButton b = (ImageButton)v.findViewById(R.id.item_action); 69757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang b.setImageResource(R.drawable.ic_menu_add); 69857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang b.setTag(item); 69957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang b.setOnClickListener(new OnClickListener() { 70057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang @Override 70157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang public void onClick(View v) { 70257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang if (item != null) { 70370f3627685b55b2bc1b3f0c17c9c30aa3a7fd062Donghyun Cho mSessionManager.add(item.mName, item.mUri, item.mMime); 70457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 70557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 70657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang }); 70757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 70857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang return v; 70957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 71057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 71157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 712a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang private final class PlaylistAdapter extends ArrayAdapter<PlaylistItem> { 71357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang public PlaylistAdapter() { 71457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang super(SampleMediaRouterActivity.this, R.layout.media_item); 71557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 71657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 71757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang @Override 71857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang public View getView(int position, View convertView, ViewGroup parent) { 71957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang final View v; 72057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang if (convertView == null) { 72157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang v = getLayoutInflater().inflate(R.layout.media_item, null); 72257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } else { 72357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang v = convertView; 72457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 72557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 726a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang final PlaylistItem item = getItem(position); 72757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 72857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang TextView tv = (TextView)v.findViewById(R.id.item_text); 72957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang tv.setText(item.toString()); 73057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 73157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang ImageButton b = (ImageButton)v.findViewById(R.id.item_action); 73257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang b.setImageResource(R.drawable.ic_menu_delete); 73357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang b.setTag(item); 73457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang b.setOnClickListener(new OnClickListener() { 73557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang @Override 73657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang public void onClick(View v) { 73757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang if (item != null) { 738a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang mSessionManager.remove(item.getItemId()); 73957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 74057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 74157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang }); 74257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 74357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang return v; 74457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 74557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 74657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 74755e47d370890d3cbdab82857090c42df734ba276Jeff Brown /** 74855e47d370890d3cbdab82857090c42df734ba276Jeff Brown * Trivial subclass of this activity used to provide another copy of the 74955e47d370890d3cbdab82857090c42df734ba276Jeff Brown * same activity using a light theme instead of the dark theme. 75055e47d370890d3cbdab82857090c42df734ba276Jeff Brown */ 75155e47d370890d3cbdab82857090c42df734ba276Jeff Brown public static class Light extends SampleMediaRouterActivity { 75255e47d370890d3cbdab82857090c42df734ba276Jeff Brown } 75355e47d370890d3cbdab82857090c42df734ba276Jeff Brown 75455e47d370890d3cbdab82857090c42df734ba276Jeff Brown /** 75555e47d370890d3cbdab82857090c42df734ba276Jeff Brown * Trivial subclass of this activity used to provide another copy of the 75655e47d370890d3cbdab82857090c42df734ba276Jeff Brown * same activity using a light theme with dark action bar instead of the dark theme. 75755e47d370890d3cbdab82857090c42df734ba276Jeff Brown */ 75855e47d370890d3cbdab82857090c42df734ba276Jeff Brown public static class LightWithDarkActionBar extends SampleMediaRouterActivity { 75955e47d370890d3cbdab82857090c42df734ba276Jeff Brown } 7605d429bc3a8195d6f37cf2f7da0935972950539b4RoboErik 7615d429bc3a8195d6f37cf2f7da0935972950539b4RoboErik public static class ControllerDialogFragment extends MediaRouteControllerDialogFragment { 7625d429bc3a8195d6f37cf2f7da0935972950539b4RoboErik private MediaRouteControllerDialog mControllerDialog; 7635d429bc3a8195d6f37cf2f7da0935972950539b4RoboErik private Player mPlayer; 76476d965dc41863b33f887db33d283cb7f1523f60dJae Seo private CheckBox mUseDefaultControlCheckBox; 7655d429bc3a8195d6f37cf2f7da0935972950539b4RoboErik 7665d429bc3a8195d6f37cf2f7da0935972950539b4RoboErik public ControllerDialogFragment() { 7675d429bc3a8195d6f37cf2f7da0935972950539b4RoboErik super(); 7685d429bc3a8195d6f37cf2f7da0935972950539b4RoboErik } 7695d429bc3a8195d6f37cf2f7da0935972950539b4RoboErik 77076d965dc41863b33f887db33d283cb7f1523f60dJae Seo public ControllerDialogFragment(Player player, CheckBox customControlViewCheckBox) { 7715d429bc3a8195d6f37cf2f7da0935972950539b4RoboErik mPlayer = player; 77276d965dc41863b33f887db33d283cb7f1523f60dJae Seo this.mUseDefaultControlCheckBox = customControlViewCheckBox; 7735d429bc3a8195d6f37cf2f7da0935972950539b4RoboErik } 7745d429bc3a8195d6f37cf2f7da0935972950539b4RoboErik 7755d429bc3a8195d6f37cf2f7da0935972950539b4RoboErik @Override 7765d429bc3a8195d6f37cf2f7da0935972950539b4RoboErik public MediaRouteControllerDialog onCreateControllerDialog( 7775d429bc3a8195d6f37cf2f7da0935972950539b4RoboErik Context context, Bundle savedInstanceState) { 77876d965dc41863b33f887db33d283cb7f1523f60dJae Seo mControllerDialog = this.mUseDefaultControlCheckBox.isChecked() 77976d965dc41863b33f887db33d283cb7f1523f60dJae Seo ? super.onCreateControllerDialog(context, savedInstanceState) 78076d965dc41863b33f887db33d283cb7f1523f60dJae Seo : new MyMediaRouteControllerDialog(context); 7815d429bc3a8195d6f37cf2f7da0935972950539b4RoboErik mControllerDialog.setOnDismissListener(new DialogInterface.OnDismissListener() { 7825d429bc3a8195d6f37cf2f7da0935972950539b4RoboErik @Override 7835d429bc3a8195d6f37cf2f7da0935972950539b4RoboErik public void onDismiss(DialogInterface dialog) { 7845d429bc3a8195d6f37cf2f7da0935972950539b4RoboErik mControllerDialog = null; 7855d429bc3a8195d6f37cf2f7da0935972950539b4RoboErik } 7865d429bc3a8195d6f37cf2f7da0935972950539b4RoboErik }); 7875d429bc3a8195d6f37cf2f7da0935972950539b4RoboErik return mControllerDialog; 7885d429bc3a8195d6f37cf2f7da0935972950539b4RoboErik } 7895d429bc3a8195d6f37cf2f7da0935972950539b4RoboErik 7905d429bc3a8195d6f37cf2f7da0935972950539b4RoboErik public void setPlayer(Player player) { 7915d429bc3a8195d6f37cf2f7da0935972950539b4RoboErik mPlayer = player; 7925d429bc3a8195d6f37cf2f7da0935972950539b4RoboErik } 7935d429bc3a8195d6f37cf2f7da0935972950539b4RoboErik } 794ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown} 795