Android RemoteController使用

原文链接

RemoteController在API 19 引进,用来给音乐控制提供标准接口。长久以来,音乐播放在Android平台没有一个标准的接口,所有播放器都使用自己的方式实现对音乐的控制,最常见的方式是在Service中进行音乐播放,通过PendingIntent进行播放事件的传递及控制,因此就带来了一个问题。任何一个第三方app无法通过标准方式获取到当前正在播放的音乐的信息,更无法进行控制。RemoteController的出现恰好解决了这个问题,RemoteController需要和RemoteControlClient配合使用,从命名上能够看出,RemoteController是控制及信息获取端的接口,用来进行音乐信息的获取以及音乐播放动作的发送。RemoteControlClient是播放器端的接口,用来获取并执行播放动作,同时讲当前播放状态信息进行同步。

然而相关文档介绍很少。

使用方式

1.继承 NotificationListenerService 并实现RemoteController.OnClientUpdateListener接口来创建remoteController对象并获取播放进度

@TargetApi(Build.VERSION_CODES.KITKAT)

public class MusicStateListener extends NotificationListenerService

implements RemoteController.OnClientUpdateListener {

}

NotificationListenerService的主要作用是用来获取和操作通知栏通知,由于很奇葩的原因,为了获取合法的remoteController对象,必须实现这样一个NotificationListenerService并作为onClientUpdateListener传入remoteController来实现。

public void registerRemoteController() {

remoteController = new RemoteController(this, this);

boolean registered;

try {

registered = ((AudioManager) getSystemService(AUDIO_SERVICE))

.registerRemoteController(remoteController);

} catch (NullPointerException e) {

registered = false;

}

if (registered) {

try {

remoteController.setArtworkConfiguration(

getResources().getDimensionPixelSize(R.dimen.remote_artwork_bitmap_width),

getResources().getDimensionPixelSize(R.dimen.remote_artwork_bitmap_height));

remoteController.setSynchronizationMode(RemoteController.POSITION_SYNCHRONIZATION_CHECK);

} catch (IllegalArgumentException e) {

e.printStackTrace();

}

}

}

RemoteController的初始化传入的两个参数分别是context和updateListener,而且此处的context必须是notificationListenerService

2.获取播放信息

合法register之后在回调中会接收到播放信息,包括播放/暂停等动作信息以及歌曲的meta信息

/**

* Interface definition for the callbacks to be invoked whenever media events, metadata

* and playback status are available.

*/

public interface OnClientUpdateListener {

/**

* Called whenever all information, previously received through the other

* methods of the listener, is no longer valid and is about to be refreshed.

* This is typically called whenever a new {@link RemoteControlClient} has been selected

* by the system to have its media information published.

* @param clearing true if there is no selected RemoteControlClient and no information

* is available.

*/

public void onClientChange(boolean clearing);

/**

* Called whenever the playback state has changed.

* It is called when no information is known about the playback progress in the media and

* the playback speed.

* @param state one of the playback states authorized

* in {@link RemoteControlClient#setPlaybackState(int)}.

*/

public void onClientPlaybackStateUpdate(int state);

/**

* Called whenever the playback state has changed, and playback position

* and speed are known.

* @param state one of the playback states authorized

* in {@link RemoteControlClient#setPlaybackState(int)}.

* @param stateChangeTimeMs the system time at which the state change was reported,

* expressed in ms. Based on {@link android.os.SystemClock#elapsedRealtime()}.

* @param currentPosMs a positive value for the current media playback position expressed

* in ms, a negative value if the position is temporarily unknown.

* @param speed a value expressed as a ratio of 1x playback: 1.0f is normal playback,

* 2.0f is 2x, 0.5f is half-speed, -2.0f is rewind at 2x speed. 0.0f means nothing is

* playing (e.g. when state is {@link RemoteControlClient#PLAYSTATE_ERROR}).

*/

public void onClientPlaybackStateUpdate(int state, long stateChangeTimeMs,

long currentPosMs, float speed);

/**

* Called whenever the transport control flags have changed.

* @param transportControlFlags one of the flags authorized

* in {@link RemoteControlClient#setTransportControlFlags(int)}.

*/

public void onClientTransportControlUpdate(int transportControlFlags);

/**

* Called whenever new metadata is available.

* See the {@link MediaMetadataEditor#putLong(int, long)},

* {@link MediaMetadataEditor#putString(int, String)},

* {@link MediaMetadataEditor#putBitmap(int, Bitmap)}, and

* {@link MediaMetadataEditor#putObject(int, Object)} methods for the various keys that

* can be queried.

* @param metadataEditor the container of the new metadata.

*/

public void onClientMetadataUpdate(MetadataEditor metadataEditor);

};

音乐的meta信息从onClientMetadataUpdate回调中获取,能够获取到的字段包括歌手、名称、专辑名称、专辑封面等。注意此处获取到的专辑封面bitmap的尺寸是由注册remoteController时setArtworkConfiguration (int, int)来决定的

3.音乐控制

音乐的控制主要通过remoteController的sendMediaKeyEvent来实现

需要注意的是音乐的控制在逻辑上是模拟按钮的点击动作来实现的,所以在send一个keyCode时需要先后send KEY_ACTION_DOWN和KEY_ACTION_UP两个event来实现,所以我的实现是这样的

public boolean sendMusicKeyEvent(int keyCode) {

if (!clientIdLost && remoteController != null) {

// send "down" and "up" key events.

KeyEvent keyEvent = new KeyEvent(KeyEvent.ACTION_DOWN, keyCode);

boolean down = remoteController.sendMediaKeyEvent(keyEvent);

keyEvent = new KeyEvent(KeyEvent.ACTION_UP, keyCode);

boolean up = remoteController.sendMediaKeyEvent(keyEvent);

return down && up;

} else {

long eventTime = SystemClock.uptimeMillis();

KeyEvent key = new KeyEvent(eventTime, eventTime, KeyEvent.ACTION_DOWN, keyCode, 0);

dispatchMediaKeyToAudioService(key);

dispatchMediaKeyToAudioService(KeyEvent.changeAction(key, KeyEvent.ACTION_UP));

}

return false;

}

