liaoxiang1987 2013-05-06 10:35 采纳率: 50%
浏览 3799
已采纳

android 获取其他应用的背景音乐状态

首先,我自己在做一个关于音乐的插件。
其次,该插件的一个需求是在某一个条件下运行,然后弹出一些操作。而这种条件就是当有应用在跑时,如果有背景音乐在播放(play)状态,我不做某些操作。但如果背景音乐在暂停或停止状态(pause or stop),我这边就会做一些操作。

现在的情况是,我找了很多关于android音乐的处理,在底层服务层没有找到能获取到当前音乐播放状态的方式,只能获取到isActive,但这个状态在播放和暂停时都是返回true的。而上层情况是其他应用都是用mediaplay进行播放控制,而我作为另一个应用是获取不到别人应用的类对象的,所以这个问题陷入迷茫状态,希望做过或了解过这块的大神们能给出点方法,意见或思路哦。谢谢了,小弟快苦恼死了,搞了一个星期了

  • 写回答

2条回答 默认 最新

  • liaoxiang1987 2013-05-09 03:59
    关注

    研究两个星期,终于把这个问题进行了曲线救国,下面我来分享下自己的经验:

    思路:
    首先别人应用使用的播放方法是不同的,有jetPlay,mediaplay,更有牛的人用上了复杂的mediatrack。所以必须得用一个通用的方法进行获取。
    其次,对于别人应用来说,无论用那种方法,我们都是获取不到它的播放实例的,比如我研究的是一个Unity3d游戏,底层核心是用mediaplay进行播放控制的,但我们是获取不到它生成的那个实例的。
    最后,我们就必须将思路放到底层,比如service,framework,甚至是驱动级

    讲一下我自己的研究过程:
    首先使用的是liunx下的hook方法,对一些应用调用的库文件进行hook,如果能够直接获取到它自身的函数,比如play,pause等,或者状态参数返回,那这种方法当然是最好的,准确无误,不存在外界干扰。唯一的就是需要root权限,这个我想很简单吧。但有一个很大的缺点,hook函数的调用时frame级别的,如果不做系统是没办法是用的。
    但我自己进行了研究,发现在unity3d游戏下,hook方法实用性太差,因为它的封装性太好,而且结构与android正常结构不同,所以我就放弃了。
    最后我把思路转向应用级,试试在应用级上能否找到获取状态的函数,但最后不幸的是,除了一个isActive()外,我找不到关于状态的回馈。柳暗花明又一村,就在这里我发现了一个音乐播放器常用的东西----频谱。然后我就试着进行频谱分析来获取状态,而且频谱与播放形式无关,只跟输出数据有关。结果是真让我找到一个歪门邪道。虽然会有延迟还得自己逻辑,但起码是获取到了状态情况。

    简约写下流程

    {
      private Visualizer visualizer = null;//频谱测试器
      private byte [] mRawVizData;//频谱容器
    
    
      //实例化 Visualizer 对象
      visualizer = new Visualizer(0); 
      mRawVizData = new byte[128];
    
      //对象的初始化
      if(visualizer != null)
      {
        if (visualizer.getEnabled()) {
            visualizer.setEnabled(false);
    
         }
    
           visualizer.setCaptureSize(mRawVizData.length);//一定要在频谱false状态使用
           visualizer.setEnabled(true);//开启频谱获取
    
      }
    

    下面是开一个线程进行循环获取频谱信息,我只把获取给贴出来

    int status = Visualizer.ERROR;
    
      if(visualizer != null)
      {
    
        //音乐频谱获取
        status = visualizer.getFft(mRawVizData);//获取波形图
    
        if(status != Visualizer.SUCCESS)
        {
        Log.i("answer", "getWaveFail");
        }
        else
       {                         
        int j = 0;
    
        for(int i = 0; i < 128; i++)
        {
    
            if(mRawVizData[i] == 0)
            {
                j++;
            }
        }
    
            Log.i("answer", "getWave j = " + j);
        }
      }
    }
    

    最后我们可以看到j的数量,如果j的数量跟你当时申请数组128相同,说明此时是没有数据流出的,也就是说当前是在pause或stop状态了,其他数据不一样就是有数据进行输出。
    关于频谱的使用大家可以参照http://blog.csdn.net/caryee89/article/details/6935237 大牛之作。
    本人也就是使用获取一下数据而已,并没多复杂处理,仅供参考。

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥15 代写uni代码,app唤醒
  • ¥15 全志t113i启动qt应用程序提示internal error
  • ¥15 ensp可以看看嘛.
  • ¥80 51单片机C语言代码解决单片机为AT89C52是清翔单片机
  • ¥60 优博讯DT50高通安卓11系统刷完机自动进去fastboot模式
  • ¥15 minist数字识别
  • ¥15 在安装gym库的pygame时遇到问题,不知道如何解决
  • ¥20 uniapp中的webview 使用的是本地的vue页面,在模拟器上显示无法打开
  • ¥15 网上下载的3DMAX模型,不显示贴图怎么办
  • ¥15 关于#stm32#的问题:寻找一块开发版,作为智能化割草机的控制模块和树莓派主板相连,要求:最低可控制 3 个电机(两个驱动电机,1 个割草电机),其次可以与树莓派主板相连电机照片如下: