控制音乐播放软件的音乐播放状态(非广播形式)

TongsengsBlog 2014-07-30

        下面是我对实现过程的总结,看实现方式请直接到博客最后即可。

=====================================过程总结======================================

       上几篇博客简单说明了我制作一个远程控制音乐播放软件的方式,目的其实就是想要实现在锁屏界面自由控制音乐的播放与暂停。但是却遇到了很多阻碍,这个前面几篇已经说过,一些常见问题都写了解答。问题的原因其实都是出在控制广播的版本适配上面。由于不用版本接受MediaButton事件广播的处理机制不同,导致出现了一系列问题。这里我准备介绍一种新的方式来实现该功能。

      这个功能的本质是利用android自带的给耳机按钮留的接口来实现锁屏控制,这一点无法改变。由于耳机在安卓内部也是使用广播的方式进行。所以我们使用了广播来做。其实完全可以绕过这部,直接利用系统内部的对耳机按钮事件的处理方式即可,发广播的事让系统去做。我们只需要传递事件即可。而上篇博客已经说过,android是如何发送MediaButton广播的,即利用dispatchMediaKeyEvent()方法。这里我们就要使用这个方法来让系统实现我们的事件。使用这个方法,我们需要拿到AudioService。AudioService是被AudioManager通过binder机制来使用的。而在AudioManager中是有AudioService的静态变量的。可惜是私有的,我们不能直接使用,这里就通过反射,获取到这个变量。AudioService也是内部函数,所以也要通过反射来调用其方法。有了这些就已经足够了我们实现功能了。实现方式如下:

====================================功能实现====================================

            AudioManager audioManager =

                  (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE);

            Class<? extends AudioManager> AM =  audioManager.getClass();

            Class<IAudioService> IAS = IAudioService.class;

            Field service = null;

            try {

            service = AM.getDeclaredField("sService");         //反射静态变量属性字段

            service.setAccessible(true);                                 //设置访问权限

            Object  service = service.get(null);                       //获取静态变量对象

            Method dispatchMediaKeyEvent = IAS.getDeclaredMethod(

                       "dispatchMediaKeyEvent", KeyEvent.class);        //获取方法

            dispatchMediaKeyEvent .invoke(service ,

                         new KeyEvent(65535L, 200L, KeyEvent.ACTION_DOWN, keyCode,

                         0, 0, 248, 226, 8));

            Thread.sleep(200L);           //模拟按钮按下抬起                                                                                                                                                                           

            dispatchMediaKeyEvent .invoke(service ,

                         new KeyEvent(65535L, 200L, KeyEvent.ACTION_UP, keyCode,

                         0, 0, 248, 0, 8));

          }catch (Exception e) {

            // TODO Auto-generated catch block

            e.printStackTrace();

           }

这种直接利用系统来实现的方式,可以完全不用担心版本适配的问题。

相关推荐