Android RemoteController使用

写一个APP控制第三方播放器播放,以及获取正在播放的歌曲信息 最近遇到这么一个需求,就是在自己的应用中控制第三方播放器播放,以及获取正在播放的歌曲信息,包括名字,歌手,专辑,显示出来。一开始觉得很简单,但实际上遇到了不少的麻烦,最终实现了两种方案,读者可根据自己需要选择。 阅读详情


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)来决定的

API文档

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 蓝牙——Avrcp协议获取歌曲信息(十七) 以上是对获取歌曲信息的流程进行简单分析,至于APP部分如何获取歌曲信息这里就不做研究,有兴趣的可以参考。 阅读详情

相关推荐

AndroidRemoteControl:Android远程控制客户端

AndroidRemoteControl Android远程控制客户端,服务端采用java web 采用后台Service监听网络数据 交互数据格式:XML

Android音乐控制接口RemoteController使用

Android RemoteController使用 原文链接 RemoteController在API 19 引进,用来给音乐控制提供标准接口。长久以来,音乐播放在Android平台没有一个标准的接口,所有播放器都使用自己的方式实现对音乐的控制,最常见的方式是在Service中进行音乐播放,通过PendingIntent进行播放事件的传递及控制,因此就带来了一个问题。任何一个第三方app无法

zlklove1234的专栏 915

基于Meteoinfo与TrajStat的后向轨迹聚类分析实战:从数据准备到可视化制图

本文详细介绍了基于Meteoinfo与TrajStat进行后向轨迹聚类分析的完整实战流程。从Java环境配置、Meteoinfo软件与TrajStat插件安装,到精准获取NOAA气象数据、设置参数进行批量轨迹计算,再到利用聚类分析提炼主要气流路径,并最终完成专业地图可视化与制图。文章旨在帮助环境与气象研究者快速掌握从数据准备到成果输出的全链路操作。

p4q5r6s7t的博客 804

RemoteControl应用介绍

本文介绍了RemoteControl应用,该应用来自《Android权威编程指南》一书。RemoteControl简介RemoteControl应用只有一个activity。应用界面的最顶端区域可以显示当前频道。下面紧接着的区域显示用户正在输入的新频道。点击Delete按钮可以清除输入区域的频道;点击Enter按钮可变换频道,即更新当前频道并清除输入区域的频道。

vanpersie_9987的博客 6709

NLP DAY1: 文本数据读取

txt 文本数据的读写CSV 及 Excel 文本数据的读写更多的 DataFrame 操作数据规模太大怎么办相信通过本次实验的学习,同学们可以游刃有余地面对各种数据文件了。在接下来的实验中,我们将开始真正地开启自然语言处理之旅,开始认识并熟悉一些常见的针对文本本身的预处理操作。

feifeikon的博客 1060

数十个锂电池充放电电路,锂电池充放电芯片

关乎锂电池供电的产品,在锂电池上,需要三个电路系统:1,锂电池保护电路,2,锂电池充电电路,3,锂电池输出电路。 内容目录: 单节的锂电池保护电路单节为3.7V锂电池(也叫4.2V)和3.8V锂电池(也叫4.35V) 单节的锂电池充电电路即锂电池保护板 单节的锂电池输出电路锂电池转换稳压输出为:1.2V,3.3V,5V,12V等等 两节的锂电池保护电路两节串联7.4V锂电池(也叫8.4V) 两节的锂电池充电电路即两节锂电池保护板 两节...

kuakewei123的博客 1万+

android RemoteControlClient的使用

http://blog.youkuaiyun.com/liu149339750/article/details/31406701: 用于锁屏时的音乐播放

brucexu1978的专栏 4210

Python 爬虫实战:爬取电商平台商品信息(价格 / 销量 / 评价)

