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);
整體的代碼如下:
/**
* Created by SHICHENG
* <p>
* Time on 2021/11/08
*/
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 /*10 minutes*/);
}
}
private void setScreenOn() {
if (wakeLock != null) {
wakeLock.setReferenceCounted(false);
wakeLock.release();
wakeLock = null;
}
}
}
MediaManager
/**
* Created by SHICHENG
* <p>
* Time on 2021/11/08
*/
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");
}
/**
* 當前Activity的背景關系
*
* @param context
* @return
*/
public MediaManagerBuilder setContext(Context context){
this.context = context;
return this;
}
/**
* 設定MediaPlayer Url鏈接
*
* @param url
* @return
*/
public MediaManagerBuilder setUrl(String url){
this.config.url = url;
return this;
}
/**
* 設定播放進度監聽回呼
*
* @param mediaListener
* @return
*/
public MediaManagerBuilder setMediaListener(MediaCallBack mediaListener){
this.mediaListener = mediaListener;
return this;
}
/**
* 設定是否是debug
*
* @param b
* @return
*/
public MediaManagerBuilder setDebugModel(boolean b){
this.DEBUG = b;
return this;
}
/**
* 設定進度條
*/
public MediaManagerBuilder setProgressSeek(SeekBar seek){
this.seekBar = seek;
return this;
}
/**
* 初始化MediaPlayer
*/
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進入準備狀態
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
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/353439.html
標籤:其他
