Android 判断是否有声音在播放

在Android中,我们可以通过AudioManager来判断是否有声音在播放。
实例1:
源码地址: PhoneWindowManager.java (frameworks\base\policy\src\com\android\internal\policy\impl)  
源码如下:

  /**
     * @return Whether fm is being played right now.
     */
    boolean isFmActive() {
        final AudioManager am = (AudioManager)mContext.getSystemService(Context.AUDIO_SERVICE);
        if (am == null) {
            Log.w(TAG, "isFmActive: couldn't get AudioManager reference");
            return false;
        }
        return am.isFmActive();
    }

转载于:https://www.cnblogs.com/aikongmeng/p/3697373.html

Android 系统中获取当前播放音频的来源应用或组件是一个相对复杂的问题,涉及到音频焦点管理、通知监听以及系统级权限等多方面的内容。 ### 音频焦点机制 Android 提供了音频焦点(Audio Focus)机制,用于协调多个应用程序对音频资源的使用。当某个应用请求音频焦点时,其他正在播放音频的应用可能会失去焦点并做出相应的处理,例如暂停播放或降低音量。通过 `AudioManager.requestAudioFocus()` 方法可以申请音频焦点,并注册一个 `OnAudioFocusChangeListener` 来监听音频焦点的变化[^1]。 然而,Android 的 `AudioManager` 并没有提供直接的方法来查询当前持有音频焦点的应用名称或组件信息[^3]。这意味着即使通过反射或系统级权限也无法直接获得当前音频焦点的所有者。 ### 通过 Notification 获取音乐信息 一种间接的方式来判断当前是否有音频正在播放,并且识别出播放音频的应用是通过监听状态栏中的 `Notification` 消息。主流的音乐播放器(如天天动听、QQ音乐、酷狗音乐、酷我音乐、百度音乐等)在播放过程中通常会向状态栏发送包含歌曲信息的通知。通过拦截这些通知并进行包名匹配,可以获取到正在播放的音乐信息[^1]。 为了实现这一点,可以创建一个服务,在 Android 手机启动时自动运行,并通过 `AudioManager.requestAudioFocus()` 获取音频焦点,但不执行任何实际操作,仅用于监听音频焦点的变化。同时,修改 `SystemUI` 来拦截主流音乐播放器的通知,从中提取音乐信息。结合步骤 1 中的 `OnAudioFocusChangeListener`,可以在音频焦点被其他音乐播放器抢占后,结合最近收到的通知更准确地确定当前播放的音乐信息[^1]。 ### 实现示例 以下是一个简单的代码示例,展示了如何注册 `OnAudioFocusChangeListener` 来监听音频焦点的变化: ```java import android.media.AudioManager; import android.os.Bundle; import androidx.appcompat.app.AppCompatActivity; public class AudioFocusActivity extends AppCompatActivity { private AudioManager audioManager; private AudioManager.OnAudioFocusChangeListener focusChangeListener; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_audio_focus); audioManager = (AudioManager) getSystemService(AUDIO_SERVICE); focusChangeListener = new AudioManager.OnAudioFocusChangeListener() { @Override public void onAudioFocusChange(int focusChange) { Log.i(TAG, "focusChange=" + focusChange); switch (focusChange) { case AudioManager.AUDIOFOCUS_GAIN: // 恢复播放 break; case AudioManager.AUDIOFOCUS_LOSS: // 停止播放 break; case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT: // 暂停播放 break; case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK: // 降低音量 break; } } }; int result = audioManager.requestAudioFocus(focusChangeListener, AudioManager.STREAM_MUSIC, AudioManager.AUDIOFOCUS_GAIN); if (result == AudioManager.AUDIOFOCUS_REQUEST_GRANTED) { // 音频焦点已获得 } } @Override protected void onDestroy() { super.onDestroy(); audioManager.abandonAudioFocus(focusChangeListener); } } ``` ### 监听通知 要监听其他应用的通知,可以通过继承 `NotificationListenerService` 并重写其方法来实现。以下是一个简单的例子: ```java import android.service.notification.NotificationListenerService; import android.service.notification.StatusBarNotification; import android.util.Log; public class MyNotificationListener extends NotificationListenerService { private static final String TAG = "MyNotificationListener"; @Override public void onNotificationPosted(StatusBarNotification sbn) { Log.d(TAG, "onNotificationPosted: " + sbn.getPackageName()); // 这里可以添加逻辑来处理特定包名的通知 } @Override public void onNotificationRemoved(StatusBarNotification sbn) { Log.d(TAG, "onNotificationRemoved: " + sbn.getPackageName()); // 这里可以添加逻辑来处理特定包名的通知移除 } } ``` ### 总结 尽管 Android 提供了音频焦点机制来管理音频资源的使用,但由于系统限制,无法直接获取当前持有音频焦点的应用名称或组件信息。不过,通过监听状态栏中的通知,可以间接地识别出正在播放音频的应用,并从中提取相关的音乐信息。这种方法虽然不是完美的解决方案,但在实际应用中已经能够满足大部分需求。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值