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; 339a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErikimport android.support.v4.media.session.MediaSessionCompat; 34ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brownimport android.util.Log; 357578fad97dcd3b4b390652f37a30d805538980f5Chong Zhangimport android.view.KeyEvent; 36ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brownimport android.view.Menu; 37ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brownimport android.view.MenuItem; 38ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brownimport android.view.View; 39ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brownimport android.view.View.OnClickListener; 4057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhangimport android.view.ViewGroup; 41ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brownimport android.widget.AdapterView; 4257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhangimport android.widget.AdapterView.OnItemClickListener; 43ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brownimport android.widget.ArrayAdapter; 4476d965dc41863b33f887db33d283cb7f1523f60dJae Seoimport android.widget.CheckBox; 4557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhangimport android.widget.ImageButton; 46ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brownimport android.widget.ListView; 4757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhangimport android.widget.SeekBar; 4857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhangimport android.widget.SeekBar.OnSeekBarChangeListener; 4944d25261c2a38c81f1eea123de3986b453b9afeeChris Banesimport android.widget.TabHost; 5044d25261c2a38c81f1eea123de3986b453b9afeeChris Banesimport android.widget.TabHost.OnTabChangeListener; 5144d25261c2a38c81f1eea123de3986b453b9afeeChris Banesimport android.widget.TabHost.TabSpec; 5244d25261c2a38c81f1eea123de3986b453b9afeeChris Banesimport android.widget.TextView; 535d429bc3a8195d6f37cf2f7da0935972950539b4RoboErik 54def582a5836579a3fadabfdbe4413cb1652bf098Aurimas Liutikasimport androidx.appcompat.app.AppCompatActivity; 55def582a5836579a3fadabfdbe4413cb1652bf098Aurimas Liutikasimport androidx.core.view.MenuItemCompat; 56def582a5836579a3fadabfdbe4413cb1652bf098Aurimas Liutikasimport androidx.fragment.app.FragmentManager; 57def582a5836579a3fadabfdbe4413cb1652bf098Aurimas Liutikasimport androidx.mediarouter.app.MediaRouteActionProvider; 58def582a5836579a3fadabfdbe4413cb1652bf098Aurimas Liutikasimport androidx.mediarouter.app.MediaRouteControllerDialog; 59def582a5836579a3fadabfdbe4413cb1652bf098Aurimas Liutikasimport androidx.mediarouter.app.MediaRouteControllerDialogFragment; 60def582a5836579a3fadabfdbe4413cb1652bf098Aurimas Liutikasimport androidx.mediarouter.app.MediaRouteDialogFactory; 61def582a5836579a3fadabfdbe4413cb1652bf098Aurimas Liutikasimport androidx.mediarouter.app.MediaRouteDiscoveryFragment; 62def582a5836579a3fadabfdbe4413cb1652bf098Aurimas Liutikasimport androidx.mediarouter.media.MediaControlIntent; 63def582a5836579a3fadabfdbe4413cb1652bf098Aurimas Liutikasimport androidx.mediarouter.media.MediaItemStatus; 64def582a5836579a3fadabfdbe4413cb1652bf098Aurimas Liutikasimport androidx.mediarouter.media.MediaRouteSelector; 65def582a5836579a3fadabfdbe4413cb1652bf098Aurimas Liutikasimport androidx.mediarouter.media.MediaRouter; 66def582a5836579a3fadabfdbe4413cb1652bf098Aurimas Liutikasimport androidx.mediarouter.media.MediaRouter.Callback; 67def582a5836579a3fadabfdbe4413cb1652bf098Aurimas Liutikasimport androidx.mediarouter.media.MediaRouter.ProviderInfo; 68def582a5836579a3fadabfdbe4413cb1652bf098Aurimas Liutikasimport androidx.mediarouter.media.MediaRouter.RouteInfo; 69def582a5836579a3fadabfdbe4413cb1652bf098Aurimas Liutikas 70c1a24039658cc52f34046800790de302b7db075bSungsoo Limimport com.example.android.supportv7.R; 71c1a24039658cc52f34046800790de302b7db075bSungsoo Lim 7257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhangimport java.io.File; 73ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown 74ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown/** 75ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown * <h3>Media Router Support Activity</h3> 76ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown * 77ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown * <p> 78ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown * This demonstrates how to use the {@link MediaRouter} API to build an 79ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown * application that allows the user to send content to various rendering 80ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown * targets. 81ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown * </p> 82ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown */ 8344d25261c2a38c81f1eea123de3986b453b9afeeChris Banespublic class SampleMediaRouterActivity extends AppCompatActivity { 84a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang private static final String TAG = "SampleMediaRouterActivity"; 85f0dd451048100915f072423730a93d17c53fd899Jeff Brown private static final String DISCOVERY_FRAGMENT_TAG = "DiscoveryFragment"; 8676d965dc41863b33f887db33d283cb7f1523f60dJae Seo private static final boolean ENABLE_DEFAULT_CONTROL_CHECK_BOX = false; 87ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown 88ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown private MediaRouter mMediaRouter; 8955e47d370890d3cbdab82857090c42df734ba276Jeff Brown private MediaRouteSelector mSelector; 9057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang private LibraryAdapter mLibraryItems; 9157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang private PlaylistAdapter mPlayListItems; 92ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown private TextView mInfoTextView; 9357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang private ListView mLibraryView; 9457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang private ListView mPlayListView; 9576d965dc41863b33f887db33d283cb7f1523f60dJae Seo private CheckBox mUseDefaultControlCheckBox; 9657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang private ImageButton mPauseResumeButton; 9757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang private ImageButton mStopButton; 9857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang private SeekBar mSeekBar; 9957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang private boolean mNeedResume; 10057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang private boolean mSeeking; 10157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 10257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang private final Handler mHandler = new Handler(); 10357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang private final Runnable mUpdateSeekRunnable = new Runnable() { 10457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang @Override 10557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang public void run() { 106a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang updateProgress(); 10757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang // update Ui every 1 second 10857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang mHandler.postDelayed(this, 1000); 10957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 11057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang }; 11157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 112a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang private final SessionManager mSessionManager = new SessionManager("app"); 11357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang private Player mPlayer; 11457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 11557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang private final MediaRouter.Callback mMediaRouterCB = new MediaRouter.Callback() { 11657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang // Return a custom callback that will simply log all of the route events 11757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang // for demonstration purposes. 11857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang @Override 11957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang public void onRouteAdded(MediaRouter router, RouteInfo route) { 12057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang Log.d(TAG, "onRouteAdded: route=" + route); 12157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 12257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 12357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang @Override 12457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang public void onRouteChanged(MediaRouter router, RouteInfo route) { 12557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang Log.d(TAG, "onRouteChanged: route=" + route); 12657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 12757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 12857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang @Override 12957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang public void onRouteRemoved(MediaRouter router, RouteInfo route) { 13057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang Log.d(TAG, "onRouteRemoved: route=" + route); 13157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 13257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 13357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang @Override 13457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang public void onRouteSelected(MediaRouter router, RouteInfo route) { 13557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang Log.d(TAG, "onRouteSelected: route=" + route); 13657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 1379a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik mPlayer = Player.create(SampleMediaRouterActivity.this, route, mMediaSession); 13861636870e0a12db5909955eca58e0070357dde42Donghyun Cho if (isPresentationApiSupported()) { 13961636870e0a12db5909955eca58e0070357dde42Donghyun Cho mPlayer.updatePresentation(); 14061636870e0a12db5909955eca58e0070357dde42Donghyun Cho } 141a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang mSessionManager.setPlayer(mPlayer); 142a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang mSessionManager.unsuspend(); 14357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 14457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang updateUi(); 14557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 14657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 14757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang @Override 14857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang public void onRouteUnselected(MediaRouter router, RouteInfo route) { 14957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang Log.d(TAG, "onRouteUnselected: route=" + route); 1509a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik mMediaSession.setActive(false); 151a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang 152a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang PlaylistItem item = getCheckedPlaylistItem(); 153a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang if (item != null) { 154cf61a6ed2bfa6141b832fdc40a9fbfb70af91416Chong Zhang long pos = item.getPosition() + (mSessionManager.isPaused() ? 155a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang 0 : (SystemClock.elapsedRealtime() - item.getTimestamp())); 156a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang mSessionManager.suspend(pos); 157a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang } 15861636870e0a12db5909955eca58e0070357dde42Donghyun Cho if (isPresentationApiSupported()) { 15961636870e0a12db5909955eca58e0070357dde42Donghyun Cho mPlayer.updatePresentation(); 16061636870e0a12db5909955eca58e0070357dde42Donghyun Cho } 161a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang mPlayer.release(); 16257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 16357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 16457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang @Override 16557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang public void onRouteVolumeChanged(MediaRouter router, RouteInfo route) { 16657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang Log.d(TAG, "onRouteVolumeChanged: route=" + route); 16757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 16857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 16957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang @Override 17057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang public void onRoutePresentationDisplayChanged( 17157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang MediaRouter router, RouteInfo route) { 17257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang Log.d(TAG, "onRoutePresentationDisplayChanged: route=" + route); 17361636870e0a12db5909955eca58e0070357dde42Donghyun Cho if (isPresentationApiSupported()) { 17461636870e0a12db5909955eca58e0070357dde42Donghyun Cho mPlayer.updatePresentation(); 17561636870e0a12db5909955eca58e0070357dde42Donghyun Cho } 17657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 17757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 17857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang @Override 17957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang public void onProviderAdded(MediaRouter router, ProviderInfo provider) { 18057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang Log.d(TAG, "onRouteProviderAdded: provider=" + provider); 18157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 18257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 18357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang @Override 18457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang public void onProviderRemoved(MediaRouter router, ProviderInfo provider) { 18557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang Log.d(TAG, "onRouteProviderRemoved: provider=" + provider); 18657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 18757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 18857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang @Override 18957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang public void onProviderChanged(MediaRouter router, ProviderInfo provider) { 19057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang Log.d(TAG, "onRouteProviderChanged: provider=" + provider); 19157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 19261636870e0a12db5909955eca58e0070357dde42Donghyun Cho 19361636870e0a12db5909955eca58e0070357dde42Donghyun Cho private boolean isPresentationApiSupported() { 19461636870e0a12db5909955eca58e0070357dde42Donghyun Cho return Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1; 19561636870e0a12db5909955eca58e0070357dde42Donghyun Cho } 19657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang }; 19757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 1989a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik private MediaSessionCompat mMediaSession; 1997578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang private ComponentName mEventReceiver; 2007578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang private AudioManager mAudioManager; 2017578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang private PendingIntent mMediaPendingIntent; 2027578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang private final OnAudioFocusChangeListener mAfChangeListener = 2037578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang new OnAudioFocusChangeListener() { 2047578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang @Override 2057578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang public void onAudioFocusChange(int focusChange) { 2067578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang if (focusChange == AudioManager.AUDIOFOCUS_LOSS_TRANSIENT) { 2077578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang Log.d(TAG, "onAudioFocusChange: LOSS_TRANSIENT"); 2087578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang } else if (focusChange == AudioManager.AUDIOFOCUS_GAIN) { 2097578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang Log.d(TAG, "onAudioFocusChange: AUDIOFOCUS_GAIN"); 2107578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang } else if (focusChange == AudioManager.AUDIOFOCUS_LOSS) { 2117578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang Log.d(TAG, "onAudioFocusChange: AUDIOFOCUS_LOSS"); 2127578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang } 2137578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang } 2147578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang }; 2157578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang 216ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown @Override 217ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown protected void onCreate(Bundle savedInstanceState) { 218ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown // Be sure to call the super class. 219ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown super.onCreate(savedInstanceState); 220ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown 2210e573df7dcd4a3062e76627f26ee2ee377eebfaeHyundo Moon // Need overlay permission for emulating remote display. 2220e573df7dcd4a3062e76627f26ee2ee377eebfaeHyundo Moon if (Build.VERSION.SDK_INT >= 23 && !Settings.canDrawOverlays(this)) { 2230e573df7dcd4a3062e76627f26ee2ee377eebfaeHyundo Moon Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION, 2240e573df7dcd4a3062e76627f26ee2ee377eebfaeHyundo Moon Uri.parse("package:" + getPackageName())); 2250e573df7dcd4a3062e76627f26ee2ee377eebfaeHyundo Moon startActivityForResult(intent, 0); 2260e573df7dcd4a3062e76627f26ee2ee377eebfaeHyundo Moon } 2270e573df7dcd4a3062e76627f26ee2ee377eebfaeHyundo Moon 228ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown // Get the media router service. 229ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown mMediaRouter = MediaRouter.getInstance(this); 230ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown 23155e47d370890d3cbdab82857090c42df734ba276Jeff Brown // Create a route selector for the type of routes that we care about. 23255e47d370890d3cbdab82857090c42df734ba276Jeff Brown mSelector = new MediaRouteSelector.Builder() 23355e47d370890d3cbdab82857090c42df734ba276Jeff Brown .addControlCategory(MediaControlIntent.CATEGORY_LIVE_AUDIO) 23455e47d370890d3cbdab82857090c42df734ba276Jeff Brown .addControlCategory(MediaControlIntent.CATEGORY_LIVE_VIDEO) 23555e47d370890d3cbdab82857090c42df734ba276Jeff Brown .addControlCategory(MediaControlIntent.CATEGORY_REMOTE_PLAYBACK) 23655e47d370890d3cbdab82857090c42df734ba276Jeff Brown .addControlCategory(SampleMediaRouteProvider.CATEGORY_SAMPLE_ROUTE) 23755e47d370890d3cbdab82857090c42df734ba276Jeff Brown .build(); 238f796be9c80d6a62de61853a0cb1d98b440a3586fSungsoo 239f796be9c80d6a62de61853a0cb1d98b440a3586fSungsoo // Add a fragment to take care of media route discovery. 240f796be9c80d6a62de61853a0cb1d98b440a3586fSungsoo // This fragment automatically adds or removes a callback whenever the activity 241f796be9c80d6a62de61853a0cb1d98b440a3586fSungsoo // is started or stopped. 242f796be9c80d6a62de61853a0cb1d98b440a3586fSungsoo FragmentManager fm = getSupportFragmentManager(); 243f796be9c80d6a62de61853a0cb1d98b440a3586fSungsoo DiscoveryFragment fragment = (DiscoveryFragment) fm.findFragmentByTag( 244f796be9c80d6a62de61853a0cb1d98b440a3586fSungsoo DISCOVERY_FRAGMENT_TAG); 245f796be9c80d6a62de61853a0cb1d98b440a3586fSungsoo if (fragment == null) { 24611cd4963ab66125d66342bde773559da74611cd5Donghyun Cho fragment = new DiscoveryFragment(); 247f796be9c80d6a62de61853a0cb1d98b440a3586fSungsoo fm.beginTransaction() 248f796be9c80d6a62de61853a0cb1d98b440a3586fSungsoo .add(fragment, DISCOVERY_FRAGMENT_TAG) 249f796be9c80d6a62de61853a0cb1d98b440a3586fSungsoo .commit(); 250f796be9c80d6a62de61853a0cb1d98b440a3586fSungsoo } 25111cd4963ab66125d66342bde773559da74611cd5Donghyun Cho fragment.setCallback(mMediaRouterCB); 25211cd4963ab66125d66342bde773559da74611cd5Donghyun Cho fragment.setRouteSelector(mSelector); 253f0dd451048100915f072423730a93d17c53fd899Jeff Brown 25457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang // Populate an array adapter with streaming media items. 255ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown String[] mediaNames = getResources().getStringArray(R.array.media_names); 256ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown String[] mediaUris = getResources().getStringArray(R.array.media_uris); 25757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang mLibraryItems = new LibraryAdapter(); 258ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown for (int i = 0; i < mediaNames.length; i++) { 25957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang mLibraryItems.add(new MediaItem( 260a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang "[streaming] "+mediaNames[i], Uri.parse(mediaUris[i]), "video/mp4")); 261ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown } 262ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown 26345ca8fb42505658590e808d4d30b57598689d9a8Jeff Brown // Scan local external storage directory for media files. 26445ca8fb42505658590e808d4d30b57598689d9a8Jeff Brown File externalDir = Environment.getExternalStorageDirectory(); 26545ca8fb42505658590e808d4d30b57598689d9a8Jeff Brown if (externalDir != null) { 26645ca8fb42505658590e808d4d30b57598689d9a8Jeff Brown File list[] = externalDir.listFiles(); 26745ca8fb42505658590e808d4d30b57598689d9a8Jeff Brown if (list != null) { 26845ca8fb42505658590e808d4d30b57598689d9a8Jeff Brown for (int i = 0; i < list.length; i++) { 26945ca8fb42505658590e808d4d30b57598689d9a8Jeff Brown String filename = list[i].getName(); 27045ca8fb42505658590e808d4d30b57598689d9a8Jeff Brown if (filename.matches(".*\\.(m4v|mp4)")) { 27145ca8fb42505658590e808d4d30b57598689d9a8Jeff Brown mLibraryItems.add(new MediaItem("[local] " + filename, 272a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang Uri.fromFile(list[i]), "video/mp4")); 27345ca8fb42505658590e808d4d30b57598689d9a8Jeff Brown } 27445ca8fb42505658590e808d4d30b57598689d9a8Jeff Brown } 27557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 27657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 27757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 27857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang mPlayListItems = new PlaylistAdapter(); 27957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 280ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown // Initialize the layout. 281ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown setContentView(R.layout.sample_media_router); 282ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown 28357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang TabHost tabHost=(TabHost)findViewById(R.id.tabHost); 28457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang tabHost.setup(); 28557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang String tabName = getResources().getString(R.string.library_tab_text); 28657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang TabSpec spec1=tabHost.newTabSpec(tabName); 28757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang spec1.setContent(R.id.tab1); 28857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang spec1.setIndicator(tabName); 28957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 29057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang tabName = getResources().getString(R.string.playlist_tab_text); 29157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang TabSpec spec2=tabHost.newTabSpec(tabName); 29257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang spec2.setIndicator(tabName); 29357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang spec2.setContent(R.id.tab2); 29457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 295cf61a6ed2bfa6141b832fdc40a9fbfb70af91416Chong Zhang tabName = getResources().getString(R.string.info_tab_text); 29657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang TabSpec spec3=tabHost.newTabSpec(tabName); 29757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang spec3.setIndicator(tabName); 29857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang spec3.setContent(R.id.tab3); 29957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 30057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang tabHost.addTab(spec1); 30157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang tabHost.addTab(spec2); 30257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang tabHost.addTab(spec3); 30357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang tabHost.setOnTabChangedListener(new OnTabChangeListener() { 30457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang @Override 30557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang public void onTabChanged(String arg0) { 30657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang updateUi(); 30757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 30857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang }); 30957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 310fa2e2acf79d791a90410025daad438968550d18cAlan Viverette mLibraryView = findViewById(R.id.media); 31157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang mLibraryView.setAdapter(mLibraryItems); 31257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang mLibraryView.setChoiceMode(ListView.CHOICE_MODE_SINGLE); 31357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang mLibraryView.setOnItemClickListener(new OnItemClickListener() { 31457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang @Override 31557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang public void onItemClick(AdapterView<?> parent, View view, int position, long id) { 31657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang updateButtons(); 31757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 31857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang }); 319ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown 320fa2e2acf79d791a90410025daad438968550d18cAlan Viverette mPlayListView = findViewById(R.id.playlist); 32157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang mPlayListView.setAdapter(mPlayListItems); 32257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang mPlayListView.setChoiceMode(ListView.CHOICE_MODE_SINGLE); 32357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang mPlayListView.setOnItemClickListener(new OnItemClickListener() { 324ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown @Override 325ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown public void onItemClick(AdapterView<?> parent, View view, int position, long id) { 326ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown updateButtons(); 327ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown } 328ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown }); 329ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown 330fa2e2acf79d791a90410025daad438968550d18cAlan Viverette mInfoTextView = findViewById(R.id.info); 33157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 332fa2e2acf79d791a90410025daad438968550d18cAlan Viverette mUseDefaultControlCheckBox = findViewById(R.id.custom_control_view_checkbox); 33376d965dc41863b33f887db33d283cb7f1523f60dJae Seo if (ENABLE_DEFAULT_CONTROL_CHECK_BOX) { 33476d965dc41863b33f887db33d283cb7f1523f60dJae Seo mUseDefaultControlCheckBox.setVisibility(View.VISIBLE); 33576d965dc41863b33f887db33d283cb7f1523f60dJae Seo } 33657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang mPauseResumeButton = (ImageButton)findViewById(R.id.pause_resume_button); 33757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang mPauseResumeButton.setOnClickListener(new OnClickListener() { 338ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown @Override 339ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown public void onClick(View v) { 340cf61a6ed2bfa6141b832fdc40a9fbfb70af91416Chong Zhang if (mSessionManager.isPaused()) { 341a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang mSessionManager.resume(); 342cf61a6ed2bfa6141b832fdc40a9fbfb70af91416Chong Zhang } else { 343cf61a6ed2bfa6141b832fdc40a9fbfb70af91416Chong Zhang mSessionManager.pause(); 34457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 345ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown } 346ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown }); 347ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown 34857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang mStopButton = (ImageButton)findViewById(R.id.stop_button); 34957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang mStopButton.setOnClickListener(new OnClickListener() { 350ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown @Override 351ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown public void onClick(View v) { 352a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang mSessionManager.stop(); 353ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown } 354ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown }); 35557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 356fa2e2acf79d791a90410025daad438968550d18cAlan Viverette mSeekBar = findViewById(R.id.seekbar); 35757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang mSeekBar.setOnSeekBarChangeListener(new OnSeekBarChangeListener() { 35857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang @Override 35957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { 360a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang PlaylistItem item = getCheckedPlaylistItem(); 361a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang if (fromUser && item != null && item.getDuration() > 0) { 362a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang long pos = progress * item.getDuration() / 100; 363a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang mSessionManager.seek(item.getItemId(), pos); 364a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang item.setPosition(pos); 365a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang item.setTimestamp(SystemClock.elapsedRealtime()); 36657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 36757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 36857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang @Override 36957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang public void onStartTrackingTouch(SeekBar seekBar) { 37057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang mSeeking = true; 37157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 37257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang @Override 37357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang public void onStopTrackingTouch(SeekBar seekBar) { 37457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang mSeeking = false; 37557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang updateUi(); 37657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 37757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang }); 37857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 37957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang // Schedule Ui update 38057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang mHandler.postDelayed(mUpdateSeekRunnable, 1000); 38157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 3827578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang // Build the PendingIntent for the remote control client 3837578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang mAudioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE); 3847578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang mEventReceiver = new ComponentName(getPackageName(), 3857578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang SampleMediaButtonReceiver.class.getName()); 3867578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang Intent mediaButtonIntent = new Intent(Intent.ACTION_MEDIA_BUTTON); 3877578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang mediaButtonIntent.setComponent(mEventReceiver); 3887578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang mMediaPendingIntent = PendingIntent.getBroadcast(this, 0, mediaButtonIntent, 0); 3897b95dd38981772983f00c5ed91aca4b30b782facJeff Brown 3907b95dd38981772983f00c5ed91aca4b30b782facJeff Brown // Create and register the remote control client 3919a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik createMediaSession(); 3929a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik mMediaRouter.setMediaSessionCompat(mMediaSession); 393a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang 394a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang // Set up playback manager and player 395a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang mPlayer = Player.create(SampleMediaRouterActivity.this, 3969a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik mMediaRouter.getSelectedRoute(), mMediaSession); 3975d429bc3a8195d6f37cf2f7da0935972950539b4RoboErik 398a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang mSessionManager.setPlayer(mPlayer); 399a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang mSessionManager.setCallback(new SessionManager.Callback() { 400a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang @Override 401a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang public void onStatusChanged() { 402a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang updateUi(); 403a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang } 404a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang 405a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang @Override 406a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang public void onItemChanged(PlaylistItem item) { 407a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang } 408a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang }); 409a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang 410a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang updateUi(); 4117578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang } 4127578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang 4139a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik private void createMediaSession() { 4149a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik // Create the MediaSession 4159a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik mMediaSession = new MediaSessionCompat(this, "SampleMediaRouter", mEventReceiver, 4169a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik mMediaPendingIntent); 4179a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik mMediaSession.setFlags(MediaSessionCompat.FLAG_HANDLES_MEDIA_BUTTONS 4189a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik | MediaSessionCompat.FLAG_HANDLES_TRANSPORT_CONTROLS); 4199a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik mMediaSession.setCallback(new MediaSessionCompat.Callback() { 4209a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik @Override 4219a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik public boolean onMediaButtonEvent(Intent mediaButtonEvent) { 4229a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik if (mediaButtonEvent != null) { 4239a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik return handleMediaKey( 4249a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik (KeyEvent) mediaButtonEvent.getParcelableExtra(Intent.EXTRA_KEY_EVENT)); 4259a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik } 4269a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik return super.onMediaButtonEvent(mediaButtonEvent); 4279a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik } 4287578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang 4299a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik @Override 4309a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik public void onPlay() { 4319a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik mSessionManager.resume(); 4329a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik } 4339a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik 4349a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik @Override 4359a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik public void onPause() { 4369a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik mSessionManager.pause(); 4379a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik } 4389a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik }); 4399a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik 4409a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik SampleMediaButtonReceiver.setActivity(SampleMediaRouterActivity.this); 4417578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang } 4427578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang 4437578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang public boolean handleMediaKey(KeyEvent event) { 4449a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik if (event != null && event.getAction() == KeyEvent.ACTION_DOWN 4459a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik && event.getRepeatCount() == 0) { 4467578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang switch (event.getKeyCode()) { 4477578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang case KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE: 4489a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik case KeyEvent.KEYCODE_HEADSETHOOK: 4497578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang { 4507578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang Log.d(TAG, "Received Play/Pause event from RemoteControlClient"); 451cf61a6ed2bfa6141b832fdc40a9fbfb70af91416Chong Zhang if (mSessionManager.isPaused()) { 452a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang mSessionManager.resume(); 453cf61a6ed2bfa6141b832fdc40a9fbfb70af91416Chong Zhang } else { 454cf61a6ed2bfa6141b832fdc40a9fbfb70af91416Chong Zhang mSessionManager.pause(); 4557578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang } 4567578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang return true; 4577578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang } 4587578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang case KeyEvent.KEYCODE_MEDIA_PLAY: 4597578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang { 4607578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang Log.d(TAG, "Received Play event from RemoteControlClient"); 461cf61a6ed2bfa6141b832fdc40a9fbfb70af91416Chong Zhang if (mSessionManager.isPaused()) { 462a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang mSessionManager.resume(); 4637578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang } 4647578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang return true; 4657578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang } 4667578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang case KeyEvent.KEYCODE_MEDIA_PAUSE: 4677578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang { 4687578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang Log.d(TAG, "Received Pause event from RemoteControlClient"); 469cf61a6ed2bfa6141b832fdc40a9fbfb70af91416Chong Zhang if (!mSessionManager.isPaused()) { 470a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang mSessionManager.pause(); 4717578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang } 4727578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang return true; 4737578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang } 4747578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang case KeyEvent.KEYCODE_MEDIA_STOP: 4757578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang { 4767578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang Log.d(TAG, "Received Stop event from RemoteControlClient"); 477a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang mSessionManager.stop(); 4787578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang return true; 4797578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang } 4807578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang default: 4817578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang break; 4827578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang } 4837578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang } 4847578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang return false; 4857578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang } 4867578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang 4877578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang @Override 4887578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang public boolean onKeyDown(int keyCode, KeyEvent event) { 4897578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang return handleMediaKey(event) || super.onKeyDown(keyCode, event); 4907578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang } 4917578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang 4927578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang @Override 4937578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang public boolean onKeyUp(int keyCode, KeyEvent event) { 4947578fad97dcd3b4b390652f37a30d805538980f5Chong Zhang return handleMediaKey(event) || super.onKeyUp(keyCode, event); 495ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown } 496ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown 497ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown @Override 498f0dd451048100915f072423730a93d17c53fd899Jeff Brown public void onStart() { 499ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown // Be sure to call the super class. 500f0dd451048100915f072423730a93d17c53fd899Jeff Brown super.onStart(); 50157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 502ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown 50357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang @Override 50457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang public void onPause() { 50557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang // pause media player for local playback case only 506cf61a6ed2bfa6141b832fdc40a9fbfb70af91416Chong Zhang if (!mPlayer.isRemotePlayback() && !mSessionManager.isPaused()) { 50757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang mNeedResume = true; 508a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang mSessionManager.pause(); 50957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 51057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang super.onPause(); 51157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 51257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 51357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang @Override 51457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang public void onResume() { 51557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang // resume media player for local playback case only 516a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang if (!mPlayer.isRemotePlayback() && mNeedResume) { 517a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang mSessionManager.resume(); 51857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang mNeedResume = false; 51957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 52057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang super.onResume(); 52157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 52257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 52357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang @Override 52457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang public void onDestroy() { 525a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang mSessionManager.stop(); 526a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang mPlayer.release(); 5279a2de97bec8126f8c8c05e9c995f378c5a73319aRoboErik mMediaSession.release(); 52857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang super.onDestroy(); 529ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown } 530ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown 531ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown @Override 532ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown public boolean onCreateOptionsMenu(Menu menu) { 533ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown // Be sure to call the super class. 534ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown super.onCreateOptionsMenu(menu); 535ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown 536ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown // Inflate the menu and configure the media router action provider. 537ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown getMenuInflater().inflate(R.menu.sample_media_router_menu, menu); 538ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown 53955e47d370890d3cbdab82857090c42df734ba276Jeff Brown MenuItem mediaRouteMenuItem = menu.findItem(R.id.media_route_menu_item); 540f796be9c80d6a62de61853a0cb1d98b440a3586fSungsoo MediaRouteActionProvider mediaRouteActionProvider = 541f796be9c80d6a62de61853a0cb1d98b440a3586fSungsoo (MediaRouteActionProvider) MenuItemCompat.getActionProvider(mediaRouteMenuItem); 54255e47d370890d3cbdab82857090c42df734ba276Jeff Brown mediaRouteActionProvider.setRouteSelector(mSelector); 543cf61a6ed2bfa6141b832fdc40a9fbfb70af91416Chong Zhang mediaRouteActionProvider.setDialogFactory(new MediaRouteDialogFactory() { 544cf61a6ed2bfa6141b832fdc40a9fbfb70af91416Chong Zhang @Override 545cf61a6ed2bfa6141b832fdc40a9fbfb70af91416Chong Zhang public MediaRouteControllerDialogFragment onCreateControllerDialogFragment() { 54676d965dc41863b33f887db33d283cb7f1523f60dJae Seo return new ControllerDialogFragment(mPlayer, mUseDefaultControlCheckBox); 547cf61a6ed2bfa6141b832fdc40a9fbfb70af91416Chong Zhang } 548cf61a6ed2bfa6141b832fdc40a9fbfb70af91416Chong Zhang }); 549ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown 550ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown // Return true to show the menu. 551ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown return true; 552ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown } 553ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown 554a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang private void updateProgress() { 55557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang // Estimate content position from last status time and elapsed time. 55657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang // (Note this might be slightly out of sync with remote side, however 55757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang // it avoids frequent polling the MRP.) 55857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang int progress = 0; 559a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang PlaylistItem item = getCheckedPlaylistItem(); 560a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang if (item != null) { 561a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang int state = item.getState(); 562a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang long duration = item.getDuration(); 56357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang if (duration <= 0) { 56457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang if (state == MediaItemStatus.PLAYBACK_STATE_PLAYING 56557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang || state == MediaItemStatus.PLAYBACK_STATE_PAUSED) { 566a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang mSessionManager.updateStatus(); 56757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 56857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } else { 569a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang long position = item.getPosition(); 570cf61a6ed2bfa6141b832fdc40a9fbfb70af91416Chong Zhang long timeDelta = mSessionManager.isPaused() ? 0 : 571a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang (SystemClock.elapsedRealtime() - item.getTimestamp()); 57257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang progress = (int)(100.0 * (position + timeDelta) / duration); 57357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 574ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown } 57557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang mSeekBar.setProgress(progress); 57657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 577ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown 57857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang private void updateUi() { 57957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang updatePlaylist(); 580a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang updateRouteDescription(); 58157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang updateButtons(); 58270f3627685b55b2bc1b3f0c17c9c30aa3a7fd062Donghyun Cho if (mPlayer != null && mSessionManager != null) { 58370f3627685b55b2bc1b3f0c17c9c30aa3a7fd062Donghyun Cho PlaylistItem currentItem = mSessionManager.getCurrentItem(); 58470f3627685b55b2bc1b3f0c17c9c30aa3a7fd062Donghyun Cho if (currentItem != null) { 58570f3627685b55b2bc1b3f0c17c9c30aa3a7fd062Donghyun Cho mPlayer.updateMetadata(currentItem); 58670f3627685b55b2bc1b3f0c17c9c30aa3a7fd062Donghyun Cho int currentItemState = Player.STATE_IDLE; 58770f3627685b55b2bc1b3f0c17c9c30aa3a7fd062Donghyun Cho switch(currentItem.getState()) { 58870f3627685b55b2bc1b3f0c17c9c30aa3a7fd062Donghyun Cho case MediaItemStatus.PLAYBACK_STATE_PLAYING: 58970f3627685b55b2bc1b3f0c17c9c30aa3a7fd062Donghyun Cho currentItemState = Player.STATE_PLAYING; 59070f3627685b55b2bc1b3f0c17c9c30aa3a7fd062Donghyun Cho break; 59170f3627685b55b2bc1b3f0c17c9c30aa3a7fd062Donghyun Cho case MediaItemStatus.PLAYBACK_STATE_PAUSED: 59270f3627685b55b2bc1b3f0c17c9c30aa3a7fd062Donghyun Cho currentItemState = Player.STATE_PAUSED; 59370f3627685b55b2bc1b3f0c17c9c30aa3a7fd062Donghyun Cho break; 59470f3627685b55b2bc1b3f0c17c9c30aa3a7fd062Donghyun Cho case MediaItemStatus.PLAYBACK_STATE_PENDING: 59570f3627685b55b2bc1b3f0c17c9c30aa3a7fd062Donghyun Cho case MediaItemStatus.PLAYBACK_STATE_BUFFERING: 59670f3627685b55b2bc1b3f0c17c9c30aa3a7fd062Donghyun Cho currentItemState = Player.STATE_PREPARING_FOR_PLAY; 59770f3627685b55b2bc1b3f0c17c9c30aa3a7fd062Donghyun Cho break; 59870f3627685b55b2bc1b3f0c17c9c30aa3a7fd062Donghyun Cho } 59970f3627685b55b2bc1b3f0c17c9c30aa3a7fd062Donghyun Cho mPlayer.publishState(currentItemState); 60070f3627685b55b2bc1b3f0c17c9c30aa3a7fd062Donghyun Cho } 601cf61a6ed2bfa6141b832fdc40a9fbfb70af91416Chong Zhang } 602ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown } 603ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown 60457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang private void updatePlaylist() { 60557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang mPlayListItems.clear(); 606a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang for (PlaylistItem item : mSessionManager.getPlaylist()) { 607a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang mPlayListItems.add(item); 608a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang } 60957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang mPlayListView.invalidate(); 610a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang } 611ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown 612a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang private void updateRouteDescription() { 613a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang RouteInfo route = mMediaRouter.getSelectedRoute(); 614a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang mInfoTextView.setText("Currently selected route:" 615a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang + "\nName: " + route.getName() 61670f3627685b55b2bc1b3f0c17c9c30aa3a7fd062Donghyun Cho + "\nProvider: " + route.getProvider().getPackageName()); 61757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 618fcb6a9d1caaf43ae41f859ebb58a4483b12475a1Jeff Brown 619a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang private void updateButtons() { 620a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang MediaRouter.RouteInfo route = mMediaRouter.getSelectedRoute(); 621a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang // show pause or resume icon depending on current state 622cf61a6ed2bfa6141b832fdc40a9fbfb70af91416Chong Zhang mPauseResumeButton.setImageResource(mSessionManager.isPaused() ? 623a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang R.drawable.ic_media_play : R.drawable.ic_media_pause); 624a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang // only enable seek bar when duration is known 625a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang PlaylistItem item = getCheckedPlaylistItem(); 626a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang mSeekBar.setEnabled(item != null && item.getDuration() > 0); 62757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 628ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown 629a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang private PlaylistItem getCheckedPlaylistItem() { 63057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang int count = mPlayListView.getCount(); 63157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang int index = mPlayListView.getCheckedItemPosition(); 63257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang if (count > 0) { 63357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang if (index < 0 || index >= count) { 63457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang index = 0; 63557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang mPlayListView.setItemChecked(0, true); 63657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 63757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang return mPlayListItems.getItem(index); 638ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown } 63957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang return null; 640ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown } 641ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown 642f796be9c80d6a62de61853a0cb1d98b440a3586fSungsoo /** 643f796be9c80d6a62de61853a0cb1d98b440a3586fSungsoo * Media route discovery fragment. 644f796be9c80d6a62de61853a0cb1d98b440a3586fSungsoo */ 645f796be9c80d6a62de61853a0cb1d98b440a3586fSungsoo public static final class DiscoveryFragment extends MediaRouteDiscoveryFragment { 646f796be9c80d6a62de61853a0cb1d98b440a3586fSungsoo private static final String TAG = "DiscoveryFragment"; 647f796be9c80d6a62de61853a0cb1d98b440a3586fSungsoo private Callback mCallback; 648f796be9c80d6a62de61853a0cb1d98b440a3586fSungsoo 649f796be9c80d6a62de61853a0cb1d98b440a3586fSungsoo public void setCallback(Callback cb) { 650f796be9c80d6a62de61853a0cb1d98b440a3586fSungsoo mCallback = cb; 651f796be9c80d6a62de61853a0cb1d98b440a3586fSungsoo } 652f796be9c80d6a62de61853a0cb1d98b440a3586fSungsoo 653f796be9c80d6a62de61853a0cb1d98b440a3586fSungsoo @Override 654f796be9c80d6a62de61853a0cb1d98b440a3586fSungsoo public Callback onCreateCallback() { 655f796be9c80d6a62de61853a0cb1d98b440a3586fSungsoo return mCallback; 656f796be9c80d6a62de61853a0cb1d98b440a3586fSungsoo } 657f796be9c80d6a62de61853a0cb1d98b440a3586fSungsoo 658f796be9c80d6a62de61853a0cb1d98b440a3586fSungsoo @Override 659f796be9c80d6a62de61853a0cb1d98b440a3586fSungsoo public int onPrepareCallbackFlags() { 660f796be9c80d6a62de61853a0cb1d98b440a3586fSungsoo // Add the CALLBACK_FLAG_UNFILTERED_EVENTS flag to ensure that we will 661f796be9c80d6a62de61853a0cb1d98b440a3586fSungsoo // observe and log all route events including those that are for routes 662f796be9c80d6a62de61853a0cb1d98b440a3586fSungsoo // that do not match our selector. This is only for demonstration purposes 663f796be9c80d6a62de61853a0cb1d98b440a3586fSungsoo // and should not be needed by most applications. 664f796be9c80d6a62de61853a0cb1d98b440a3586fSungsoo return super.onPrepareCallbackFlags() 665f796be9c80d6a62de61853a0cb1d98b440a3586fSungsoo | MediaRouter.CALLBACK_FLAG_UNFILTERED_EVENTS; 666f796be9c80d6a62de61853a0cb1d98b440a3586fSungsoo } 667f796be9c80d6a62de61853a0cb1d98b440a3586fSungsoo } 668f796be9c80d6a62de61853a0cb1d98b440a3586fSungsoo 669ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown private static final class MediaItem { 670ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown public final String mName; 671ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown public final Uri mUri; 672a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang public final String mMime; 673ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown 674a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang public MediaItem(String name, Uri uri, String mime) { 675ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown mName = name; 676ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown mUri = uri; 677a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang mMime = mime; 678ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown } 679ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown 680ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown @Override 681ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown public String toString() { 682ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown return mName; 683ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown } 684ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown } 68555e47d370890d3cbdab82857090c42df734ba276Jeff Brown 68657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang private final class LibraryAdapter extends ArrayAdapter<MediaItem> { 68757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang public LibraryAdapter() { 68857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang super(SampleMediaRouterActivity.this, R.layout.media_item); 68957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 69057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 69157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang @Override 69257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang public View getView(int position, View convertView, ViewGroup parent) { 69357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang final View v; 69457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang if (convertView == null) { 69557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang v = getLayoutInflater().inflate(R.layout.media_item, null); 69657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } else { 69757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang v = convertView; 69857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 69957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 70057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang final MediaItem item = getItem(position); 70157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 70257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang TextView tv = (TextView)v.findViewById(R.id.item_text); 70357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang tv.setText(item.mName); 70457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 70557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang ImageButton b = (ImageButton)v.findViewById(R.id.item_action); 70657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang b.setImageResource(R.drawable.ic_menu_add); 70757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang b.setTag(item); 70857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang b.setOnClickListener(new OnClickListener() { 70957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang @Override 71057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang public void onClick(View v) { 71157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang if (item != null) { 71270f3627685b55b2bc1b3f0c17c9c30aa3a7fd062Donghyun Cho mSessionManager.add(item.mName, item.mUri, item.mMime); 71357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 71457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 71557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang }); 71657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 71757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang return v; 71857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 71957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 72057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 721a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang private final class PlaylistAdapter extends ArrayAdapter<PlaylistItem> { 72257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang public PlaylistAdapter() { 72357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang super(SampleMediaRouterActivity.this, R.layout.media_item); 72457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 72557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 72657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang @Override 72757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang public View getView(int position, View convertView, ViewGroup parent) { 72857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang final View v; 72957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang if (convertView == null) { 73057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang v = getLayoutInflater().inflate(R.layout.media_item, null); 73157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } else { 73257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang v = convertView; 73357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 73457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 735a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang final PlaylistItem item = getItem(position); 73657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 73757456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang TextView tv = (TextView)v.findViewById(R.id.item_text); 73857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang tv.setText(item.toString()); 73957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 74057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang ImageButton b = (ImageButton)v.findViewById(R.id.item_action); 74157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang b.setImageResource(R.drawable.ic_menu_delete); 74257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang b.setTag(item); 74357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang b.setOnClickListener(new OnClickListener() { 74457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang @Override 74557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang public void onClick(View v) { 74657456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang if (item != null) { 747a6bf581f7a7a6326505569f0d1215d0ba84779d7Chong Zhang mSessionManager.remove(item.getItemId()); 74857456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 74957456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 75057456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang }); 75157456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 75257456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang return v; 75357456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 75457456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang } 75557456222f52fbfc1dcfb1b99030aad6acc02ad23Chong Zhang 75655e47d370890d3cbdab82857090c42df734ba276Jeff Brown /** 75755e47d370890d3cbdab82857090c42df734ba276Jeff Brown * Trivial subclass of this activity used to provide another copy of the 75855e47d370890d3cbdab82857090c42df734ba276Jeff Brown * same activity using a light theme instead of the dark theme. 75955e47d370890d3cbdab82857090c42df734ba276Jeff Brown */ 76055e47d370890d3cbdab82857090c42df734ba276Jeff Brown public static class Light extends SampleMediaRouterActivity { 76155e47d370890d3cbdab82857090c42df734ba276Jeff Brown } 76255e47d370890d3cbdab82857090c42df734ba276Jeff Brown 76355e47d370890d3cbdab82857090c42df734ba276Jeff Brown /** 76455e47d370890d3cbdab82857090c42df734ba276Jeff Brown * Trivial subclass of this activity used to provide another copy of the 76555e47d370890d3cbdab82857090c42df734ba276Jeff Brown * same activity using a light theme with dark action bar instead of the dark theme. 76655e47d370890d3cbdab82857090c42df734ba276Jeff Brown */ 76755e47d370890d3cbdab82857090c42df734ba276Jeff Brown public static class LightWithDarkActionBar extends SampleMediaRouterActivity { 76855e47d370890d3cbdab82857090c42df734ba276Jeff Brown } 7695d429bc3a8195d6f37cf2f7da0935972950539b4RoboErik 7705d429bc3a8195d6f37cf2f7da0935972950539b4RoboErik public static class ControllerDialogFragment extends MediaRouteControllerDialogFragment { 7715d429bc3a8195d6f37cf2f7da0935972950539b4RoboErik private MediaRouteControllerDialog mControllerDialog; 7725d429bc3a8195d6f37cf2f7da0935972950539b4RoboErik private Player mPlayer; 77376d965dc41863b33f887db33d283cb7f1523f60dJae Seo private CheckBox mUseDefaultControlCheckBox; 7745d429bc3a8195d6f37cf2f7da0935972950539b4RoboErik 7755d429bc3a8195d6f37cf2f7da0935972950539b4RoboErik public ControllerDialogFragment() { 7765d429bc3a8195d6f37cf2f7da0935972950539b4RoboErik super(); 7775d429bc3a8195d6f37cf2f7da0935972950539b4RoboErik } 7785d429bc3a8195d6f37cf2f7da0935972950539b4RoboErik 77976d965dc41863b33f887db33d283cb7f1523f60dJae Seo public ControllerDialogFragment(Player player, CheckBox customControlViewCheckBox) { 7805d429bc3a8195d6f37cf2f7da0935972950539b4RoboErik mPlayer = player; 78176d965dc41863b33f887db33d283cb7f1523f60dJae Seo this.mUseDefaultControlCheckBox = customControlViewCheckBox; 7825d429bc3a8195d6f37cf2f7da0935972950539b4RoboErik } 7835d429bc3a8195d6f37cf2f7da0935972950539b4RoboErik 7845d429bc3a8195d6f37cf2f7da0935972950539b4RoboErik @Override 7855d429bc3a8195d6f37cf2f7da0935972950539b4RoboErik public MediaRouteControllerDialog onCreateControllerDialog( 7865d429bc3a8195d6f37cf2f7da0935972950539b4RoboErik Context context, Bundle savedInstanceState) { 78776d965dc41863b33f887db33d283cb7f1523f60dJae Seo mControllerDialog = this.mUseDefaultControlCheckBox.isChecked() 78876d965dc41863b33f887db33d283cb7f1523f60dJae Seo ? super.onCreateControllerDialog(context, savedInstanceState) 78976d965dc41863b33f887db33d283cb7f1523f60dJae Seo : new MyMediaRouteControllerDialog(context); 7905d429bc3a8195d6f37cf2f7da0935972950539b4RoboErik mControllerDialog.setOnDismissListener(new DialogInterface.OnDismissListener() { 7915d429bc3a8195d6f37cf2f7da0935972950539b4RoboErik @Override 7925d429bc3a8195d6f37cf2f7da0935972950539b4RoboErik public void onDismiss(DialogInterface dialog) { 7935d429bc3a8195d6f37cf2f7da0935972950539b4RoboErik mControllerDialog = null; 7945d429bc3a8195d6f37cf2f7da0935972950539b4RoboErik } 7955d429bc3a8195d6f37cf2f7da0935972950539b4RoboErik }); 7965d429bc3a8195d6f37cf2f7da0935972950539b4RoboErik return mControllerDialog; 7975d429bc3a8195d6f37cf2f7da0935972950539b4RoboErik } 7985d429bc3a8195d6f37cf2f7da0935972950539b4RoboErik 7995d429bc3a8195d6f37cf2f7da0935972950539b4RoboErik public void setPlayer(Player player) { 8005d429bc3a8195d6f37cf2f7da0935972950539b4RoboErik mPlayer = player; 8015d429bc3a8195d6f37cf2f7da0935972950539b4RoboErik } 8025d429bc3a8195d6f37cf2f7da0935972950539b4RoboErik } 803ecdd1b114d4fb36682cdabe205e08e6f68f79f63Jeff Brown} 804