Android 监听系统媒体音量变化


在做 SAPA 适配时由于其直连驱动层不经过 Android 的音量增益控制,所以调节系统媒体音量对音量改变无效。现要调节系统音量时也可以控制播放的音量,那么就需要监听系统音量变化,然后转换成增益给输出数据乘以对应比率从而实现对音量的控制。

一般监听音量多是监听手机物理音量按键的点击事件,但是在音量控制面板拖动音量条改变音量就无法监听。那么我们需要分析无论是按音量键还是拖动音量条,系统都做了什么呢?有什么共性?

参考:Android系统音量变化后会干什么?

从文中可以知道,当音量变化时,系统会发出广播,所以我们只要监听音量改变的广播就可以了,不用关心具体是哪种方式改变的音量。该广播的 action 为AudioManager.VOLUME_CHANGED_ACTION ,但是该常量被隐藏了,所以直接用 "android.media.VOLUME_CHANGED_ACTION" ,在收到广播时可以通过 AudioManager的getStreamVolume(AudioManager.STREAM_MUSIC) 方法获得当前的音量,也可以从广播中携带的数据获取,我对此做了个封装。

封装如下

package com.ushow.sapademo;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.media.AudioManager;
import java.lang.ref.WeakReference;

/**
 * Author: Alan Wang.
 * Date: 18/5/29 16:39.
 * Mail: alanwang6584@gmail.com
 */

public class VolumeChangeObserver {

    private static final String VOLUME_CHANGED_ACTION = "android.media.VOLUME_CHANGED_ACTION";
    private static final String EXTRA_VOLUME_STREAM_TYPE = "android.media.EXTRA_VOLUME_STREAM_TYPE";

    public interface VolumeChangeListener {
        /**
         * 系统媒体音量变化
         * @param volume
         */
        void onVolumeChanged(int volume);
    }

    private VolumeChangeListener mVolumeChangeListener;
    private VolumeBroadcastReceiver mVolumeBroadcastReceiver;
    private Context mContext;
    private AudioManager mAudioManager;
    private boolean mRegistered = false;

    public VolumeChangeObserver(Context context) {
        mContext = context;
        mAudioManager = (AudioManager) context.getApplicationContext()
                .getSystemService(Context.AUDIO_SERVICE);
    }

    /**
     * 获取当前媒体音量
     * @return
     */
    public int getCurrentMusicVolume() {
        return mAudioManager != null ? mAudioManager.getStreamVolume(AudioManager.STREAM_MUSIC) : -1;
    }

