SampleMediaRouterActivity.java revision 0e573df7dcd4a3062e76627f26ee2ee377eebfae
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; 320e573df7dcd4a3062e76627f26ee2ee377eebfaeHyundo Moonimport android.provider.Settings; 33f796be9c80d6a62de61853a0cb1d98b440a3586fSungsooimport 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; 41f796be9c80d6a62de61853a0cb1d98b440a3586fSungsooimport 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; 46f796be9c80d6a62de61853a0cb1d98b440a3586fSungsooimport 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 69c1a24039658cc52f34046800790de302b7db075bSungsoo Limimport com.example.android.supportv7.R; 70c1a24039658cc52f34046800790de302b7db075bSungsoo Lim 7157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhangimport java.io.File; 72ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown 73ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown/** 74ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown * <h3>Media Router Support Activity</h3> 75ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown * 76ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown * <p> 77ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown * This demonstrates how to use the {@link MediaRouter} API to build an 78ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown * application that allows the user to send content to various rendering 79ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown * targets. 80ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown * </p> 81ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown */ 8244d25261c2a38c81f1eea123de3986b453b9afeeChris Banespublic class SampleMediaRouterActivity extends AppCompatActivity { 83a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang private static final String TAG = "SampleMediaRouterActivity"; 84f0dd451048100915f072423730a93d17c53fd899Jeff Brown private static final String DISCOVERY_FRAGMENT_TAG = "DiscoveryFragment"; 8576d965dc41863b33f887db33d283cb7f1523f60dJae Seo private static final boolean ENABLE_DEFAULT_CONTROL_CHECK_BOX = false; 86ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown 87ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown private MediaRouter mMediaRouter; 8855e47d370890d3cbdab82857090c42df734ba276Jeff Brown private MediaRouteSelector mSelector; 8957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang private LibraryAdapter mLibraryItems; 9057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang private PlaylistAdapter mPlayListItems; 91ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown private TextView mInfoTextView; 9257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang private ListView mLibraryView; 9357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang private ListView mPlayListView; 9476d965dc41863b33f887db33d283cb7f1523f60dJae Seo private CheckBox mUseDefaultControlCheckBox; 9557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang private ImageButton mPauseResumeButton; 9657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang private ImageButton mStopButton; 9757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang private SeekBar mSeekBar; 9857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang private boolean mNeedResume; 9957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang private boolean mSeeking; 10057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 10157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang private final Handler mHandler = new Handler(); 10257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang private final Runnable mUpdateSeekRunnable = new Runnable() { 10357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang @Override 10457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang public void run() { 105a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang updateProgress(); 10657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang // update Ui every 1 second 10757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang mHandler.postDelayed(this, 1000); 10857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 10957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang }; 11057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 111a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang private final SessionManager mSessionManager = new SessionManager("app"); 11257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang private Player mPlayer; 11357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 11457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang private final MediaRouter.Callback mMediaRouterCB = new MediaRouter.Callback() { 11557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang // Return a custom callback that will simply log all of the route events 11657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang // for demonstration purposes. 11757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang @Override 11857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang public void onRouteAdded(MediaRouter router, RouteInfo route) { 11957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang Log.d(TAG, "onRouteAdded: route=" + route); 12057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 12157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 12257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang @Override 12357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang public void onRouteChanged(MediaRouter router, RouteInfo route) { 12457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang Log.d(TAG, "onRouteChanged: route=" + route); 12557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 12657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 12757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang @Override 12857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang public void onRouteRemoved(MediaRouter router, RouteInfo route) { 12957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang Log.d(TAG, "onRouteRemoved: route=" + route); 13057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 13157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 13257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang @Override 13357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang public void onRouteSelected(MediaRouter router, RouteInfo route) { 13457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang Log.d(TAG, "onRouteSelected: route=" + route); 13557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 1369a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik mPlayer = Player.create(SampleMediaRouterActivity.this, route, mMediaSession); 13761636870e0a12db5909955eca58e0070357dde42Donghyun Cho if (isPresentationApiSupported()) { 13861636870e0a12db5909955eca58e0070357dde42Donghyun Cho mPlayer.updatePresentation(); 13961636870e0a12db5909955eca58e0070357dde42Donghyun Cho } 140a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang mSessionManager.setPlayer(mPlayer); 141a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang mSessionManager.unsuspend(); 14257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 14357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang updateUi(); 14457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 14557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 14657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang @Override 14757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang public void onRouteUnselected(MediaRouter router, RouteInfo route) { 14857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang Log.d(TAG, "onRouteUnselected: route=" + route); 1499a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik mMediaSession.setActive(false); 150a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang 151a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang PlaylistItem item = getCheckedPlaylistItem(); 152a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang if (item != null) { 153cf61a6ed2bfa6141b832fdc40a9fbfb70af91416Chong Zhang long pos = item.getPosition() + (mSessionManager.isPaused() ? 154a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang 0 : (SystemClock.elapsedRealtime() - item.getTimestamp())); 155a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang mSessionManager.suspend(pos); 156a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang } 15761636870e0a12db5909955eca58e0070357dde42Donghyun Cho if (isPresentationApiSupported()) { 15861636870e0a12db5909955eca58e0070357dde42Donghyun Cho mPlayer.updatePresentation(); 15961636870e0a12db5909955eca58e0070357dde42Donghyun Cho } 160a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang mPlayer.release(); 16157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 16257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 16357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang @Override 16457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang public void onRouteVolumeChanged(MediaRouter router, RouteInfo route) { 16557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang Log.d(TAG, "onRouteVolumeChanged: route=" + route); 16657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 16757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 16857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang @Override 16957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang public void onRoutePresentationDisplayChanged( 17057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang MediaRouter router, RouteInfo route) { 17157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang Log.d(TAG, "onRoutePresentationDisplayChanged: route=" + route); 17261636870e0a12db5909955eca58e0070357dde42Donghyun Cho if (isPresentationApiSupported()) { 17361636870e0a12db5909955eca58e0070357dde42Donghyun Cho mPlayer.updatePresentation(); 17461636870e0a12db5909955eca58e0070357dde42Donghyun Cho } 17557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 17657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 17757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang @Override 17857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang public void onProviderAdded(MediaRouter router, ProviderInfo provider) { 17957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang Log.d(TAG, "onRouteProviderAdded: provider=" + provider); 18057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 18157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 18257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang @Override 18357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang public void onProviderRemoved(MediaRouter router, ProviderInfo provider) { 18457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang Log.d(TAG, "onRouteProviderRemoved: provider=" + provider); 18557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 18657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 18757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang @Override 18857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang public void onProviderChanged(MediaRouter router, ProviderInfo provider) { 18957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang Log.d(TAG, "onRouteProviderChanged: provider=" + provider); 19057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 19161636870e0a12db5909955eca58e0070357dde42Donghyun Cho 19261636870e0a12db5909955eca58e0070357dde42Donghyun Cho private boolean isPresentationApiSupported() { 19361636870e0a12db5909955eca58e0070357dde42Donghyun Cho return Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1; 19461636870e0a12db5909955eca58e0070357dde42Donghyun Cho } 19557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang }; 19657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 1979a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik private MediaSessionCompat mMediaSession; 1987578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang private ComponentName mEventReceiver; 1997578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang private AudioManager mAudioManager; 2007578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang private PendingIntent mMediaPendingIntent; 2017578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang private final OnAudioFocusChangeListener mAfChangeListener = 2027578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang new OnAudioFocusChangeListener() { 2037578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang @Override 2047578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang public void onAudioFocusChange(int focusChange) { 2057578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang if (focusChange == AudioManager.AUDIOFOCUS_LOSS_TRANSIENT) { 2067578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang Log.d(TAG, "onAudioFocusChange: LOSS_TRANSIENT"); 2077578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang } else if (focusChange == AudioManager.AUDIOFOCUS_GAIN) { 2087578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang Log.d(TAG, "onAudioFocusChange: AUDIOFOCUS_GAIN"); 2097578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang } else if (focusChange == AudioManager.AUDIOFOCUS_LOSS) { 2107578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang Log.d(TAG, "onAudioFocusChange: AUDIOFOCUS_LOSS"); 2117578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang } 2127578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang } 2137578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang }; 2147578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang 215ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown @Override 216ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown protected void onCreate(Bundle savedInstanceState) { 217ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown // Be sure to call the super class. 218ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown super.onCreate(savedInstanceState); 219ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown 2200e573df7dcd4a3062e76627f26ee2ee377eebfaeHyundo Moon // Need overlay permission for emulating remote display. 2210e573df7dcd4a3062e76627f26ee2ee377eebfaeHyundo Moon if (Build.VERSION.SDK_INT >= 23 && !Settings.canDrawOverlays(this)) { 2220e573df7dcd4a3062e76627f26ee2ee377eebfaeHyundo Moon Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION, 2230e573df7dcd4a3062e76627f26ee2ee377eebfaeHyundo Moon Uri.parse("package:" + getPackageName())); 2240e573df7dcd4a3062e76627f26ee2ee377eebfaeHyundo Moon startActivityForResult(intent, 0); 2250e573df7dcd4a3062e76627f26ee2ee377eebfaeHyundo Moon } 2260e573df7dcd4a3062e76627f26ee2ee377eebfaeHyundo Moon 227ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown // Get the media router service. 228ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown mMediaRouter = MediaRouter.getInstance(this); 229ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown 23055e47d370890d3cbdab82857090c42df734ba276Jeff Brown // Create a route selector for the type of routes that we care about. 23155e47d370890d3cbdab82857090c42df734ba276Jeff Brown mSelector = new MediaRouteSelector.Builder() 23255e47d370890d3cbdab82857090c42df734ba276Jeff Brown .addControlCategory(MediaControlIntent.CATEGORY_LIVE_AUDIO) 23355e47d370890d3cbdab82857090c42df734ba276Jeff Brown .addControlCategory(MediaControlIntent.CATEGORY_LIVE_VIDEO) 23455e47d370890d3cbdab82857090c42df734ba276Jeff Brown .addControlCategory(MediaControlIntent.CATEGORY_REMOTE_PLAYBACK) 23555e47d370890d3cbdab82857090c42df734ba276Jeff Brown .addControlCategory(SampleMediaRouteProvider.CATEGORY_SAMPLE_ROUTE) 23655e47d370890d3cbdab82857090c42df734ba276Jeff Brown .build(); 237f796be9c80d6a62de61853a0cb1d98b440a3586fSungsoo 238f796be9c80d6a62de61853a0cb1d98b440a3586fSungsoo // Add a fragment to take care of media route discovery. 239f796be9c80d6a62de61853a0cb1d98b440a3586fSungsoo // This fragment automatically adds or removes a callback whenever the activity 240f796be9c80d6a62de61853a0cb1d98b440a3586fSungsoo // is started or stopped. 241f796be9c80d6a62de61853a0cb1d98b440a3586fSungsoo FragmentManager fm = getSupportFragmentManager(); 242f796be9c80d6a62de61853a0cb1d98b440a3586fSungsoo DiscoveryFragment fragment = (DiscoveryFragment) fm.findFragmentByTag( 243f796be9c80d6a62de61853a0cb1d98b440a3586fSungsoo DISCOVERY_FRAGMENT_TAG); 244f796be9c80d6a62de61853a0cb1d98b440a3586fSungsoo if (fragment == null) { 24511cd4963ab66125d66342bde773559da74611cd5Donghyun Cho fragment = new DiscoveryFragment(); 246f796be9c80d6a62de61853a0cb1d98b440a3586fSungsoo fm.beginTransaction() 247f796be9c80d6a62de61853a0cb1d98b440a3586fSungsoo .add(fragment, DISCOVERY_FRAGMENT_TAG) 248f796be9c80d6a62de61853a0cb1d98b440a3586fSungsoo .commit(); 249f796be9c80d6a62de61853a0cb1d98b440a3586fSungsoo } 25011cd4963ab66125d66342bde773559da74611cd5Donghyun Cho fragment.setCallback(mMediaRouterCB); 25111cd4963ab66125d66342bde773559da74611cd5Donghyun Cho fragment.setRouteSelector(mSelector); 252f0dd451048100915f072423730a93d17c53fd899Jeff Brown 25357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang // Populate an array adapter with streaming media items. 254ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown String[] mediaNames = getResources().getStringArray(R.array.media_names); 255ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown String[] mediaUris = getResources().getStringArray(R.array.media_uris); 25657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang mLibraryItems = new LibraryAdapter(); 257ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown for (int i = 0; i < mediaNames.length; i++) { 25857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang mLibraryItems.add(new MediaItem( 259a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang "[streaming] "+mediaNames[i], Uri.parse(mediaUris[i]), "video/mp4")); 260ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown } 261ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown 26245ca8fb42505658590e808d4d30b57598689d9a8Jeff Brown // Scan local external storage directory for media files. 26345ca8fb42505658590e808d4d30b57598689d9a8Jeff Brown File externalDir = Environment.getExternalStorageDirectory(); 26445ca8fb42505658590e808d4d30b57598689d9a8Jeff Brown if (externalDir != null) { 26545ca8fb42505658590e808d4d30b57598689d9a8Jeff Brown File list[] = externalDir.listFiles(); 26645ca8fb42505658590e808d4d30b57598689d9a8Jeff Brown if (list != null) { 26745ca8fb42505658590e808d4d30b57598689d9a8Jeff Brown for (int i = 0; i < list.length; i++) { 26845ca8fb42505658590e808d4d30b57598689d9a8Jeff Brown String filename = list[i].getName(); 26945ca8fb42505658590e808d4d30b57598689d9a8Jeff Brown if (filename.matches(".*\\.(m4v|mp4)")) { 27045ca8fb42505658590e808d4d30b57598689d9a8Jeff Brown mLibraryItems.add(new MediaItem("[local] " + filename, 271a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang Uri.fromFile(list[i]), "video/mp4")); 27245ca8fb42505658590e808d4d30b57598689d9a8Jeff Brown } 27345ca8fb42505658590e808d4d30b57598689d9a8Jeff Brown } 27457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 27557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 27657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 27757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang mPlayListItems = new PlaylistAdapter(); 27857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 279ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown // Initialize the layout. 280ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown setContentView(R.layout.sample_media_router); 281ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown 28257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang TabHost tabHost=(TabHost)findViewById(R.id.tabHost); 28357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang tabHost.setup(); 28457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang String tabName = getResources().getString(R.string.library_tab_text); 28557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang TabSpec spec1=tabHost.newTabSpec(tabName); 28657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang spec1.setContent(R.id.tab1); 28757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang spec1.setIndicator(tabName); 28857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 28957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang tabName = getResources().getString(R.string.playlist_tab_text); 29057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang TabSpec spec2=tabHost.newTabSpec(tabName); 29157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang spec2.setIndicator(tabName); 29257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang spec2.setContent(R.id.tab2); 29357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 294cf61a6ed2bfa6141b832fdc40a9fbfb70af91416Chong Zhang tabName = getResources().getString(R.string.info_tab_text); 29557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang TabSpec spec3=tabHost.newTabSpec(tabName); 29657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang spec3.setIndicator(tabName); 29757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang spec3.setContent(R.id.tab3); 29857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 29957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang tabHost.addTab(spec1); 30057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang tabHost.addTab(spec2); 30157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang tabHost.addTab(spec3); 30257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang tabHost.setOnTabChangedListener(new OnTabChangeListener() { 30357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang @Override 30457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang public void onTabChanged(String arg0) { 30557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang updateUi(); 30657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 30757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang }); 30857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 309fa2e2acf79d791a90410025daad438968550d18cAlan Viverette mLibraryView = findViewById(R.id.media); 31057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang mLibraryView.setAdapter(mLibraryItems); 31157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang mLibraryView.setChoiceMode(ListView.CHOICE_MODE_SINGLE); 31257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang mLibraryView.setOnItemClickListener(new OnItemClickListener() { 31357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang @Override 31457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang public void onItemClick(AdapterView<?> parent, View view, int position, long id) { 31557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang updateButtons(); 31657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 31757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang }); 318ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown 319fa2e2acf79d791a90410025daad438968550d18cAlan Viverette mPlayListView = findViewById(R.id.playlist); 32057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang mPlayListView.setAdapter(mPlayListItems); 32157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang mPlayListView.setChoiceMode(ListView.CHOICE_MODE_SINGLE); 32257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang mPlayListView.setOnItemClickListener(new OnItemClickListener() { 323ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown @Override 324ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown public void onItemClick(AdapterView<?> parent, View view, int position, long id) { 325ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown updateButtons(); 326ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown } 327ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown }); 328ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown 329fa2e2acf79d791a90410025daad438968550d18cAlan Viverette mInfoTextView = findViewById(R.id.info); 33057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 331fa2e2acf79d791a90410025daad438968550d18cAlan Viverette mUseDefaultControlCheckBox = findViewById(R.id.custom_control_view_checkbox); 33276d965dc41863b33f887db33d283cb7f1523f60dJae Seo if (ENABLE_DEFAULT_CONTROL_CHECK_BOX) { 33376d965dc41863b33f887db33d283cb7f1523f60dJae Seo mUseDefaultControlCheckBox.setVisibility(View.VISIBLE); 33476d965dc41863b33f887db33d283cb7f1523f60dJae Seo } 33557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang mPauseResumeButton = (ImageButton)findViewById(R.id.pause_resume_button); 33657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang mPauseResumeButton.setOnClickListener(new OnClickListener() { 337ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown @Override 338ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown public void onClick(View v) { 339cf61a6ed2bfa6141b832fdc40a9fbfb70af91416Chong Zhang if (mSessionManager.isPaused()) { 340a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang mSessionManager.resume(); 341cf61a6ed2bfa6141b832fdc40a9fbfb70af91416Chong Zhang } else { 342cf61a6ed2bfa6141b832fdc40a9fbfb70af91416Chong Zhang mSessionManager.pause(); 34357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 344ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown } 345ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown }); 346ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown 34757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang mStopButton = (ImageButton)findViewById(R.id.stop_button); 34857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang mStopButton.setOnClickListener(new OnClickListener() { 349ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown @Override 350ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown public void onClick(View v) { 351a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang mSessionManager.stop(); 352ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown } 353ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown }); 35457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 355fa2e2acf79d791a90410025daad438968550d18cAlan Viverette mSeekBar = findViewById(R.id.seekbar); 35657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang mSeekBar.setOnSeekBarChangeListener(new OnSeekBarChangeListener() { 35757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang @Override 35857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { 359a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang PlaylistItem item = getCheckedPlaylistItem(); 360a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang if (fromUser && item != null && item.getDuration() > 0) { 361a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang long pos = progress * item.getDuration() / 100; 362a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang mSessionManager.seek(item.getItemId(), pos); 363a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang item.setPosition(pos); 364a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang item.setTimestamp(SystemClock.elapsedRealtime()); 36557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 36657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 36757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang @Override 36857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang public void onStartTrackingTouch(SeekBar seekBar) { 36957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang mSeeking = true; 37057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 37157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang @Override 37257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang public void onStopTrackingTouch(SeekBar seekBar) { 37357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang mSeeking = false; 37457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang updateUi(); 37557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 37657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang }); 37757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 37857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang // Schedule Ui update 37957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang mHandler.postDelayed(mUpdateSeekRunnable, 1000); 38057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 3817578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang // Build the PendingIntent for the remote control client 3827578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang mAudioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE); 3837578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang mEventReceiver = new ComponentName(getPackageName(), 3847578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang SampleMediaButtonReceiver.class.getName()); 3857578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang Intent mediaButtonIntent = new Intent(Intent.ACTION_MEDIA_BUTTON); 3867578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang mediaButtonIntent.setComponent(mEventReceiver); 3877578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang mMediaPendingIntent = PendingIntent.getBroadcast(this, 0, mediaButtonIntent, 0); 3887b95dd38981772983f00c5ed91aca4b30b782facJeff Brown 3897b95dd38981772983f00c5ed91aca4b30b782facJeff Brown // Create and register the remote control client 3909a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik createMediaSession(); 3919a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik mMediaRouter.setMediaSessionCompat(mMediaSession); 392a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang 393a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang // Set up playback manager and player 394a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang mPlayer = Player.create(SampleMediaRouterActivity.this, 3959a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik mMediaRouter.getSelectedRoute(), mMediaSession); 3965d429bc3a8195d6f37cf2f7da0935972950539b4RoboErik 397a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang mSessionManager.setPlayer(mPlayer); 398a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang mSessionManager.setCallback(new SessionManager.Callback() { 399a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang @Override 400a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang public void onStatusChanged() { 401a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang updateUi(); 402a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang } 403a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang 404a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang @Override 405a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang public void onItemChanged(PlaylistItem item) { 406a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang } 407a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang }); 408a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang 409a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang updateUi(); 4107578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang } 4117578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang 4129a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik private void createMediaSession() { 4139a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik // Create the MediaSession 4149a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik mMediaSession = new MediaSessionCompat(this, "SampleMediaRouter", mEventReceiver, 4159a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik mMediaPendingIntent); 4169a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik mMediaSession.setFlags(MediaSessionCompat.FLAG_HANDLES_MEDIA_BUTTONS 4179a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik | MediaSessionCompat.FLAG_HANDLES_TRANSPORT_CONTROLS); 4189a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik mMediaSession.setCallback(new MediaSessionCompat.Callback() { 4199a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik @Override 4209a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik public boolean onMediaButtonEvent(Intent mediaButtonEvent) { 4219a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik if (mediaButtonEvent != null) { 4229a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik return handleMediaKey( 4239a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik (KeyEvent) mediaButtonEvent.getParcelableExtra(Intent.EXTRA_KEY_EVENT)); 4249a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik } 4259a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik return super.onMediaButtonEvent(mediaButtonEvent); 4269a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik } 4277578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang 4289a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik @Override 4299a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik public void onPlay() { 4309a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik mSessionManager.resume(); 4319a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik } 4329a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik 4339a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik @Override 4349a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik public void onPause() { 4359a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik mSessionManager.pause(); 4369a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik } 4379a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik }); 4389a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik 4399a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik SampleMediaButtonReceiver.setActivity(SampleMediaRouterActivity.this); 4407578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang } 4417578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang 4427578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang public boolean handleMediaKey(KeyEvent event) { 4439a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik if (event != null && event.getAction() == KeyEvent.ACTION_DOWN 4449a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik && event.getRepeatCount() == 0) { 4457578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang switch (event.getKeyCode()) { 4467578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang case KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE: 4479a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik case KeyEvent.KEYCODE_HEADSETHOOK: 4487578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang { 4497578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang Log.d(TAG, "Received Play/Pause event from RemoteControlClient"); 450cf61a6ed2bfa6141b832fdc40a9fbfb70af91416Chong Zhang if (mSessionManager.isPaused()) { 451a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang mSessionManager.resume(); 452cf61a6ed2bfa6141b832fdc40a9fbfb70af91416Chong Zhang } else { 453cf61a6ed2bfa6141b832fdc40a9fbfb70af91416Chong Zhang mSessionManager.pause(); 4547578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang } 4557578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang return true; 4567578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang } 4577578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang case KeyEvent.KEYCODE_MEDIA_PLAY: 4587578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang { 4597578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang Log.d(TAG, "Received Play event from RemoteControlClient"); 460cf61a6ed2bfa6141b832fdc40a9fbfb70af91416Chong Zhang if (mSessionManager.isPaused()) { 461a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang mSessionManager.resume(); 4627578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang } 4637578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang return true; 4647578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang } 4657578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang case KeyEvent.KEYCODE_MEDIA_PAUSE: 4667578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang { 4677578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang Log.d(TAG, "Received Pause event from RemoteControlClient"); 468cf61a6ed2bfa6141b832fdc40a9fbfb70af91416Chong Zhang if (!mSessionManager.isPaused()) { 469a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang mSessionManager.pause(); 4707578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang } 4717578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang return true; 4727578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang } 4737578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang case KeyEvent.KEYCODE_MEDIA_STOP: 4747578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang { 4757578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang Log.d(TAG, "Received Stop event from RemoteControlClient"); 476a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang mSessionManager.stop(); 4777578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang return true; 4787578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang } 4797578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang default: 4807578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang break; 4817578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang } 4827578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang } 4837578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang return false; 4847578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang } 4857578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang 4867578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang @Override 4877578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang public boolean onKeyDown(int keyCode, KeyEvent event) { 4887578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang return handleMediaKey(event) || super.onKeyDown(keyCode, event); 4897578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang } 4907578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang 4917578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang @Override 4927578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang public boolean onKeyUp(int keyCode, KeyEvent event) { 4937578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang return handleMediaKey(event) || super.onKeyUp(keyCode, event); 494ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown } 495ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown 496ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown @Override 497f0dd451048100915f072423730a93d17c53fd899Jeff Brown public void onStart() { 498ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown // Be sure to call the super class. 499f0dd451048100915f072423730a93d17c53fd899Jeff Brown super.onStart(); 50057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 501ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown 50257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang @Override 50357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang public void onPause() { 50457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang // pause media player for local playback case only 505cf61a6ed2bfa6141b832fdc40a9fbfb70af91416Chong Zhang if (!mPlayer.isRemotePlayback() && !mSessionManager.isPaused()) { 50657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang mNeedResume = true; 507a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang mSessionManager.pause(); 50857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 50957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang super.onPause(); 51057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 51157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 51257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang @Override 51357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang public void onResume() { 51457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang // resume media player for local playback case only 515a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang if (!mPlayer.isRemotePlayback() && mNeedResume) { 516a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang mSessionManager.resume(); 51757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang mNeedResume = false; 51857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 51957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang super.onResume(); 52057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 52157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 52257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang @Override 52357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang public void onDestroy() { 524a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang mSessionManager.stop(); 525a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang mPlayer.release(); 5269a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik mMediaSession.release(); 52757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang super.onDestroy(); 528ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown } 529ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown 530ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown @Override 531ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown public boolean onCreateOptionsMenu(Menu menu) { 532ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown // Be sure to call the super class. 533ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown super.onCreateOptionsMenu(menu); 534ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown 535ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown // Inflate the menu and configure the media router action provider. 536ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown getMenuInflater().inflate(R.menu.sample_media_router_menu, menu); 537ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown 53855e47d370890d3cbdab82857090c42df734ba276Jeff Brown MenuItem mediaRouteMenuItem = menu.findItem(R.id.media_route_menu_item); 539f796be9c80d6a62de61853a0cb1d98b440a3586fSungsoo MediaRouteActionProvider mediaRouteActionProvider = 540f796be9c80d6a62de61853a0cb1d98b440a3586fSungsoo (MediaRouteActionProvider) MenuItemCompat.getActionProvider(mediaRouteMenuItem); 54155e47d370890d3cbdab82857090c42df734ba276Jeff Brown mediaRouteActionProvider.setRouteSelector(mSelector); 542cf61a6ed2bfa6141b832fdc40a9fbfb70af91416Chong Zhang mediaRouteActionProvider.setDialogFactory(new MediaRouteDialogFactory() { 543cf61a6ed2bfa6141b832fdc40a9fbfb70af91416Chong Zhang @Override 544cf61a6ed2bfa6141b832fdc40a9fbfb70af91416Chong Zhang public MediaRouteControllerDialogFragment onCreateControllerDialogFragment() { 54576d965dc41863b33f887db33d283cb7f1523f60dJae Seo return new ControllerDialogFragment(mPlayer, mUseDefaultControlCheckBox); 546cf61a6ed2bfa6141b832fdc40a9fbfb70af91416Chong Zhang } 547cf61a6ed2bfa6141b832fdc40a9fbfb70af91416Chong Zhang }); 548ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown 549ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown // Return true to show the menu. 550ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown return true; 551ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown } 552ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown 553a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang private void updateProgress() { 55457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang // Estimate content position from last status time and elapsed time. 55557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang // (Note this might be slightly out of sync with remote side, however 55657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang // it avoids frequent polling the MRP.) 55757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang int progress = 0; 558a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang PlaylistItem item = getCheckedPlaylistItem(); 559a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang if (item != null) { 560a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang int state = item.getState(); 561a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang long duration = item.getDuration(); 56257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang if (duration <= 0) { 56357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang if (state == MediaItemStatus.PLAYBACK_STATE_PLAYING 56457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang || state == MediaItemStatus.PLAYBACK_STATE_PAUSED) { 565a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang mSessionManager.updateStatus(); 56657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 56757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } else { 568a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang long position = item.getPosition(); 569cf61a6ed2bfa6141b832fdc40a9fbfb70af91416Chong Zhang long timeDelta = mSessionManager.isPaused() ? 0 : 570a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang (SystemClock.elapsedRealtime() - item.getTimestamp()); 57157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang progress = (int)(100.0 * (position + timeDelta) / duration); 57257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 573ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown } 57457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang mSeekBar.setProgress(progress); 57557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 576ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown 57757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang private void updateUi() { 57857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang updatePlaylist(); 579a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang updateRouteDescription(); 58057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang updateButtons(); 58170f3627685b55b2bc1b3f0c17c9c30aa3a7fd062Donghyun Cho if (mPlayer != null && mSessionManager != null) { 58270f3627685b55b2bc1b3f0c17c9c30aa3a7fd062Donghyun Cho PlaylistItem currentItem = mSessionManager.getCurrentItem(); 58370f3627685b55b2bc1b3f0c17c9c30aa3a7fd062Donghyun Cho if (currentItem != null) { 58470f3627685b55b2bc1b3f0c17c9c30aa3a7fd062Donghyun Cho mPlayer.updateMetadata(currentItem); 58570f3627685b55b2bc1b3f0c17c9c30aa3a7fd062Donghyun Cho int currentItemState = Player.STATE_IDLE; 58670f3627685b55b2bc1b3f0c17c9c30aa3a7fd062Donghyun Cho switch(currentItem.getState()) { 58770f3627685b55b2bc1b3f0c17c9c30aa3a7fd062Donghyun Cho case MediaItemStatus.PLAYBACK_STATE_PLAYING: 58870f3627685b55b2bc1b3f0c17c9c30aa3a7fd062Donghyun Cho currentItemState = Player.STATE_PLAYING; 58970f3627685b55b2bc1b3f0c17c9c30aa3a7fd062Donghyun Cho break; 59070f3627685b55b2bc1b3f0c17c9c30aa3a7fd062Donghyun Cho case MediaItemStatus.PLAYBACK_STATE_PAUSED: 59170f3627685b55b2bc1b3f0c17c9c30aa3a7fd062Donghyun Cho currentItemState = Player.STATE_PAUSED; 59270f3627685b55b2bc1b3f0c17c9c30aa3a7fd062Donghyun Cho break; 59370f3627685b55b2bc1b3f0c17c9c30aa3a7fd062Donghyun Cho case MediaItemStatus.PLAYBACK_STATE_PENDING: 59470f3627685b55b2bc1b3f0c17c9c30aa3a7fd062Donghyun Cho case MediaItemStatus.PLAYBACK_STATE_BUFFERING: 59570f3627685b55b2bc1b3f0c17c9c30aa3a7fd062Donghyun Cho currentItemState = Player.STATE_PREPARING_FOR_PLAY; 59670f3627685b55b2bc1b3f0c17c9c30aa3a7fd062Donghyun Cho break; 59770f3627685b55b2bc1b3f0c17c9c30aa3a7fd062Donghyun Cho } 59870f3627685b55b2bc1b3f0c17c9c30aa3a7fd062Donghyun Cho mPlayer.publishState(currentItemState); 59970f3627685b55b2bc1b3f0c17c9c30aa3a7fd062Donghyun Cho } 600cf61a6ed2bfa6141b832fdc40a9fbfb70af91416Chong Zhang } 601ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown } 602ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown 60357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang private void updatePlaylist() { 60457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang mPlayListItems.clear(); 605a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang for (PlaylistItem item : mSessionManager.getPlaylist()) { 606a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang mPlayListItems.add(item); 607a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang } 60857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang mPlayListView.invalidate(); 609a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang } 610ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown 611a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang private void updateRouteDescription() { 612a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang RouteInfo route = mMediaRouter.getSelectedRoute(); 613a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang mInfoTextView.setText("Currently selected route:" 614a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang + "\nName: " + route.getName() 61570f3627685b55b2bc1b3f0c17c9c30aa3a7fd062Donghyun Cho + "\nProvider: " + route.getProvider().getPackageName()); 61657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 617fcb6a9d1caaf43ae41f859ebb58a4483b12475a1Jeff Brown 618a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang private void updateButtons() { 619a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang MediaRouter.RouteInfo route = mMediaRouter.getSelectedRoute(); 620a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang // show pause or resume icon depending on current state 621cf61a6ed2bfa6141b832fdc40a9fbfb70af91416Chong Zhang mPauseResumeButton.setImageResource(mSessionManager.isPaused() ? 622a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang R.drawable.ic_media_play : R.drawable.ic_media_pause); 623a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang // only enable seek bar when duration is known 624a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang PlaylistItem item = getCheckedPlaylistItem(); 625a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang mSeekBar.setEnabled(item != null && item.getDuration() > 0); 62657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 627ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown 628a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang private PlaylistItem getCheckedPlaylistItem() { 62957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang int count = mPlayListView.getCount(); 63057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang int index = mPlayListView.getCheckedItemPosition(); 63157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang if (count > 0) { 63257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang if (index < 0 || index >= count) { 63357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang index = 0; 63457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang mPlayListView.setItemChecked(0, true); 63557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 63657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang return mPlayListItems.getItem(index); 637ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown } 63857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang return null; 639ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown } 640ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown 641f796be9c80d6a62de61853a0cb1d98b440a3586fSungsoo /** 642f796be9c80d6a62de61853a0cb1d98b440a3586fSungsoo * Media route discovery fragment. 643f796be9c80d6a62de61853a0cb1d98b440a3586fSungsoo */ 644f796be9c80d6a62de61853a0cb1d98b440a3586fSungsoo public static final class DiscoveryFragment extends MediaRouteDiscoveryFragment { 645f796be9c80d6a62de61853a0cb1d98b440a3586fSungsoo private static final String TAG = "DiscoveryFragment"; 646f796be9c80d6a62de61853a0cb1d98b440a3586fSungsoo private Callback mCallback; 647f796be9c80d6a62de61853a0cb1d98b440a3586fSungsoo 648f796be9c80d6a62de61853a0cb1d98b440a3586fSungsoo public void setCallback(Callback cb) { 649f796be9c80d6a62de61853a0cb1d98b440a3586fSungsoo mCallback = cb; 650f796be9c80d6a62de61853a0cb1d98b440a3586fSungsoo } 651f796be9c80d6a62de61853a0cb1d98b440a3586fSungsoo 652f796be9c80d6a62de61853a0cb1d98b440a3586fSungsoo @Override 653f796be9c80d6a62de61853a0cb1d98b440a3586fSungsoo public Callback onCreateCallback() { 654f796be9c80d6a62de61853a0cb1d98b440a3586fSungsoo return mCallback; 655f796be9c80d6a62de61853a0cb1d98b440a3586fSungsoo } 656f796be9c80d6a62de61853a0cb1d98b440a3586fSungsoo 657f796be9c80d6a62de61853a0cb1d98b440a3586fSungsoo @Override 658f796be9c80d6a62de61853a0cb1d98b440a3586fSungsoo public int onPrepareCallbackFlags() { 659f796be9c80d6a62de61853a0cb1d98b440a3586fSungsoo // Add the CALLBACK_FLAG_UNFILTERED_EVENTS flag to ensure that we will 660f796be9c80d6a62de61853a0cb1d98b440a3586fSungsoo // observe and log all route events including those that are for routes 661f796be9c80d6a62de61853a0cb1d98b440a3586fSungsoo // that do not match our selector. This is only for demonstration purposes 662f796be9c80d6a62de61853a0cb1d98b440a3586fSungsoo // and should not be needed by most applications. 663f796be9c80d6a62de61853a0cb1d98b440a3586fSungsoo return super.onPrepareCallbackFlags() 664f796be9c80d6a62de61853a0cb1d98b440a3586fSungsoo | MediaRouter.CALLBACK_FLAG_UNFILTERED_EVENTS; 665f796be9c80d6a62de61853a0cb1d98b440a3586fSungsoo } 666f796be9c80d6a62de61853a0cb1d98b440a3586fSungsoo } 667f796be9c80d6a62de61853a0cb1d98b440a3586fSungsoo 668ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown private static final class MediaItem { 669ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown public final String mName; 670ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown public final Uri mUri; 671a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang public final String mMime; 672ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown 673a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang public MediaItem(String name, Uri uri, String mime) { 674ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown mName = name; 675ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown mUri = uri; 676a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang mMime = mime; 677ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown } 678ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown 679ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown @Override 680ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown public String toString() { 681ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown return mName; 682ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown } 683ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown } 68455e47d370890d3cbdab82857090c42df734ba276Jeff Brown 68557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang private final class LibraryAdapter extends ArrayAdapter<MediaItem> { 68657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang public LibraryAdapter() { 68757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang super(SampleMediaRouterActivity.this, R.layout.media_item); 68857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 68957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 69057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang @Override 69157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang public View getView(int position, View convertView, ViewGroup parent) { 69257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang final View v; 69357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang if (convertView == null) { 69457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang v = getLayoutInflater().inflate(R.layout.media_item, null); 69557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } else { 69657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang v = convertView; 69757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 69857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 69957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang final MediaItem item = getItem(position); 70057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 70157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang TextView tv = (TextView)v.findViewById(R.id.item_text); 70257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang tv.setText(item.mName); 70357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 70457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang ImageButton b = (ImageButton)v.findViewById(R.id.item_action); 70557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang b.setImageResource(R.drawable.ic_menu_add); 70657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang b.setTag(item); 70757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang b.setOnClickListener(new OnClickListener() { 70857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang @Override 70957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang public void onClick(View v) { 71057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang if (item != null) { 71170f3627685b55b2bc1b3f0c17c9c30aa3a7fd062Donghyun Cho mSessionManager.add(item.mName, item.mUri, item.mMime); 71257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 71357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 71457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang }); 71557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 71657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang return v; 71757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 71857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 71957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 720a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang private final class PlaylistAdapter extends ArrayAdapter<PlaylistItem> { 72157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang public PlaylistAdapter() { 72257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang super(SampleMediaRouterActivity.this, R.layout.media_item); 72357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 72457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 72557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang @Override 72657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang public View getView(int position, View convertView, ViewGroup parent) { 72757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang final View v; 72857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang if (convertView == null) { 72957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang v = getLayoutInflater().inflate(R.layout.media_item, null); 73057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } else { 73157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang v = convertView; 73257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 73357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 734a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang final PlaylistItem item = getItem(position); 73557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 73657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang TextView tv = (TextView)v.findViewById(R.id.item_text); 73757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang tv.setText(item.toString()); 73857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 73957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang ImageButton b = (ImageButton)v.findViewById(R.id.item_action); 74057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang b.setImageResource(R.drawable.ic_menu_delete); 74157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang b.setTag(item); 74257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang b.setOnClickListener(new OnClickListener() { 74357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang @Override 74457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang public void onClick(View v) { 74557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang if (item != null) { 746a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang mSessionManager.remove(item.getItemId()); 74757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 74857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 74957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang }); 75057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 75157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang return v; 75257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 75357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 75457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 75555e47d370890d3cbdab82857090c42df734ba276Jeff Brown /** 75655e47d370890d3cbdab82857090c42df734ba276Jeff Brown * Trivial subclass of this activity used to provide another copy of the 75755e47d370890d3cbdab82857090c42df734ba276Jeff Brown * same activity using a light theme instead of the dark theme. 75855e47d370890d3cbdab82857090c42df734ba276Jeff Brown */ 75955e47d370890d3cbdab82857090c42df734ba276Jeff Brown public static class Light extends SampleMediaRouterActivity { 76055e47d370890d3cbdab82857090c42df734ba276Jeff Brown } 76155e47d370890d3cbdab82857090c42df734ba276Jeff Brown 76255e47d370890d3cbdab82857090c42df734ba276Jeff Brown /** 76355e47d370890d3cbdab82857090c42df734ba276Jeff Brown * Trivial subclass of this activity used to provide another copy of the 76455e47d370890d3cbdab82857090c42df734ba276Jeff Brown * same activity using a light theme with dark action bar instead of the dark theme. 76555e47d370890d3cbdab82857090c42df734ba276Jeff Brown */ 76655e47d370890d3cbdab82857090c42df734ba276Jeff Brown public static class LightWithDarkActionBar extends SampleMediaRouterActivity { 76755e47d370890d3cbdab82857090c42df734ba276Jeff Brown } 7685d429bc3a8195d6f37cf2f7da0935972950539b4RoboErik 7695d429bc3a8195d6f37cf2f7da0935972950539b4RoboErik public static class ControllerDialogFragment extends MediaRouteControllerDialogFragment { 7705d429bc3a8195d6f37cf2f7da0935972950539b4RoboErik private MediaRouteControllerDialog mControllerDialog; 7715d429bc3a8195d6f37cf2f7da0935972950539b4RoboErik private Player mPlayer; 77276d965dc41863b33f887db33d283cb7f1523f60dJae Seo private CheckBox mUseDefaultControlCheckBox; 7735d429bc3a8195d6f37cf2f7da0935972950539b4RoboErik 7745d429bc3a8195d6f37cf2f7da0935972950539b4RoboErik public ControllerDialogFragment() { 7755d429bc3a8195d6f37cf2f7da0935972950539b4RoboErik super(); 7765d429bc3a8195d6f37cf2f7da0935972950539b4RoboErik } 7775d429bc3a8195d6f37cf2f7da0935972950539b4RoboErik 77876d965dc41863b33f887db33d283cb7f1523f60dJae Seo public ControllerDialogFragment(Player player, CheckBox customControlViewCheckBox) { 7795d429bc3a8195d6f37cf2f7da0935972950539b4RoboErik mPlayer = player; 78076d965dc41863b33f887db33d283cb7f1523f60dJae Seo this.mUseDefaultControlCheckBox = customControlViewCheckBox; 7815d429bc3a8195d6f37cf2f7da0935972950539b4RoboErik } 7825d429bc3a8195d6f37cf2f7da0935972950539b4RoboErik 7835d429bc3a8195d6f37cf2f7da0935972950539b4RoboErik @Override 7845d429bc3a8195d6f37cf2f7da0935972950539b4RoboErik public MediaRouteControllerDialog onCreateControllerDialog( 7855d429bc3a8195d6f37cf2f7da0935972950539b4RoboErik Context context, Bundle savedInstanceState) { 78676d965dc41863b33f887db33d283cb7f1523f60dJae Seo mControllerDialog = this.mUseDefaultControlCheckBox.isChecked() 78776d965dc41863b33f887db33d283cb7f1523f60dJae Seo ? super.onCreateControllerDialog(context, savedInstanceState) 78876d965dc41863b33f887db33d283cb7f1523f60dJae Seo : new MyMediaRouteControllerDialog(context); 7895d429bc3a8195d6f37cf2f7da0935972950539b4RoboErik mControllerDialog.setOnDismissListener(new DialogInterface.OnDismissListener() { 7905d429bc3a8195d6f37cf2f7da0935972950539b4RoboErik @Override 7915d429bc3a8195d6f37cf2f7da0935972950539b4RoboErik public void onDismiss(DialogInterface dialog) { 7925d429bc3a8195d6f37cf2f7da0935972950539b4RoboErik mControllerDialog = null; 7935d429bc3a8195d6f37cf2f7da0935972950539b4RoboErik } 7945d429bc3a8195d6f37cf2f7da0935972950539b4RoboErik }); 7955d429bc3a8195d6f37cf2f7da0935972950539b4RoboErik return mControllerDialog; 7965d429bc3a8195d6f37cf2f7da0935972950539b4RoboErik } 7975d429bc3a8195d6f37cf2f7da0935972950539b4RoboErik 7985d429bc3a8195d6f37cf2f7da0935972950539b4RoboErik public void setPlayer(Player player) { 7995d429bc3a8195d6f37cf2f7da0935972950539b4RoboErik mPlayer = player; 8005d429bc3a8195d6f37cf2f7da0935972950539b4RoboErik } 8015d429bc3a8195d6f37cf2f7da0935972950539b4RoboErik } 802ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown} 803