摘要:本文详细介绍基于Python的电商商品信息爬取技术方案,以京东商品详情页为例,对比分析静态(BeautifulSoup)和动态(Selenium)两种爬取方式的实现逻辑。静态爬取适合获取基础信息,而动态爬取可解决JS渲染数据的获取问题。文章包含完整的代码实现、反爬规避策略及数据存储方案,涵盖商品名称、价格、销量、评价等核心数据提取。同时强调爬虫的合规使用,提供扩展方向建议,为电商数据采集提供实用技术参考。

2503_91057718的博客 2023

android 控制音乐,Android音乐控制接口RemoteController使用

Android RemoteController使用原文链接RemoteController在API 19 引进,用来给音乐控制提供标准接口。长久以来,音乐播放在Android平台没有一个标准的接口,所有播放器都使用自己的方式实现对音乐的控制,最常见的方式是在Service中进行音乐播放,通过PendingIntent进行播放事件的传递及控制,因此就带来了一个问题。任何一个第三方app无法通过标准...

weixin_31884143的博客 1955

单线激光雷达的工作原理

单线激光雷达通过单一激光束的水平扫描和时间 / 相位测量,实现二维环境的距离感知,是低成本二维导航的核心传感器。尽管其无法直接提供三维信息,但其可靠性和经济性使其在消费级和工业级场景中广泛应用。随着技术发展,部分单线雷达通过振动镜或 MEMS 微振镜实现微小角度偏转,可近似模拟多线扫描效果,进一步拓展了应用边界。

谢谢大家的关注和点赞!这里只有纯纯的知识干货,没有一句废话。希望能实实在在帮到大家~要是觉得有用,别忘了给我点支持哟,你 1859

20、啁啾脉冲光纤放大器:原理、设计与仿真

本文详细介绍了啁啾脉冲光纤放大器(FCPA)的原理、设计与仿真过程。内容涵盖CPA技术的基本原理、光纤基CPA系统的组成、Tm掺杂光纤放大器的工作机制、全光纤脉冲展宽器的设计以及仿真分析。通过MATLAB仿真展示了脉冲在光纤中的展宽与放大过程,并讨论了如何优化系统以减少非线性失真、控制峰值功率并提高整体性能。文章还总结了系统优化的关键策略,并展望了未来的发展方向。

v4w5x6的博客 318

Android-RemoteController 项目常见问题解决方案

Android-RemoteController 项目常见问题解决方案 项目基础介绍 Android-RemoteController 是一个用于远程控制第三方音乐播放器的开源项目。该项目的主要目的是通过模拟耳机按键事件和利用 Android API 19 中提供的 RemoteController 类,来获取第三方音乐播放器的音乐信息并进行控制。项目的主要编程语言是 Java。 新手使用注意事项...

gitblog_00986的博客 727

YOLO26训练自己的数据集,从代码下载到实例测试 (含YOLO26网络结构图)

在Windows10上配置CUDA环境教程2026年1月14日,YOLO26是最新发布的计算机视觉模型。支持多种任务,包括目标检测、实例分割、图像分类、姿态估计、有向目标检测以及物体跟踪等。以上就是YOLO26训练自己数据集的全部过程啦,欢迎大家在评论区交流~

Limiiiing的博客 6509

AcDisplay媒体控制功能详解:锁屏界面下的音乐播放控制实现

AcDisplay作为一款创新的Android通知处理应用,不仅提供了美观的锁屏通知界面,还集成了强大的**媒体控制功能**,让用户可以在锁屏界面直接控制音乐播放。本文将深入解析AcDisplay的媒体控制实现机制,帮助你理解这一功能的工作原理和实现细节。🎵 ## 为什么需要锁屏媒体控制? 在Android设备上,**音乐播放控制**是用户日常使用频率最高的功能之一。传统的锁屏界面通常只显示

gitblog_01021的博客 743

G.6 PaddleHub实战篇{ERNIE实现文新闻本分类、ERNIE3.0 实现序列标注}【四】