    /**
     * 获取系统最大媒体音量
     * @return
     */
    public int getMaxMusicVolume() {
        return mAudioManager != null ? mAudioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC) : 15;
    }

    public VolumeChangeListener getVolumeChangeListener() {
        return mVolumeChangeListener;
    }

    public void setVolumeChangeListener(VolumeChangeListener volumeChangeListener) {
        this.mVolumeChangeListener = volumeChangeListener;
    }

    /**
     * 注册音量广播接收器
     * @return
     */
    public void registerReceiver() {
        mVolumeBroadcastReceiver = new VolumeBroadcastReceiver(this);
        IntentFilter filter = new IntentFilter();
        filter.addAction(VOLUME_CHANGED_ACTION);
        mContext.registerReceiver(mVolumeBroadcastReceiver, filter);
        mRegistered = true;
    }

    /**
     * 解注册音量广播监听器,需要与 registerReceiver 成对使用
     */
    public void unregisterReceiver() {
        if (mRegistered) {
            try {
                mContext.unregisterReceiver(mVolumeBroadcastReceiver);
                mVolumeChangeListener = null;
                mRegistered = false;
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    private static class VolumeBroadcastReceiver extends BroadcastReceiver {
        private WeakReference<VolumeChangeObserver> mObserverWeakReference;

        public VolumeBroadcastReceiver(VolumeChangeObserver volumeChangeObserver) {
            mObserverWeakReference = new WeakReference<>(volumeChangeObserver);
        }

        @Override
        public void onReceive(Context context, Intent intent) {
            //媒体音量改变才通知
            if (VOLUME_CHANGED_ACTION.equals(intent.getAction())
                    && (intent.getIntExtra(EXTRA_VOLUME_STREAM_TYPE, -1) == AudioManager.STREAM_MUSIC)) {
                VolumeChangeObserver observer = mObserverWeakReference.get();
                if (observer != null) {
                    VolumeChangeListener listener = observer.getVolumeChangeListener();
                    if (listener != null) {
                        int volume = observer.getCurrentMusicVolume();
                        if (volume >= 0) {
                            listener.onVolumeChanged(volume);
                        }
                    }
                }
            }
        }
    }
}

对外暴露有以下几个方法:

  • VolumeChangeObserver(Context context):构造函数;

  • VolumeChangeListener:音量改变接口,当媒体音量变化时会调用其 onVolumeChanged(int volume) 方法;

  • setVolumeChangeListener(VolumeChangeListener volumeChangeListener):设置音量改变的监听器;

  • getCurrentMusicVolume():获取当前媒体音量;

  • registerReceiver():注册接收器;

  • unregisterReceiver():解注册接收器

调用逻辑如下

package com.ushow.sapademo;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;

//实现 VolumeChangeListener 接口
public class MainActivity extends AppCompatActivity implements VolumeChangeObserver.VolumeChangeListener {
    private final static String TAG = MainActivity.class.getSimpleName();

    private VolumeChangeObserver mVolumeChangeObserver;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        //实例化对象并设置监听器
        mVolumeChangeObserver = new VolumeChangeObserver(this);
        mVolumeChangeObserver.setVolumeChangeListener(this);
        int initVolume = mVolumeChangeObserver.getCurrentMusicVolume();
        Log.e(TAG, "initVolume = " + initVolume);
    }

    @Override
    protected void onResume() {
        //注册广播接收器
        mVolumeChangeObserver.registerReceiver();
        super.onResume();
    }

    @Override
    protected void onPause() {
        //解注册广播接收器
        mVolumeChangeObserver.unregisterReceiver();
        super.onPause();
    }

    @Override
    public void onVolumeChanged(int volume) {
        //系统媒体音量改变时的回调
        Log.e(TAG, "onVolumeChanged()--->volume = " + volume);
    }
}

未来发展进行了展望。 关键词:大学物理学,量子力学,相对论,统计物理 1.引言 大学物理学是物理学的基础学科,对于培养学要修改 ElementUI 组件库中 Radio 组件的样式,可以通过覆盖默认样式来实现。以下是一些示生的物理思维和物理素养具有重要意义。大学物理学的研究方向和例代码: 1. 修改 Radio 按钮的颜色: ```css .el-radio__input.is-checked+.el-radio__label { 热点涉及到物理学的各个领域,如量子力学、相对论、统计物理等 color: red; } ``` 2. 修改 Radio 按钮的尺寸: ```css .el-radio__input.is-checked+.el-radio方面。 2.量子力学在大学物理学中的研究 量子力学是研究微观__label { font-size: 18px; } ``` 3. 修改 Radio 按钮的边框样式: ```css 粒子行为的物理学分支,是大学物理学中的重要研究方向。量子力.el-radio__input.is-checked+.el-radio__label { border: 2px solid blue; } ``` 4. 修改 Radio 按学的研究内容包括量子力学基础理论、量子力学中的信息处理、量子力学钮的背景色: ```css .el-radio__input.is-checked+.el-radio__label { background-color: yellow; } ``中的量子态等方面。近年来,量子计算机的研究成为了量子力学研` 这些样式可以通过将它们添加到全局样式表中,或者在组件中使用 scoped 样式究的一个重要领域,该领域的研究成果将对未来的计算机技术和信息处理表来覆盖默认样式。
评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值