Android 仿微信根据距离传感器改变播放语音模式

首先,当然是初始化出AudioManager和传感器管理SensorManager:

mAudioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
mSensorManager = (SensorManager) context.getSystemService(Context.SENSOR_SERVICE);

我会创建出一个单例类来管理,并将这两个对象作为全局变量。

接下来我要获取到距离传感器对象,并为他设置监听:

mSensor = mManager.getDefaultSensor(Sensor.TYPE_PROXIMITY);//TYPE_PROXIMITY是距离传感器类型,当然你还可以换成其他的,比如光线传感器
mEventListener = new SensorEventListener() {
            @Override
            public void onSensorChanged(SensorEvent event) {
                mProximiny = event.values[0];

                if (mProximiny == mSensor.getMaximumRange()) {
                    setModeNormal();//稍后会展示这个方法
                } else {
                    setInCallBySdk();//稍后会展示这个方法
                }

            }

            @Override
            public void onAccuracyChanged(Sensor sensor, int accuracy) {

            }
        };
mSensorManager.registerListener(mEventListener, mSensor, SensorManager.SENSOR_DELAY_NORMAL);

接下来要说的是如何切换播放模式了。也就是setModeNormal(扬声器播放模式)和setInCallBySdk(听筒播放模式):

private void setInCallBySdk() {
        if (mAudioManager == null) {
            return;
        }
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            if (mAudioManager.getMode() != AudioManager.MODE_IN_COMMUNICATION) {
                mAudioManager.setMode(AudioManager.MODE_IN_COMMUNICATION);
            }
            try {
                Class clazz = Class.forName("android.media.AudioSystem");
                Method m = clazz.getMethod("setForceUse", new Class[]{int.class, int.class});
                m.invoke(null, 1, 1);
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            } catch (NoSuchMethodException e) {
                e.printStackTrace();
            } catch (InvocationTargetException e) {
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }
        } else {
            if (mAudioManager.getMode() != AudioManager.MODE_IN_CALL) {
                mAudioManager.setMode(AudioManager.MODE_IN_CALL);
            }
        }
        if (mAudioManager.isSpeakerphoneOn()) {
            mAudioManager.setSpeakerphoneOn(false);
            mAudioManager.setStreamVolume(AudioManager.STREAM_VOICE_CALL, mAudioManager.getStreamMaxVolume(AudioManager.STREAM_VOICE_CALL),
                    AudioManager.STREAM_VOICE_CALL);
        }
    }

这个听筒播放模式切换方法区分了sdk版本,5.0及以上的不能使用MODE_IN_CALL直接进行切换,因为这个模式被改为只支持系统级应用。5.0以上的系统我们使用MODE_IN_COMMUNICATION。并调用隐藏类AudioSystem中的setForceUse方法,用AS开发的同学可以进AudioManager中找到这个类,并查看其代码。

private void setModeNormal() {
        if (mAudioManager == null) {
            return;
        }
        mAudioManager.setSpeakerphoneOn(true);
        mAudioManager.setMode(AudioManager.MODE_NORMAL);

        if (!mAudioManager.isSpeakerphoneOn()) {
            mAudioManager.setSpeakerphoneOn(true);

            mAudioManager.setStreamVolume(AudioManager.STREAM_VOICE_CALL,
                    mAudioManager.getStreamMaxVolume(AudioManager.STREAM_VOICE_CALL),
                    AudioManager.STREAM_VOICE_CALL);
        }

    }

这样就可以根据距离传感器来改变播放模式了。当然,在你不使用传感器的时候,记得调用解除监听的方法。

public void unRegistListener() {
        if (mSensorManager != null) {
            mSensorManager.unregisterListener(mEventListener);
        }
    }

最后,你需要在manifest中添加权限:

<uses-permission android:name="android.permission.BODY_SENSORS"/>
    <uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS"/>



你可能感兴趣的:(android,传感器,微信,播放模式切换)