百度飞桨:ERNIE 3.0 、通用信息抽取 UIE、paddleNLP的安装使用[一]_汀、的博客-优快云博客PaddleHub--飞桨预训练模型应用工具{风格迁移模型、词法分析情感分析、Fine-tune API微调}【一】_汀、的博客-优快云博客 PaddleHub--{超参优化AutoDL Finetuner}【二】_汀、的博客-优快云博客PaddleHub实战篇{词法分析模型LAC、情感分类ERNIE Tiny}训练、部署【三】_汀、的博客-优快云博客通过前面几篇文章大家都有一定了解,下面

丨汀、的博客 6185

温度PID控制PLC程序

温度PID稳定控制程序,适用于欧姆龙PLC,对其他PLC也具有很大参考价值

探索音乐操控新境界:AndroidRemoteController项目推荐

探索音乐操控新境界:AndroidRemoteController项目推荐 随着智能手机成为我们日常生活中不可或缺的一部分,音乐播放体验也在不断进化。今天,我们要向您推荐一个创新的开源项目——AndroidRemoteController,它将为您的音乐之旅带来前所未有的便捷与乐趣。 项目介绍 AndroidRemoteController是一款专注于远程控制第三方音乐播放器的神器。本项目基于两个...

gitblog_00542的博客 708

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

天语3com.android.phon,万能遥控(com.duokan.phone.remotecontroller) - 6.0.6 - 应用 - 酷安

权限信息· android.permission.REQUEST_INSTALL_PACKAGES· 完全的网络访问权限· 查看网络连接· 查看WLAN连接· 允许接收WLAN多播· 连接WLAN网络和断开连接· 防止手机休眠· 查找设备上的帐户· android.permission.GET_ACCOUNTS_PRIVILEGED· 使用设备上的帐户· 添加或移除帐户· 控制振动· 发射红外线·...

weixin_32120627的博客 962

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

Android锁屏界面控制音乐播放

目前,在锁屏界面控制音乐播放有两种常用方式。 第一种方式:原生Android系统及自带音乐播放器。 锁屏界面端: 原生Android中,锁屏界面相关的UI由KeyguardHostView提供,KeyguardHostView向KeyguardUpdateMonitor注册一个类型为 KeyguardUpdateMonitorCallback的回调, KeyguardUpdateMo...

weixin_34227447的博客 2179

Android 解决不同进程发送KeyEvent 的问题

  最近在做有关于Remote Controller 的功能,该功能把手机做成TV的遥控器来处理。在手机的客户端发送消息到TV的android 服务端,服务端接收到客户端的请求消息,模拟KeyEvent命令,发送Key值。  最简单的发送命令为如下代码:      public static void simulateKeystroke(final int KeyCode) { ...

weixin_34080951的博客 412

Android 跨进程模拟点击,Android 跨进程模拟按键(KeyEvent )实例详解

Android 解决不同进程发送KeyEvent 的问题最近在做有关于Remote Controller 的功能,该功能把手机做成TV的遥控器来处理。在手机的客户端发送消息到TV的android 服务端,服务端接收到客户端的请求消息,模拟KeyEvent命令,发送Key值。最简单的发送命令为如下代码:public static void simulateKeystroke(final int Ke...

weixin_39778150的博客 540

探索Android远程控制器:创新的技术解决方案

探索Android远程控制器:创新的技术解决方案 项目简介 在GitHub上发现了一个独特的项目,是由开发者YoungBill创建的一款Android应用程序,它允许用户将他们的Android设备转变为一个强大的远程控制器,适用于多种应用场景。这个开源项目提供了灵活的自定义选项和直观的交互方式,旨在提升智能设备间的连接与控制体验。 技术分析 1. 蓝牙与WiFi通信 此项目的基石是利用Androi...

gitblog_00015的博客 521
上一篇: 关于ViewTreeObserver的理解
下一篇: 视频播放器的界面设计并实现播放器
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值