am 620b29a5: media router sample: handle remote volume change
* commit '620b29a566e87ce7bb21223150ff97f919fee836': media router sample: handle remote volume change
This commit is contained in:
@@ -48,7 +48,11 @@
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
|
||||
<receiver android:name="com.example.android.supportv7.media.SampleMediaButtonReceiver">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MEDIA_BUTTON" />
|
||||
</intent-filter>
|
||||
</receiver>
|
||||
<!-- MediaRouter Support Samples -->
|
||||
|
||||
<activity android:name=".media.SampleMediaRouterActivity"
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
* Copyright (C) 2013 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.example.android.supportv7.media;
|
||||
|
||||
import com.example.android.supportv7.R;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.util.Log;
|
||||
import android.view.KeyEvent;
|
||||
|
||||
/**
|
||||
* Broadcast receiver for handling ACTION_MEDIA_BUTTON.
|
||||
*
|
||||
* This is needed to create the RemoteControlClient for controlling
|
||||
* remote route volume in lock screen. It routes media key events back
|
||||
* to main app activity SampleMediaRouterActivity.
|
||||
*/
|
||||
public class SampleMediaButtonReceiver extends BroadcastReceiver {
|
||||
private static final String TAG = "SampleMediaButtonReceiver";
|
||||
private static SampleMediaRouterActivity mActivity;
|
||||
|
||||
public static void setActivity(SampleMediaRouterActivity activity) {
|
||||
mActivity = activity;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
if (mActivity != null && Intent.ACTION_MEDIA_BUTTON.equals(intent.getAction())) {
|
||||
mActivity.handleMediaKey(
|
||||
(KeyEvent)intent.getParcelableExtra(Intent.EXTRA_KEY_EVENT));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -23,6 +23,7 @@ import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.content.IntentFilter.MalformedMimeTypeException;
|
||||
import android.content.res.Resources;
|
||||
import android.media.AudioManager;
|
||||
import android.media.MediaRouter;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
@@ -161,6 +162,7 @@ final class SampleMediaRouteProvider extends MediaRouteProvider {
|
||||
r.getString(R.string.fixed_volume_route_name))
|
||||
.setDescription(r.getString(R.string.sample_route_description))
|
||||
.addControlFilters(CONTROL_FILTERS)
|
||||
.setPlaybackStream(AudioManager.STREAM_MUSIC)
|
||||
.setPlaybackType(MediaRouter.RouteInfo.PLAYBACK_TYPE_REMOTE)
|
||||
.setVolumeHandling(MediaRouter.RouteInfo.PLAYBACK_VOLUME_FIXED)
|
||||
.setVolume(VOLUME_MAX)
|
||||
@@ -171,6 +173,7 @@ final class SampleMediaRouteProvider extends MediaRouteProvider {
|
||||
r.getString(R.string.variable_volume_route_name))
|
||||
.setDescription(r.getString(R.string.sample_route_description))
|
||||
.addControlFilters(CONTROL_FILTERS)
|
||||
.setPlaybackStream(AudioManager.STREAM_MUSIC)
|
||||
.setPlaybackType(MediaRouter.RouteInfo.PLAYBACK_TYPE_REMOTE)
|
||||
.setVolumeHandling(MediaRouter.RouteInfo.PLAYBACK_VOLUME_VARIABLE)
|
||||
.setVolumeMax(VOLUME_MAX)
|
||||
@@ -287,6 +290,9 @@ final class SampleMediaRouteProvider extends MediaRouteProvider {
|
||||
if (volume >= 0 && volume <= VOLUME_MAX) {
|
||||
mVolume = volume;
|
||||
Log.d(TAG, mRouteId + ": New volume is " + mVolume);
|
||||
AudioManager audioManager =
|
||||
(AudioManager)getContext().getSystemService(Context.AUDIO_SERVICE);
|
||||
audioManager.setStreamVolume(AudioManager.STREAM_MUSIC, volume, 0);
|
||||
publishRoutes();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@ package com.example.android.supportv7.media;
|
||||
|
||||
import com.example.android.supportv7.R;
|
||||
|
||||
import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
@@ -26,7 +27,13 @@ import android.content.res.Resources;
|
||||
import android.content.DialogInterface;
|
||||
import android.app.PendingIntent;
|
||||
import android.app.Presentation;
|
||||
import android.media.AudioManager;
|
||||
import android.media.AudioManager.OnAudioFocusChangeListener;
|
||||
import android.media.MediaMetadataRetriever;
|
||||
import android.media.RemoteControlClient;
|
||||
import android.media.RemoteControlClient.MetadataEditor;
|
||||
import android.net.Uri;
|
||||
import android.os.Build;
|
||||
import android.os.Handler;
|
||||
import android.os.Bundle;
|
||||
import android.os.SystemClock;
|
||||
@@ -44,6 +51,7 @@ import android.support.v7.media.MediaRouteSelector;
|
||||
import android.support.v7.media.MediaItemStatus;
|
||||
import android.util.Log;
|
||||
import android.view.Gravity;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
@@ -193,11 +201,17 @@ public class SampleMediaRouterActivity extends ActionBarActivity {
|
||||
}
|
||||
playerCB = mRemotePlayer;
|
||||
mRemotePlayer.reset();
|
||||
|
||||
// Create and register the remote control client
|
||||
registerRCC();
|
||||
} else {
|
||||
// Local Playback:
|
||||
// Use local player and feed media player one item at a time
|
||||
player = mLocalPlayer;
|
||||
playerCB = mMediaPlayer;
|
||||
|
||||
// Unregister the remote control client
|
||||
unregisterRCC();
|
||||
}
|
||||
|
||||
if (player != mPlayer || playerCB != mPlayerCB) {
|
||||
@@ -301,6 +315,24 @@ public class SampleMediaRouterActivity extends ActionBarActivity {
|
||||
}
|
||||
};
|
||||
|
||||
private RemoteControlClient mRemoteControlClient;
|
||||
private ComponentName mEventReceiver;
|
||||
private AudioManager mAudioManager;
|
||||
private PendingIntent mMediaPendingIntent;
|
||||
private final OnAudioFocusChangeListener mAfChangeListener =
|
||||
new OnAudioFocusChangeListener() {
|
||||
@Override
|
||||
public void onAudioFocusChange(int focusChange) {
|
||||
if (focusChange == AudioManager.AUDIOFOCUS_LOSS_TRANSIENT) {
|
||||
Log.d(TAG, "onAudioFocusChange: LOSS_TRANSIENT");
|
||||
} else if (focusChange == AudioManager.AUDIOFOCUS_GAIN) {
|
||||
Log.d(TAG, "onAudioFocusChange: AUDIOFOCUS_GAIN");
|
||||
} else if (focusChange == AudioManager.AUDIOFOCUS_LOSS) {
|
||||
Log.d(TAG, "onAudioFocusChange: AUDIOFOCUS_LOSS");
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
// Be sure to call the super class.
|
||||
@@ -471,6 +503,97 @@ public class SampleMediaRouterActivity extends ActionBarActivity {
|
||||
IntentFilter filter = new IntentFilter();
|
||||
filter.addAction(SampleMediaRouterActivity.ACTION_STATUS_CHANGE);
|
||||
registerReceiver(mReceiver, filter);
|
||||
|
||||
// Build the PendingIntent for the remote control client
|
||||
mAudioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
|
||||
mEventReceiver = new ComponentName(getPackageName(),
|
||||
SampleMediaButtonReceiver.class.getName());
|
||||
Intent mediaButtonIntent = new Intent(Intent.ACTION_MEDIA_BUTTON);
|
||||
mediaButtonIntent.setComponent(mEventReceiver);
|
||||
mMediaPendingIntent = PendingIntent.getBroadcast(this, 0, mediaButtonIntent, 0);
|
||||
}
|
||||
|
||||
private void registerRCC() {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
|
||||
// Create the RCC and register with AudioManager and MediaRouter
|
||||
mAudioManager.requestAudioFocus(mAfChangeListener,
|
||||
AudioManager.STREAM_MUSIC, AudioManager.AUDIOFOCUS_GAIN);
|
||||
mAudioManager.registerMediaButtonEventReceiver(mEventReceiver);
|
||||
mRemoteControlClient = new RemoteControlClient(mMediaPendingIntent);
|
||||
mAudioManager.registerRemoteControlClient(mRemoteControlClient);
|
||||
mMediaRouter.addRemoteControlClient(mRemoteControlClient);
|
||||
SampleMediaButtonReceiver.setActivity(SampleMediaRouterActivity.this);
|
||||
mRemoteControlClient.setTransportControlFlags(
|
||||
RemoteControlClient.FLAG_KEY_MEDIA_PLAY_PAUSE);
|
||||
mRemoteControlClient.setPlaybackState(
|
||||
RemoteControlClient.PLAYSTATE_PLAYING);
|
||||
}
|
||||
}
|
||||
|
||||
private void unregisterRCC() {
|
||||
// Unregister the RCC with AudioManager and MediaRouter
|
||||
if (mRemoteControlClient != null) {
|
||||
mRemoteControlClient.setTransportControlFlags(0);
|
||||
mAudioManager.abandonAudioFocus(mAfChangeListener);
|
||||
mAudioManager.unregisterMediaButtonEventReceiver(mEventReceiver);
|
||||
mAudioManager.unregisterRemoteControlClient(mRemoteControlClient);
|
||||
mMediaRouter.removeRemoteControlClient(mRemoteControlClient);
|
||||
SampleMediaButtonReceiver.setActivity(null);
|
||||
mRemoteControlClient = null;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean handleMediaKey(KeyEvent event) {
|
||||
if (event.getAction() == KeyEvent.ACTION_DOWN && event.getRepeatCount() == 0) {
|
||||
switch (event.getKeyCode()) {
|
||||
case KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE:
|
||||
{
|
||||
Log.d(TAG, "Received Play/Pause event from RemoteControlClient");
|
||||
if (!mPaused) {
|
||||
mPlayer.pause();
|
||||
} else {
|
||||
mPlayer.resume();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
case KeyEvent.KEYCODE_MEDIA_PLAY:
|
||||
{
|
||||
Log.d(TAG, "Received Play event from RemoteControlClient");
|
||||
if (mPaused) {
|
||||
mPlayer.resume();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
case KeyEvent.KEYCODE_MEDIA_PAUSE:
|
||||
{
|
||||
Log.d(TAG, "Received Pause event from RemoteControlClient");
|
||||
if (!mPaused) {
|
||||
mPlayer.pause();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
case KeyEvent.KEYCODE_MEDIA_STOP:
|
||||
{
|
||||
Log.d(TAG, "Received Stop event from RemoteControlClient");
|
||||
mPlayer.stop();
|
||||
clearContent();
|
||||
return true;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onKeyDown(int keyCode, KeyEvent event) {
|
||||
return handleMediaKey(event) || super.onKeyDown(keyCode, event);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onKeyUp(int keyCode, KeyEvent event) {
|
||||
return handleMediaKey(event) || super.onKeyUp(keyCode, event);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -549,6 +672,10 @@ public class SampleMediaRouterActivity extends ActionBarActivity {
|
||||
// only enable seek bar when duration is known
|
||||
MediaQueueItem item = getCheckedMediaQueueItem();
|
||||
mSeekBar.setEnabled(item != null && item.getContentDuration() > 0);
|
||||
if (mRemoteControlClient != null) {
|
||||
mRemoteControlClient.setPlaybackState(mPaused ?
|
||||
RemoteControlClient.PLAYSTATE_PAUSED : RemoteControlClient.PLAYSTATE_PLAYING);
|
||||
}
|
||||
}
|
||||
|
||||
private void updateProgress(MediaQueueItem queueItem) {
|
||||
@@ -684,6 +811,13 @@ public class SampleMediaRouterActivity extends ActionBarActivity {
|
||||
Log.d(TAG, "LocalPlayer: enqueue, uri=" + uri + ", pos=" + pos);
|
||||
MediaQueueItem playlistItem = mSessionManager.enqueue(mSessionId, uri, null);
|
||||
mSessionId = playlistItem.getSessionId();
|
||||
// Set remote control client title
|
||||
if (mPlayListItems.getCount() == 0 && mRemoteControlClient != null) {
|
||||
RemoteControlClient.MetadataEditor ed = mRemoteControlClient.editMetadata(true);
|
||||
ed.putString(MediaMetadataRetriever.METADATA_KEY_TITLE,
|
||||
playlistItem.toString());
|
||||
ed.apply();
|
||||
}
|
||||
mPlayListItems.add(playlistItem);
|
||||
if (pos > 0) {
|
||||
// Seek to initial position if needed
|
||||
|
||||
Reference in New Issue
Block a user