MIUI系统音乐控件标准化方案,第三方APP接入指南

1 功能概述

MIUI提供了强大的系统音乐控件来优化用户体验,系统通过通知栏、桌面小控件、锁屏等方式来展示正在播放的歌曲信息,同时以更为便捷的方式来控制音乐播放器。

第三方音乐播放器可以通过本文所述的接口将正在播放的歌曲信息显示在系统控件上,并接收系统的控制请求(上一首歌、下一首歌,播放、暂停)。

点击下载:MIUI系统音乐控件Demo

2 使用方法说明

2.1 采用Android原生RemoteControlClient

      Android自带了向系统控件设置歌曲名、歌手名、专辑名等信息的功能,在此基础上MIUI添加了设置歌词的功能,在与Android原有功能兼容的基础上进行扩展。

2.2 app如何接收到控件发出的命令

2.2.1注册接收系统控制请求的BoardCastReceiver与RemoteControlClient

注册Receiver与RemoteControlClient
ComponentName myEventReceiver = new ComponentName(getPackageName(), MyRemoteControlEventReceiver.class.getName());
  // MyRemoteControlEventReceiver是一个接收系统控件请求的BoardCastReceiver,需要在manifest中进行注册
       /* <receiver android:name=".receiver.MediaButtonIntentReceiver">
          <intent-filter >
             <action android:name="android.intent.action.MEDIA_BUTTON" />
          </intent-filter>
          </receiver>*/
 AudioManager myAudioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
  // 需要向AudioManager注册
 myAudioManager.registerMediaButtonEventReceiver(myEventReceiver);
 // build the PendingIntent for the remote control client
 Intent mediaButtonIntent = new Intent(Intent.ACTION_MEDIA_BUTTON);
 mediaButtonIntent.setComponent(myEventReceiver);
 PendingIntent mediaPendingIntent = PendingIntent.getBroadcast(getApplicationContext(), 0, mediaButtonIntent, 0);
 // create and register the remote control client
 RemoteControlClient myRemoteControlClient = new RemoteControlClient(mediaPendingIntent);
  // 在AudioManager中注册RemoteControlClient
 myAudioManager.registerRemoteControlClient(myRemoteControlClient);

   摘自官方文档:http://developer.android.com/reference/android/media/RemoteControlClient.html

注意:在退出app时需要及时注销receiver与RemoteControlClient

myAudioManager.unregisterRemoteControlClient(myRemoteControlClient);
myAudioManager.unregisterMediaButtonEventReceiver(myEventReceiver);

2.2.2 声明支持系统控件的操作

//设置所支持的系统操作,下面的例子中支持了上一首,下一首,播放,暂停,播放/暂停, 评分(收藏)
int flags = RemoteControlClient.FLAG_KEY_MEDIA_PREVIOUS
             | RemoteControlClient.FLAG_KEY_MEDIA_NEXT
             | RemoteControlClient.FLAG_KEY_MEDIA_PLAY
             | RemoteControlClient.FLAG_KEY_MEDIA_PAUSE
             | RemoteControlClient.FLAG_KEY_MEDIA_PLAY_PAUSE
             | RemoteControlClient.FLAG_KEY_MEDIA_RATING;
mRemoteControlClient.setTransportControlFlags(flags);

2.2.3 注册listener监听系统发出的进度更新请求

mRemoteControlClient.setOnGetPlaybackPositionListener(new OnGetPlaybackPositionListener() {
    @Override
    public long onGetPlaybackPosition() {
        return 返回你的播放进度;
    }
});

2.2.4 注册listener监听系统发出的用户评分信息

mRemoteControlClient.setMetadataUpdateListener(new OnMetadataUpdateListener() {
    @Override
    public void onMetadataUpdate(int key, Object newValue) {
        处理评分信息
    }
});

摘自官方文档:http://developer.android.com/about/versions/android-4.4.html#Ratings

 

2.3 app如何将信息显示到控件

2.3.1 静态歌曲信息

发送的信息常用的有:歌曲名、专辑名、歌手名,播放时常,在播放列表中的歌曲序号,播放列表中的总歌曲数,歌曲封面。

// 要向系统控件发送上述信息,需要创建一个MetadataEditor
  RemoteControlClient.MetadataEditor ed = mRemoteControlClient.editMetadata(true);
 // 创建时传入的布尔值参数,指示本次传入的数据是否附加在之前传入的数据一起传给系统,一般来说,换歌了才需要将其设置为true
 // 向系统传入歌曲信息
 ed.putString(MediaMetadataRetriever.METADATA_KEY_TITLE, 歌曲名);
 ed.putString(MediaMetadataRetriever.METADATA_KEY_ALBUM, 专辑名);
 ed.putString(MediaMetadataRetriever.METADATA_KEY_ARTIST, 歌手名);
 ed.putLong(MediaMetadataRetriever.METADATA_KEY_DURATION, 歌曲时长);
 ed.putLong(MediaMetadataRetriever.METADATA_KEY_CD_TRACK_NUMBER, 歌曲在播放列表中的位置);
 ed.putLong(MediaMetadataRetriever.METADATA_KEY_NUM_TRACKS, 歌曲列表的长度);
 ed.putBitmap(MetadataEditor.BITMAP_KEY_ARTWORK, 歌曲封面);
 ed.putObject(MediaMetadataEditor.RATING_KEY_BY_USER, 评分(参考Rating类,目前只支持RATING_HEART类型));
 ed.apply();
 // MIUI在此基础上提供了发送歌词信息的接口,第三方app需将符合规范的.lrc文件读取成字符串直接传入即可,系统会自己解析歌词
 // MIUI应用使用方法,MediaMetadataRetriever.METADATA_KEY_LYRIC是MIUI自己定义的字段,其值为1000
  ed.putString(MediaMetadataRetriever.METADATA_KEY_LYRIC, 歌词);
 // 第三方app使用方法,1000这个字段是MIUI定义的传输歌词的字段
   try {
      // for MIUI support
       ed.putString(1000, 歌词);
       catch (Exception e) {}

注意:发现这套传输信息的机制有一个bug,在切歌的时候,需要将MetadataEditor中曾经put过值的key(歌曲封面除外),重新put一遍,

          如果没有新值可以传入null,不然上一首歌的信息与新歌的信息会混在一起。

2.3.2 歌曲动态信息

向系统发送播放状态

可以顺带传入播放进度的信息

mRemoteControlClient.setPlaybackState(RemoteControlClient.PLAYSTATE_BUFFERING, position(), 1);//状态为加载中
mRemoteControlClient.setPlaybackState(RemoteControlClient.PLAYSTATE_PLAYING, position(), 1);//状态为播放
mRemoteControlClient.setPlaybackState(RemoteControlClient.PLAYSTATE_PAUSED);//状态为暂停

向系统发送播放进度,让系统能够实时监听到app的播放进度

mRemoteControlClient.setOnGetPlaybackPositionListener(new OnGetPlaybackPositionListener() {
    @Override
    public long onGetPlaybackPosition() {
        return 返回你的播放进度;
    }
});

注册listener监听系统发出的进度更新请求

mRemoteControlClient.setPlaybackPositionUpdateListener(new OnPlaybackPositionUpdateListener() {
    @Override
    public void onPlaybackPositionUpdate(long newPositionMs) {
        //设置app播放器的播放进度;
    }
});

相关资料摘自官方文档:

http://developer.android.com/reference/android/media/RemoteControlClient.html

如果您有疑问可以邮件至 nirui@xiaomi.com