控制第三方播放的播放状态
控制第三方播放的播放暂停等等可以通过AudioManager API控制其他播放器的播放状态
//播放/暂停
import android.view.KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE;
//播放
import android.view.KeyEvent.KEYCODE_MEDIA_PLAY;
//暂停
import android.view.KeyEvent.KEYCODE_MEDIA_PAUSE;
//上一曲
import android.view.KeyEvent.KEYCODE_MEDIA_PREVIOUS;
//下一曲
import android.view.KeyEvent.KEYCODE_MEDIA_NEXT;
/**
* 模拟按键事件
*/
private void sendKeyEvent(final int keyCode) {
KeyEvent keyEvent = new KeyEvent(KeyEvent.ACTION_DOWN, keyCode);
audioManager.dispatchMediaKeyEvent(keyEvent);
keyEvent = new KeyEvent(KeyEvent.ACTION_UP, keyCode);
audioManager.dispatchMediaKeyEvent(keyEvent);
}
获取第三方播放器的播放信息
第一步获取通知权限
获取第三方的播放信息需要android.permission.BIND_NOTIFICATION_LISTENER_SERVICE权限,并且要获得用户的许可
<!--通知的监听服务 继承android.service.notification.NotificationListenerService-->
<service android:name=".YourNotificationListenerService"
android:permission="android.permission.BIND_NOTIFICATION_LISTENER_SERVICE">
<intent-filter>
<action android:name="android.service.notification.NotificationListenerService" />
</intent-filter>
</service>
//进入通知权限设置,找到自己的应用并打开
startActivity(new Intent("android.settings.ACTION_NOTIFICATION_LISTENER_SETTINGS"));
判断是否开启了通知权限
public static boolean isNotificationListenerEnabled(Context context) {
Set<String> packageNames = NotificationManagerCompat.getEnabledListenerPackages(context);
if (packageNames.contains(context.getPackageName())) {
return true;
}
return false;
}
第二步获取播放信息
在运行设备Android >= 21 ,使用MediaSessionManager
获取活动的MediaController
Object service =getContext().getSystemService(Context.MEDIA_SESSION_SERVICE);
if (service instanceof MediaSessionManager) {
MediaSessionManager manager = (MediaSessionManager) service;
ComponentName componentName =
new ComponentName(this, YourNotificationListenerService.class);
mSessionsChangedListener
= new MediaSessionManager.OnActiveSessionsChangedListener() {
@Override
public void onActiveSessionsChanged(List<MediaController> controllers) {
synchronized (this) {
mActiveSessions = controllers;
registerSessionCallbacks();
}
}
};
manager.addOnActiveSessionsChangedListener(mSessionsChangedListener, componentName);
synchronized (this) {
mActiveSessions = manager.getActiveSessions(componentName);
registerSessionCallbacks();
}
}
在这里通过MediaMetadata和PlaybackState就可以获取到第三方播放器的播放信息和播放状态
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
private void registerSessionCallbacks() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
for (MediaController controller : mActiveSessions) {
if (mSessionCallback == null) {
mSessionCallback = new MediaController.Callback() {
@Override
public void onMetadataChanged(MediaMetadata metadata) {
if (metadata != null) {
String trackName =
metadata.getString(MediaMetadata.METADATA_KEY_TITLE);
String artistName =
metadata.getString(MediaMetadata.METADATA_KEY_ARTIST);
String albumArtistName =
metadata.getString(MediaMetadata.METADATA_KEY_ALBUM_ARTIST);
String albumName =
metadata.getString(MediaMetadata.METADATA_KEY_ALBUM);
}
}
@Override
public void onPlaybackStateChanged(PlaybackState state) {
if(state != null){
boolean isPlaying = state.getState() == PlaybackState.STATE_PLAYING
}
}
};
}
controller.registerCallback(mSessionCallback);
}
}
}
在运行设备Android < 21 ,使用RemoteController
public void registerRemoteController() {
//YourNotificationListenerService实现RemoteController.OnClientUpdateListener接口
mRemoteController = new RemoteController(getContext(), this);
boolean registered;
try {
registered = ((AudioManager) getSystemService(AUDIO_SERVICE)).registerRemoteController(mRemoteController);
} catch (NullPointerException | SecurityException e) {
registered = false;
}
if (registered) {
try {
mRemoteController.setArtworkConfiguration(100, 100);
mRemoteController.setSynchronizationMode(RemoteController.POSITION_SYNCHRONIZATION_CHECK);
} catch (IllegalArgumentException e) {
e.printStackTrace();
}
}
}
回调的播放信息和播放状态
@Override
public void onClientMetadataUpdate(RemoteController.MetadataEditor arg0) {
String trackName = arg0.getString(MediaMetadataRetriever.METADATA_KEY_TITLE, null);
String artistName = arg0.getString(MediaMetadataRetriever.METADATA_KEY_ARTIST, null);
String albumArtistName = arg0
.getString(MediaMetadataRetriever.METADATA_KEY_ALBUMARTIST, null);
String albumName = arg0.getString(MediaMetadataRetriever.METADATA_KEY_ALBUM, null);
}
@Override
public void onClientPlaybackStateUpdate(int state, long stateChangeTimeMs, long currentPosMs, float speed) {
boolean isPlaying = state == PlaybackState.STATE_PLAYING
}
并不是所有的第三方音乐app都可以获取到它播放信息和播放状态,如果第三方播放器没有把
MediaMetadata和PlaybackState给到
MediaSession,通过以上方法是无法获取到该app的播放信息和播放状态的。
具体媒体类app怎么把播放器和播放状态给到Android系统,可以参考android的官方音乐播放器demouamp,最新的代码是kotlin的,java的可以看1.2版本的MusicService。
最后感谢:
stackoverflow.com/questions/5…
最后最后就是还有个bug,因为现在很多音乐播放器支持同时播放,就可能会导致获取到的播放信息和播放状态不对。