private void dispatchMediaKeyToAudioService(KeyEvent event) {

AudioManager audioManager = (AudioManager) getSystemService(AUDIO_SERVICE);

if (audioManager != null) {

try {

audioManager.dispatchMediaKeyEvent(event);

} catch (Exception e) {

e.printStackTrace();

}

}

}

前面一部分是刚才讲到的通过remoteController来sendMediaKeyEvent,后面一部分是当remoteClient发生变化时remoteController的传递会失效,此时可以通过AudioManager来传递事件,

注意事项

1.注册RemoteController时OnClientUpdateListener必须是NotificationListenerService

2.发送KeyEvent时先发送ACTION_DOWN再发送ACTION_UP才是一个完整的事件;

android 控制音乐,Android音乐控制接口RemoteController使用相关推荐

  1. Android QQ音乐/酷狗音乐锁屏控制实现原理,酷狗锁屏

    混乱的锁屏控制 Android自4.0版本, 也就是API level 14开始, 加入了锁屏控制的功能, 相关的类是RemoteControlClient, 这个类在API level 21中被标记 ...

  2. Android 安全架构及权限控制机制剖析

    简介: Android 是业界流行的开源移动平台,受到广泛关注并为多个手机制造商作为手机的操作系统平台,因此,研究其安全架构及权限控制机制具有非常的重要性.本文从 Android 层次化安全架构入手, ...

  3. Android之简单本地音乐播放器

    平台:Android studio APK:http://fir.im/apps/56ea5187e75e2d69af000042 本地的音乐播放器,主要功能就是可以播放音乐,能够读取本地的音乐,并显 ...

  4. java4android网易云,Android仿网易云音乐播放界面

    概述 网易云音乐是一款非常优秀的音乐播放器,尤其是播放界面,使用唱盘机风格,显得格外古典优雅. 首先来看一下网易的播放效果. 要实现上面的功能,我们需要对界面进行一个拆分,拆分后大概包含如下结构: 主 ...

  5. Android开发之本地音乐播放器(二)

    此次音乐播放器是针对上一个:https://blog.csdn.net/qq_43433255/article/details/88084420 开发出来的一个功能增强型,基本实现功能为: 通过列表管 ...

  6. Android实战 - 音心音乐播发器 (主界面实现)

    开发平台 : eclipse , ubuntu ,android  sdk 4.0+ 1.背景 主页的设计从上往下依次是滚动广告(ViewFlipper ),分类信息( GridView ),热门榜单 ...

  7. Android仿网易云音乐播放界面

    概述 网易云音乐是一款非常优秀的音乐播放器,尤其是播放界面,使用唱盘机风格,显得格外古典优雅.这里抛砖引玉,原文地址:http://www.jianshu.com/p/cb54990219d9 首先来 ...

  8. Android应用开发--MP3音乐播放器Service实现

    Android应用开发--MP3音乐播放器Service实现 2013年5月29日简.美音乐播放器开发记录 让网友们久等啦,关于简.美音乐播放器的开发,最重要的Service类总算是要发博了.关于An ...

  9. Android制作简易的音乐播放器和视频播放器

    文章目录 制作简易的音乐播放器和视频播放器 播放多媒体文件 播放音频 MediaPlayer的工作流程 项目示例 播放视频 项目示例 制作简易的音乐播放器和视频播放器 播放多媒体文件 Android在 ...

最新文章

  1. 红警2Linux版本
  2. 大脑天天超负荷,三分天赋,七分练,世间惊现普通脑修炼秘籍
  3. Platform.Uno介绍
  4. P4827-[国家集训队]Crash 的文明世界【树形dp,换根法,斯特林数】
  5. php layout布局文件,layout(布局) - jQuery EasyUI中文文档 - EasyUI中文站
  6. PHP+MySql+PDO实现简单登录、注册
  7. 目前已经学习的一些matlab函数
  8. 4000多人全靠报表自动化,效率提高60%,这套数据平台方法论真强
  9. idea android 开发
  10. 公司要一个网站,是选模板建站还是定制化建站?
  11. 基于单片机的脉搏心率远程监测
  12. STM32F103C6T6初步学习
  13. java获取本机的外网IP地址(亲测有效)
  14. 流程图绘制工具 yEd
  15. 有关java多态性的介绍
  16. 为什么YUV全为0的图像是绿色的
  17. SAS 时间秒 转换成多少小时,多少分钟,多少秒
  18. docker实战学习2022版本(七)之docker网络学习
  19. 17个获取设计灵感创意必备网站
  20. 超过4G如何制作NTFS格式WINPE?

热门文章

  1. Java 序列化的这三个坑千万要小心
  2. 开源项目征集 | CSDN “开源加速器计划”之【开源技术栈选型 Show】
  3. 当 AI 遇见经典,科大讯飞发布两款智能笔记本新品!
  4. 拿着 22 万美元年薪,混得还不如实习生?
  5. 战疫,微软资深高管的十余年远程办公管理经验
  6. 作为多年 PHP 的开发者,在使用了 Go 语言之后......
  7. 任何人都可以胜任全栈开发?
  8. 产品小姐姐收到这个黑科技后,开心了一整天...
  9. “Hyperledger Fabric 是假区块链!”
  10. 调查 10,500 名 Java 开发者发现,收费的 OracleJDK 仍是主流、IntelliJ IDEA 最受欢迎...