研究两个星期,终于把这个问题进行了曲线救国,下面我来分享下自己的经验:
思路:
首先别人应用使用的播放方法是不同的,有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 大牛之作。
本人也就是使用获取一下数据而已,并没多复杂处理,仅供参考。