diff --git a/samples/Support7Demos/AndroidManifest.xml b/samples/Support7Demos/AndroidManifest.xml
index 273af1e10..4735433c5 100644
--- a/samples/Support7Demos/AndroidManifest.xml
+++ b/samples/Support7Demos/AndroidManifest.xml
@@ -48,7 +48,11 @@
-
+
+
+
+
+
= 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();
}
}
diff --git a/samples/Support7Demos/src/com/example/android/supportv7/media/SampleMediaRouterActivity.java b/samples/Support7Demos/src/com/example/android/supportv7/media/SampleMediaRouterActivity.java
index cca7e101c..4305cea80 100644
--- a/samples/Support7Demos/src/com/example/android/supportv7/media/SampleMediaRouterActivity.java
+++ b/samples/Support7Demos/src/com/example/android/supportv7/media/SampleMediaRouterActivity.java
@@ -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