目录
本以为是个很简单的切换,没想到搞了快一天。 络上各种答案,各种坑,浪费了大量的时间。
亲测有效机型(案例有限、仅供参考)
三星系:SM-A9000、SM-S5
魅族系:魅蓝E(yun os)、魅蓝note5
小米系:红米1s、小米note
Vivo系:忘了什么型 了
代码
/** * ================================================ * 作 者:JayGoo * 版 本:1.1.0 * 创建日期:2016/11/24 * 描 述:音频听筒扬声器切换控制器 * ================================================ */
public class AudioModeManger {
private AudioManager audioManager;
private SensorManager sensorManager;
private Sensor mProximiny;
private onSpeakerListener mOnSpeakerListener;
/** * 扬声器状态监听器 * 如果要做成类似微信那种切换后重新播放音频的效果,需要这个监听回调 * isSpeakerOn 扬声器是否打开 */
public interface onSpeakerListener{
void onSpeakerChanged(boolean isSpeakerOn);
}
public void setOnSpeakerListener(onSpeakerListener listener){
if (listener != null){
mOnSpeakerListener = listener;
}
}
public AudioModeManger(){
}
/** * 距离传感器监听者 */
private SensorEventListener mDistanceSensorListener = new SensorEventListener() {
@Override
public void onSensorChanged(SensorEvent event) {
float f_proximiny = event.values[0];
//扬声器模式
//魅蓝E传感器得到的值竟然比最大值都要大at fuck p>
if (f_proximiny >= mProximiny.getMaximumRange()) {
setSpeakerPhoneOn(true);
if (mOnSpeakerListener != null){
mOnSpeakerListener.onSpeakerChanged(true);
}
} else {//听筒模式
setSpeakerPhoneOn(false);
if (mOnSpeakerListener != null){
mOnSpeakerListener.onSpeakerChanged(false);
}
}
}
@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
}
};
/** * 注册距离传感器监听 */
public void register(){
audioManager = (AudioManager) SMApp.getInstance()
.getSystemService(Context.AUDIO_SERVICE);
sensorManager = (SensorManager) SMApp.getInstance()
.getSystemService(Context.SENSOR_SERVICE);
if (sensorManager != null && mDistanceSensorListener != null) {
mProximiny = sensorManager.getDefaultSensor(Sensor.TYPE_PROXIMITY);
sensorManager.registerListener(mDistanceSensorListener, mProximiny,
SensorManager.SENSOR_DELAY_NORMAL);
}
}
/** * 取消注册距离传感器监听 */
public void unregister(){
if (sensorManager != null &&mDistanceSensorListener != null ) {
sensorManager.unregisterListener(mDistanceSensorListener);
}
}
/** * 听筒、扬声器切换 * * 注释: 敬那些年踩过的坑和那些 上各种千奇百怪坑比方案!! * * AudioManager设置声音类型有以下几种类型(调节音量用的是这个): * * STREAM_ALARM 警 * STREAM_MUSIC 音乐回放即媒体音量 * STREAM_NOTIFICATION 窗口顶部状态栏Notification, * STREAM_RING 铃声 * STREAM_SYSTEM 系统 * STREAM_VOICE_CALL 通话 * STREAM_DTMF 双音多频,不是很明白什么东西 * * —————————————— * * AudioManager设置声音模式有以下几个模式(切换听筒和扬声器时setMode用的是这个) * * MODE_NORMAL 正常模式,即在没有铃音与电话的情况 * MODE_RINGTONE 铃响模式 * MODE_IN_CALL 接通电话模式 5.0以下 * MODE_IN_COMMUNICATION 通话模式 5.0及其以上 * *@param on */
private void setSpeakerPhoneOn(boolean on) {
if (on) {
audioManager.setSpeakerphoneOn(true);
audioManager.setMode(AudioManager.MODE_NORMAL);
//设置音量,解决有些机型切换后没声音或者声音突然变大的问题
audioManager.setStreamVolume(AudioManager.STREAM_MUSIC,
audioManager.getStreamVolume(AudioManager.STREAM_MUSIC), AudioManager.FX_KEY_CLICK);
} else {
audioManager.setSpeakerphoneOn(false);
//5.0以上
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP){
audioManager.setMode(AudioManager.MODE_IN_COMMUNICATION);
//设置音量,解决有些机型切换后没声音或者声音突然变大的问题
audioManager.setStreamVolume(AudioManager.STREAM_VOICE_CALL,
audioManager.getStreamMaxVolume(AudioManager.STREAM_VOICE_CALL), AudioManager.FX_KEY_CLICK);
} else {
audioManager.setMode(AudioManager.MODE_IN_CALL);
audioManager.setStreamVolume(AudioManager.STREAM_VOICE_CALL,
audioManager.getStreamMaxVolume(AudioManager.STREAM_VOICE_CALL), AudioManager.FX_KEY_CLICK);
}
}
}
}
用法
第一步:注册监听器
*可以放到Activity的onCreate中或者封装到音频管理器中(建议)*
if (audioModeManger == null) {
audioModeManger = new AudioModeManger();
}
audioModeManger.register();
第二步:释放监听器
*可以放到Activity的onDestory中或者封装到音频管理器中(建议)*
if (audioModeManger != null)
audioModeManger.unregister();
第三步:权限
Demo
Feature
1、插入耳机监听
2、某些机型可能存在切换时卡顿、丢音的情况,建议采取微信的方案,重新播放音频,最佳
相关资源:视美乐购smlg2020-9-25版.apk-互联 文档类资源-CSDN文库
声明:本站部分文章及图片源自用户投稿,如本站任何资料有侵权请您尽早请联系jinwei@zod.com.cn进行处理,非常感谢!