Android - 查找当前是不是正在播放音频并停止它

Posted

技术标签:

【中文标题】Android - 查找当前是不是正在播放音频并停止它【英文标题】:Android - find whether audio is currently playing and stop itAndroid - 查找当前是否正在播放音频并停止它 【发布时间】:2010-10-28 03:16:53 【问题描述】:

我正在使用 MediaPlayer 实例从 Internet 位置流式传输音频文件。音频播放器处于单独的活动中。用户可以从音频文件列表中选择并来到这个活动来播放音频。

现在用户可能会返回到上一个活动(使用列表)并选择另一个音频文件。在这种情况下,我想停止正在播放的任何其他音频并开始播放选定的新音频。

有没有什么方法可以让我知道音频文件是否正在播放而无需等待 MediaPlayer 对象?

谢谢。

编辑

我确实发现了如何知道音频是否正在播放。 我们可以通过使用 AudioManager 的对象并调用 isAudioPlaying() 来实现。如果正在播放任何音频,这将返回 true。

现在另一个问题,如何停止当前播放的音频?我没有创建用于启动音频的 MediaPlayer 对象的实例(因为用户已经离开了活动一次并返回了活动的新对象,因此返回了 MediaPlayer 的新实例)

【问题讨论】:

【参考方案1】:

您需要在 MediaPlayer 实例上调用 stop()。要在您的应用程序中使用此功能,您需要:

例如在音频播放活动(onDestroy())中调用stop() 创建一个Service 来播放音频,并通过这两个活动与其通信

使用Service 将允许您的代码在活动生命周期之外继续运行,并且是在这种情况下保持MediaPlayer 对象的唯一方法。

或者,您可以创建Application 的自定义子类并将MediaPlayer 存储在那里,但使用Service 被认为是更好的做法。

【讨论】:

谢谢。使用服务、静态变量还是单例类会更好吗?更好的设计方案是什么?【参考方案2】:

我找到了检查音频流(AudioManager.STREAM_RING、AudioManager.STREAM_NOTIFICATION 等)当前是否正忙于使用反射的方法:

/**
 * Unhide android api: check is stream is active now (AudioManager.STREAM_RING, AudioManager.STREAM_NOTIFICATION...),
 * uses reflection
 * @param audiostream
 * @return
 */
public static boolean isStreamActive(int audioStream) 
    Class<?> audioSystemClazz = null;
    Boolean res = false;
    try 
        audioSystemClazz = Class.forName("android.media.AudioSystem");
        if (null != audioSystemClazz) 
            // isStreamActive
            Method method = audioSystemClazz.getDeclaredMethod("isStreamActive", new Class<?>[]  int.class,
                    int.class );
            if (null != method) 
                res = (Boolean) method.invoke(null, audioStream, 0);
            
        
     catch (ClassNotFoundException e) 
        e.printStackTrace();
     catch (NoSuchMethodException e) 
        e.printStackTrace();
     catch (IllegalAccessException e) 
        e.printStackTrace();
     catch (IllegalArgumentException e) 
        e.printStackTrace();
     catch (InvocationTargetException e) 
        e.printStackTrace();
    

    return res;

【讨论】:

【参考方案3】:

这里有一些方便的代码可以让你在音频播放完毕之前休眠:

   AudioManager manager = (AudioManager)this.getSystemService(Context.AUDIO_SERVICE);
   while(manager.isMusicActive())
    
        Log.d("music", "music is active");
        try
        
            Thread.sleep(500);
        
        catch (InterruptedException e)
        
            Log.e("music", "interrupted waiting for music to stop");
        
        Log.d("music", "done playing music");
    

【讨论】:

这无济于事,几乎没人会让它有用【参考方案4】:

@lostintransit “使用服务、静态变量还是单例类会更好吗?更好的设计选项是什么?”

我认为服务就是您想要的。内置媒体播放器和 Pandora 的应用程序都使用服务来确保音乐不与 Activity 生命周期绑定。

如果我理解您为什么要使用单例或静态,我认为它不会完成您想要的。单例/静态将仅在 Linux 的单个进程中强制执行。如果您启动 Activity,然后将其关闭,然后再次启动,它们将在不同的进程中运行。

【讨论】:

【参考方案5】:

试试这个...

if (mp1 != null && mp1.isPlaying()) 
               mp1.stop();
           

其中 mp1 是 MediaPlayer

【讨论】:

如果 mp1 对象在应用关闭时被销毁,这将不起作用。

以上是关于Android - 查找当前是不是正在播放音频并停止它的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 audio_service 在 Android 上显示当前正在播放的音频?

解决在Android设备播放音频与其他应用重音的问题,并监听耳机的控制按钮

Android:如何检测所选音频正在 Android Studio 中播放

HTML5 检查音频是不是正在播放?

ios nstimer 在后台运行以检查警报时间是不是等于当前时间并播放音频

Android在音频播放器中刷新Seekbar进度和播放持续时间导致音频播放滞后