耳机拔掉或者断开,音乐播放暂停,Android源码分析

文章详细解释了当有线或蓝牙耳机断开时,Android系统如何通过ACTION_AUDIO_BECOMING_NOISY广播通知应用暂停音乐播放的过程,涉及AudioService、BroadcastReceiver和MediaPlayer组件的交互。
摘要由CSDN通过智能技术生成

问题场景:有线耳机或者蓝牙耳机断开,此时音乐播放就会自动暂停,接下来分析下代码流程。

基于Android P MTK的代码

该场景注意使用的主要有一个系统广播:

android.media.AUDIO_BECOMING_NOISY

frameworks/base/media/java/android/media/AudioManager.java

    /**
     * Broadcast intent, a hint for applications that audio is about to become
     * 'noisy' due to a change in audio outputs. For example, this intent may
     * be sent when a wired headset is unplugged, or when an A2DP audio
     * sink is disconnected, and the audio system is about to automatically
     * switch audio route to the speaker. Applications that are controlling
     * audio streams may consider pausing, reducing volume or some other action
     * on receipt of this intent so as not to surprise the user with audio
     * from the speaker.
     */
    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
    public static final String ACTION_AUDIO_BECOMING_NOISY = "android.media.AUDIO_BECOMING_NOISY";

发送该广播的位置:

frameworks/base/services/core/java/com/android/server/audio/AudioService.java

    /**
     * Receiver for misc intent broadcasts the Phone app cares about.
     */
    private class AudioServiceBroadcastReceiver extends BroadcastReceiver {
        @Override
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();
                ...

            } else if (action.equals(Intent.ACTION_USER_SWITCHED)) {
                if (mUserSwitchedReceived) {
                    // attempt to stop music playback for background user except on first user
                    
                    // 接收到 ACTION_USER_SWITCHED 广播时,发送 Msg
                    // switch (i.e. first boot)
                    sendMsg(mAudioHandler,
                            MSG_BROADCAST_AUDIO_BECOMING_NOISY,
                            SENDMSG_REPLACE,
                            0,
                            0,
                            null,
                            0);
                }
                mUserSwitchedReceived = true;


        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
                ...

                //使用handler机制发送广播
                case MSG_BROADCAST_AUDIO_BECOMING_NOISY:
                    onSendBecomingNoisyIntent();
                    break;

    //这里发送广播
    private void onSendBecomingNoisyIntent() {
        sendBroadcastToAll(new Intent(AudioManager.ACTION_AUDIO_BECOMING_NOISY));
    }

接收该广播的位置:(已系统Music为例,也可能是自己的应用)

监听此广播的地方就可以暂停音乐的播放。

    packages/apps/Music/src/com/android/music/utils/Playback.java

    private IntentFilter mAudioNoisyIntentFilter =
            new IntentFilter(AudioManager.ACTION_AUDIO_BECOMING_NOISY);

    private BroadcastReceiver mAudioNoisyReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            if (AudioManager.ACTION_AUDIO_BECOMING_NOISY.equals(intent.getAction())) {
                Log.d(TAG, "Headphones disconnected.");
                if (isPlaying()) {
                    Intent i = new Intent(context, MediaPlaybackService.class);
                    i.setAction(MediaPlaybackService.ACTION_CMD);
                    i.putExtra(MediaPlaybackService.CMD_NAME, MediaPlaybackService.CMD_PAUSE);
                    mService.startService(i);  // 这里执行暂停
                }
            }
        }
    };
  • 9
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Android的视频播放流程可以简单分为以下几个步骤: 1.选择视频源:首先需要确定要播放的视频文件的位置,可以是本地文件、网络文件或者通过其他方式获取的视频数据。 2.创建MediaPlayer对象:使用MediaPlayer类,通过其构造方法创建一个MediaPlayer对象。MediaPlayer是Android中用于播放和控制音视频资源的主要类。 3.设置数据源:在MediaPlayer对象上调用setDataSource()方法,将视频源传递给MediaPlayer,告诉它要播放的是哪个视频文件。 4.准备MediaPlayer:使用prepare()或prepareAsync()方法来准备MediaPlayer。prepare()方法是同步的,会阻塞当前线程,等待MediaPlayer准备就绪;而prepareAsync()方法是异步的,不会阻塞线程,会在后台准备MediaPlayer。 5.设置显示界面:如果需要在界面上显示视频,需要先获取一个SurfaceView或TextureView,并将其传递给MediaPlayer的setSurface()方法,用于渲染视频。 6.开始播放:通过MediaPlayer的start()方法开始播放视频。此时,MediaPlayer会从数据源读取视频数据,解码并渲染到SurfaceView或TextureView上进行显示。 7.视频控制:可以通过调用MediaPlayer的其他方法,如pause()、stop()、seekTo()等,来控制视频的暂停、停止和进度跳转等操作。 8.释放资源:在不需要播放视频时,需要及时释放MediaPlayer的资源,可以调用release()方法来释放相关资源。 总的来说,Android的视频播放流程包括选择视频源、创建MediaPlayer对象、设置数据源、准备MediaPlayer、设置显示界面、开始播放、视频控制和释放资源等步骤。根据具体需求,可以根据这个基本流程进行扩展和定制。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值