import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.res.AssetFileDescriptor;
import android.hardware.Sensor;
import android.hardware.SensorManager;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.os.Build;
import android.os.PowerManager;
import com.qihoo.litegame.BaseApplication;
import com.qihoo.utils.ToastUtil;
import java.io.File;
import java.io.FileDescriptor;
import java.io.FileInputStream;
import java.io.IOException;
public class PlayerManager implements SensorEventListener {
public static final int MODE_SPEAKER = 0;
public static final int MODE_HEADSET = 1;
public static final int MODE_EARPIECE = 2;
private static PlayerManager playerManager;
private Context context;
private AudioManager audioManager;
private MediaPlayer mediaPlayer;
private PlayCallback callback;
private PowerManager powerManager;
private PowerManager.WakeLock wakeLock;
private SensorManager sensorManager;
private Sensor sensor;
private HeadsetReceiver headsetReceiver;
private boolean isPause = false;
private String filePath;
private int currentMode = MODE_SPEAKER;
private boolean isScreenOff = false;
public static PlayerManager getManager() {
if (playerManager == null) {
synchronized (PlayerManager.class) {
playerManager = new PlayerManager();
}
}
return playerManager;
}
private PlayerManager() {
context = BaseApplication.applicationContext;
// initMediaPlayer();
// initAudioManager();
}
public String getFilePath() {
return filePath;
}
public boolean isScreenOff() {
return isScreenOff;
}
public void registerSensorListener() {
initSensor();
sensorManager.registerListener(this, sensor, SensorManager.SENSOR_DELAY_NORMAL);
}
public void unregisterSensorListener() {
if (sensorManager != null) {
sensorManager.unregisterListener(this);
}
}
public void registerHeadsetReceiver() {
if (headsetReceiver == null) {
headsetReceiver = new HeadsetReceiver();
}
IntentFilter filter = new IntentFilter();
filter.addAction(Intent.ACTION_HEADSET_PLUG);
filter.addAction(AudioManager.ACTION_AUDIO_BECOMING_NOISY);
context.registerReceiver(headsetReceiver, filter);
}
public void unregisterHeadsetReceiver() {
if (headsetReceiver != null) {
context.unregisterReceiver(headsetReceiver);
}
}
private void initSensor() {
if (sensorManager == null) {
sensorManager = (SensorManager) context.getSystemService(Context.SENSOR_SERVICE);
sensor = sensorManager.getDefaultSensor(Sensor.TYPE_PROXIMITY);
}
}
private void initMediaPlayer() {
if (mediaPlayer == null) {
mediaPlayer = new MediaPlayer();
mediaPlayer.setAudioStreamType(AudioManager.STREAM_VOICE_CALL);
}
}
private void initAudioManager() {
if (audioManager == null) {
audioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
}
if (Build.VERSION.SDK_INT >= 11) {
audioManager.setMode(AudioManager.MODE_IN_COMMUNICATION);
} else {
audioManager.setMode(AudioManager.MODE_IN_CALL);
}
resetPlayMode();
}
public void play(Context context, String path, finalPlayCallback callback) {
FileInputStream is = null;
try {
File file = new File(path);
if (file.exists()) {
is = new FileInputStream(file);
FileDescriptor fd = is.getFD();
play(context, fd, 0, 0x7ffffffffffffffL, callback);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (is != null) {
is.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
public void play(Context context, AssetFileDescriptor afd, final PlayCallback callback) {
try {
play(context, afd.getFileDescriptor(), afd.getStartOffset(), afd.getLength(), callback);
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (afd != null) {
afd.close();
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
public void play(Context context, FileDescriptor fd, longoffset, long length, final PlayCallback callback) {
this.callback = callback;
try {
initMediaPlayer();
initAudioManager();
intcurrentValue = audioManager.getStreamVolume(AudioManager.STREAM_VOICE_CALL);
if (currentValue == 0) {
ToastUtil.show(R.string.voice_value_no);
}
mediaPlayer.reset();
mediaPlayer.setDataSource(fd, offset, length);
mediaPlayer.prepareAsync();
mediaPlayer.setOnPreparedListener(new OnPreparedListener() {
@Override
public void onPrepared(MediaPlayer mp) {
if (callback != null) {
callback.onPrepared();
}
mediaPlayer.start();
if (TextUtil.isEmpty(SharePreferenceUtil.obtainSharePreference(null, BusinessConstant.Voice_First_Tip))) {
SharePreferenceUtil.commitSharePreference(null, BusinessConstant.Voice_First_Tip, "1");
ToastUtil.show(R.string.voice_first_tip);
}
}
});
mediaPlayer.setOnCompletionListener(newMediaPlayer.OnCompletionListener() {
@Override
public void onCompletion (MediaPlayer mp){
resetPlayMode();
mediaPlayer.release();
mediaPlayer = null;
if (callback != null) {
callback.onComplete();
}
}
});
} catch (Exception e) {
e.printStackTrace();
}
}
public boolean isPause() {
return isPause;
}
public void pause() {
if (isPlaying()) {
isPause = true;
mediaPlayer.pause();
}
}
public void resume() {
if (isPause && mediaPlayer != null) {
isPause = false;
mediaPlayer.start();
}
}
public int getCurrentMode() {
return currentMode;
}
public void changeToEarpieceMode() {
if (audioManager != null) {
currentMode = MODE_EARPIECE;
// if (Build.VERSION.SDK_INT >= 11){
//audioManager.setMode(AudioManager.MODE_IN_COMMUNICATION);
// } else {
// audioManager.setMode(AudioManager.MODE_IN_CALL);
// }
audioManager.setSpeakerphoneOn(false);
}
}
public void changeToHeadsetMode() {
if (audioManager != null) {
currentMode = MODE_HEADSET;
// audioManager.setMode(AudioManager.MODE_NORMAL);
audioManager.setSpeakerphoneOn(false);
}
}
public void changeToSpeakerMode() {
if (audioManager != null) {
currentMode = MODE_SPEAKER;
// audioManager.setMode(AudioManager.MODE_NORMAL);
audioManager.setSpeakerphoneOn(true);
}
}
public void resetPlayMode() {
if (audioManager != null) {
if (audioManager.isWiredHeadsetOn()) {
changeToHeadsetMode();
} else {
changeToSpeakerMode();
}
}
}
public void stop() {
if (isPlaying()) {
try {
mediaPlayer.stop();
if (callback != null) {
callback.onStop();
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
public void stopAndDestroy() {
if (isPlaying()) {
mediaPlayer.stop();
mediaPlayer.release();
mediaPlayer = null;
if (callback != null) {
callback.onStop();
}
}
}
public void destroy() {
stopAndDestroy();
if (audioManager != null) {
audioManager.setMode(AudioManager.MODE_NORMAL);
audioManager = null;
}
}
public boolean isPlaying() {
return mediaPlayer != null && mediaPlayer.isPlaying();
}
@Override
public void onSensorChanged(SensorEvent event) {
//耳機模式下直接返回
if (currentMode == MODE_HEADSET) { // || audioManager == null|| audioManager.isWiredHeadsetOn()
return;
}
float value = event.values[0];
if (isPlaying()) {
if (value == sensor.getMaximumRange()) {
resetPlayMode();
setScreenOn();
} else {
changeToEarpieceMode();
setScreenOff();
}
} else {
if (value == sensor.getMaximumRange()) {
resetPlayMode();
setScreenOn();
}
}
}
private void setScreenOff() {
LogUtils.d("setScreenOff===");
isScreenOff = true;
if (wakeLock == null) {
powerManager = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
wakeLock = powerManager.newWakeLock(PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK, "PlayerManager");
}
wakeLock.acquire();
}
private void setScreenOn() {
LogUtils.d("setScreenOn===");
isScreenOff = false;
if (wakeLock != null) {
wakeLock.setReferenceCounted(false);
wakeLock.release();
wakeLock = null;
}
}
@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
}
class HeadsetReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
LogUtils.d("HeadsetReceiver===" + action);
if (Intent.ACTION_HEADSET_PLUG.equals(action)) {
int state = intent.getIntExtra("state", 0);
if (state == 1) {
changeToHeadsetMode();
} else if (state == 0) {
resume();
}
}
elseif(AudioManager.ACTION_AUDIO_BECOMING_NOISY.equals(action)) {
//拔出耳機會觸發此廣播,拔出不會觸發,且此廣播比上一個早,故可在此暫停播放,收到上一個廣播時在恢復播放
pause();
changeToSpeakerMode();
}
}
}
public interface PlayCallback {
void onPrepared();
void onComplete();
void onStop();
}
}
android錄音播放問題
最近要做一個錄音並且播放的功能,開始用的系統自帶的 MediaRecorder,效果一般。
嘗試用AudioRecord,在用系統AEC,BS去迴音去噪,結果發現效果也是差不多。
嘗試用WebRtc,結果發現效果也是差不多。
可能跟4.1之後的系統就已經把WebRtc帶上了,所以最終還是 MediaRecorder,畢竟它最簡單。
播放的時候:
1,需要揚聲器和聽筒切換,就需要監聽距離感應器SensorManager;
2,需要判斷耳機插拔狀態;
需要注意:
1,mediaPlayer.setAudioStreamType(AudioManager.STREAM_VOICE_CALL);
audioManager.setMode(AudioManager.MODE_IN_COMMUNICATION);
始終用這個,因爲不用通話模式,聽筒的時候聲音會很小;
2,需要去註冊耳機插拔的廣播,因爲只是有些機子會插上耳機後會默認耳機播放;
3,最好播放完畢就mediaPlayer.release();mediaPlayer=null;釋放資源;
4,部分機型息屏會調Activity的OnPause,所以可能要用到 isScreenOff()判斷;
5,音量鍵調節,是根據audioManager.setMode()方法控制調哪種音量的。所以Activity的OnPause裏面要釋放到AudioManager.MODE_NORMAL;
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.