Android MediaPlayer播放 听筒外放切换,通过注册监听,来判断是否靠近听筒。
结合mediaplayer坐音频播放,Android hardware搞一个根据光感听筒外放切换。 MediaManager是播放器构建模式,维护了一个MediaPlayer,用来重新处理播放器。
MediaManager.builder()
.setContext(MainActivity.this)
.setDebugModel(true)
.setMediaListener(new MediaCallBack() {
@Override
public void progress(int i, int max) {
}
@Override
public void prepare(int duration, String time) {
}
@Override
public void start() {
}
@Override
public void end() {
}
@Override
public void stop() {
}
})
.setUrl("https://96.f.1ting.com/local_to_cube_202004121813/96kmp3/2020/09/21/21e_wc/01.mp3")
.build();
开始播放
MediaManager.start();
停止
MediaManager.stop();
是否正在播放
MediaManager.isPlaying();
暂停
MediaManager.pause();
继续
MediaManager.resume();
销毁当前的mediaplayer destory时候调用
MediaManager.removeAll();
AudioManager
Android为我们提供的(音量大小控制)的API: AudioManager(音频管理器)了,该类位于Android.Media包下,提供了音量控制与铃声模式相关操作。
获得AudioManager对象实例
AudioManager am = (AudioManager)context.getSystemService(Context.AUDIO_SERVICE);
PowerManager
Android系统为我们提供的电源管理的一个API,其相关接口与设备电池的续航能力有很大的关联, 官方也说了,除非是迫不得已吧,不然的话,应该尽量避免使用这个类,并且使用完以后一定要及时释放。所谓的电源管理包括:CPU运行,键盘或者屏幕亮起来!核心其实就是wakelock锁机制,只要我们拿着这个锁, 那么系统就无法进入休眠状态,可以给用户态程序或内核获取到。锁可以是:”有超时的“或者 “没有超时“,超时的锁到时间后会自动解锁,如果没有了锁或超时,内核会启动休眠机制来进入休眠。
添加权限
<uses-permission android:name="android.permission.WAKE_LOCK"></uses-permission>
获取PowerManager对象实例
powerManager = (PowerManager) getActivity().getSystemService(POWER_SERVICE);
整体的代码如下:
public class AudioSensorBinder implements LifecycleObserver, SensorEventListener {
public final String TAG = this.getClass().getSimpleName();
private final AudioManager audioManager;
private final PowerManager powerManager;
@Nullable
private WeakReference<AppCompatActivity> activity;
private SensorManager sensorManager;
private Sensor sensor;
private PowerManager.WakeLock wakeLock;
@RequiresApi(api = Build.VERSION_CODES.M)
public AudioSensorBinder(@Nullable AppCompatActivity mActivity) {
this.activity = new WeakReference<>(mActivity);
if (getActivity()!=null){
getActivity().getLifecycle().addObserver(this);
}
audioManager = (AudioManager) getActivity().getSystemService(AUDIO_SERVICE);
powerManager = (PowerManager) getActivity().getSystemService(POWER_SERVICE);
registerProximitySensorListener();
}
@OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
public void onResume() {
}
@OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
public void onDestroy() {
sensorManager.unregisterListener(this);
sensorManager = null;
wakeLock = null;
activity = null;
}
@RequiresApi(api = Build.VERSION_CODES.M)
private void registerProximitySensorListener() {
if ( getActivity() == null) {
return;
}
sensorManager = (SensorManager) getActivity().getSystemService(SENSOR_SERVICE);
if (sensorManager == null) {
return;
}
sensor = sensorManager.getDefaultSensor(Sensor.TYPE_PROXIMITY);
sensorManager.registerListener(this, sensor, SensorManager.SENSOR_DELAY_NORMAL);
}
private AppCompatActivity getActivity() {
if (activity != null) {
return activity.get();
}
return null;
}
@Override
public void onSensorChanged(SensorEvent event) {
if (audioManager == null) {
return;
}
if (isHeadphonesPlugged()) {
return;
}
if (true) {
Log.i(TAG, "onSensorChanged: " + MediaManager.isPlaying() + " event.values[0]: " + event.values[0]);
}
if (MediaManager.isPlaying()) {
float distance = event.values[0];
if (distance >= sensor.getMaximumRange()) {
changeToSpeaker();
if (true) {
Log.i(TAG, "onSensorChanged: 外放");
}
} else {
MediaManager.resume();
changeToReceiver();
if (true) {
Log.i(TAG, "onSensorChanged: 听筒");
}
audioManager.setSpeakerphoneOn(false);
}
} else {
changeToSpeaker();
}
}
@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
}
@SuppressLint("WrongConstant")
private boolean isHeadphonesPlugged() {
if (audioManager == null) {
return false;
}
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M) {
AudioDeviceInfo[] audioDevices = audioManager.getDevices(AudioManager.GET_DEVICES_ALL);
for (AudioDeviceInfo deviceInfo : audioDevices) {
if (deviceInfo.getType() == AudioDeviceInfo.TYPE_WIRED_HEADPHONES
|| deviceInfo.getType() == AudioDeviceInfo.TYPE_WIRED_HEADSET) {
return true;
}
}
return false;
} else {
return audioManager.isWiredHeadsetOn();
}
}
public void changeToSpeaker() {
setScreenOn();
if (audioManager == null) {
return;
}
audioManager.setMode(AudioManager.MODE_NORMAL);
audioManager.setSpeakerphoneOn(true);
}
public void changeToHeadset() {
if (audioManager == null) {
return;
}
audioManager.setSpeakerphoneOn(false);
}
public void changeToReceiver() {
setScreenOff();
if (audioManager == null) {
return;
}
audioManager.setSpeakerphoneOn(false);
audioManager.setMode(AudioManager.MODE_IN_COMMUNICATION);
}
private void setScreenOff() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
Log.i(TAG, "setScreenOff: 熄灭屏幕");
if (wakeLock == null) {
wakeLock = powerManager.newWakeLock(PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK, TAG);
}
wakeLock.acquire(10 * 60 * 1000L );
}
}
private void setScreenOn() {
if (wakeLock != null) {
wakeLock.setReferenceCounted(false);
wakeLock.release();
wakeLock = null;
}
}
}
MediaManager
public class MediaManager {
private static MediaManagerBuilder mediaManagerBuilder;
public static MediaManagerBuilder builder() {
mediaManagerBuilder = new MediaManagerBuilder();
return mediaManagerBuilder;
}
public static void start(){
mediaManagerBuilder.start();
}
public static boolean isPlaying(){
if (mediaManagerBuilder!=null){
return mediaManagerBuilder.isPlaying();
}
return false;
}
public static void stop(){
if (mediaManagerBuilder!=null){
mediaManagerBuilder.stop();
}
}
public static void pause(){
if (mediaManagerBuilder!=null){
mediaManagerBuilder.pause();
}
}
public static void resume(){
if (mediaManagerBuilder!=null){
mediaManagerBuilder.resume();
}
}
public static void removeAll(){
if (mediaManagerBuilder!=null){
mediaManagerBuilder.removeAll();
}
}
public static class MediaManagerBuilder{
public final String TAG = this.getClass().getSimpleName();
private Handler handler = new Handler();
private boolean isSeekBarChanging;
private Context context;
private MediaConfig config;
private MediaCallBack mediaListener;
private MediaPlayer mediaPlayer;
private boolean DEBUG = false;
private SimpleDateFormat format;
private Timer timer;
private TimerTask timerTask;
private SeekBar seekBar;
private MediaManagerBuilder() {
this.config = new MediaConfig();
this.mediaPlayer = new MediaPlayer();
this.format = new SimpleDateFormat("mm:ss");
}
public MediaManagerBuilder setContext(Context context){
this.context = context;
return this;
}
public MediaManagerBuilder setUrl(String url){
this.config.url = url;
return this;
}
public MediaManagerBuilder setMediaListener(MediaCallBack mediaListener){
this.mediaListener = mediaListener;
return this;
}
public MediaManagerBuilder setDebugModel(boolean b){
this.DEBUG = b;
return this;
}
public MediaManagerBuilder setProgressSeek(SeekBar seek){
this.seekBar = seek;
return this;
}
public MediaManagerBuilder build(){
Uri uri = Uri.parse(config.url);
if (mediaPlayer!=null){
if (mediaPlayer.isPlaying()){
mediaPlayer.stop();
}
mediaPlayer.release();
}
mediaPlayer = new MediaPlayer();
try {
mediaPlayer.setDataSource(config.url);
mediaPlayer.prepare();
mediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
@Override
public void onPrepared(MediaPlayer mp) {
if (seekBar!=null){
seekBar.setMax(mediaPlayer.getDuration());
}
mediaListener.prepare(mediaPlayer.getDuration(),format.format(mediaPlayer.getDuration()) + "");
}
});
mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
@Override
public void onCompletion(MediaPlayer arg0) {
mediaListener.end();
}
});
} catch (IOException e) {
e.printStackTrace();
}
timerTask = new TimerTask() {
Runnable updateUI = new Runnable() {
@Override
public void run() {
if (mediaPlayer != null && mediaPlayer.getCurrentPosition() != -1) {
mediaListener.progress(mediaPlayer.getCurrentPosition(), mediaPlayer.getDuration());
}
}
};
@Override
public void run() {
if (!isSeekBarChanging) {
if (seekBar!=null){
seekBar.setProgress(mediaPlayer.getCurrentPosition());
}
handler.post(updateUI);
}
}
};
if (seekBar!=null){
seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
isSeekBarChanging = true;
}
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
isSeekBarChanging = false;
mediaPlayer.seekTo(seekBar.getProgress());
}
});
}
return this;
}
private void start(){
mediaPlayer.start();
if (seekBar!=null){
mediaPlayer.seekTo(seekBar.getProgress());
}
if (DEBUG){
Log.i(TAG, "start: media start");
}
timer = new Timer();
timer.schedule(timerTask,0,50);
}
private void stop(){
if (mediaPlayer == null){
return;
}
mediaPlayer.stop();
if (DEBUG){
Log.i(TAG, "start: media stop");
}
}
private void pause(){
if (mediaPlayer == null){
return;
}
mediaPlayer.pause();
if (DEBUG){
Log.i(TAG, "start: media pause");
}
}
private void resume(){
if (mediaPlayer == null){
return;
}
mediaPlayer.start();
if (DEBUG){
Log.i(TAG, "start: media resume");
}
}
private boolean isPlaying(){
if (mediaPlayer!=null){
return mediaPlayer.isPlaying();
}
return false;
}
public void removeAll(){
isSeekBarChanging = true;
if (timer != null) {
timer.cancel();
timer = null;
}
if (mediaPlayer != null) {
mediaPlayer.stop();
mediaPlayer.release();
mediaPlayer = null;
}
}
}
}
Demo gitee
|