我正在开发一个可以记录音频的应用程序,如果api级别高于23,则可以暂停音频,并且用户可以收听暂停的记录。
但是我发现的是,用户无法收听暂停的音频。但是我想要的是用户可以收听暂停的音频
停止记录后,由于它存储在本地路径中,因此可以播放。
我还检查了android文档以及许多关于堆栈溢出的答案,例如如何播放暂停的音频,但是我找不到任何特定的链接。
我在这里分享我的问题。如果您有任何解决方案或找到任何链接来解决我的问题,我们将不胜感激。
即使我需要共享我的代码,也请让我知道。由于我认为没有必要共享代码。因为当用户停止录制时,它应该可以播放。
下面是我的代码
public class AudioRecordingActivity extends BaseActivity
implements AppDialog.IYesListener,
AppDialog.IDiscardRecordingListener, AppDialog.ICancelRecordingListener,
PlayAudioManager.IVoiceCompleteListener,
MediaRecorder.OnInfoListener {
private static final Logger LOGGER = LoggerFactory.createLogger(AudioRecordingActivity.class);
private TaskDetailsViewModel mViewModel;
private ActivityAudioRecordingBinding mBinding;
private AssignmentIdsModel mAssignmentIdModel;
private long mStartTime = 0;
private long mPauseTime=0;
private MediaRecorder mRecorder;
private File mOutputFile;
public final ObservableField<Integer> mAudioState = new ObservableField<>(0);
private String mAudioPath;
private int mMaxAudioTime;
private int[] amplitudes = new int[100];
private int i = 0;
private Handler mHandler = new Handler();
private PlayAudioManager mAudioManager;
private Runnable mTickExecutor = new Runnable() {
@Override
public void run() {
tick();
mHandler.postDelayed(mTickExecutor, 1000);
}
};
@Override
protected void onCreatingBase(Bundle savedInstanceState, Intent intent) {
mViewModel = ViewModelProviders.of(this).get(TaskDetailsViewModel.class);
mBinding = DataBindingUtil.setContentView(this, R.layout.activity_audio_recording);
mAudioManager = new PlayAudioManager();
mAssignmentIdModel = intent.getParcelableExtra(AppConstants.AppExtras.EXTRA_ASSIGNMENT_MODEL);
mMaxAudioTime = Integer.parseInt(intent.getStringExtra(AppConstants.AppExtras.EXTRA_DURATION));
mAudioPath = MediaUtils.getAudioPath(this, mAssignmentIdModel);
mBinding.ivBack.setOnClickListener(this);
mBinding.rlRecording.setOnClickListener(this);
mBinding.ivPlayAudio.setOnClickListener(this);
mBinding.ivAudioDelete.setOnClickListener(this);
mBinding.tvSave.setOnClickListener(this);
setPlayIconClickable(false);
setSaveButtonClickable(false);
setCrossIconClickable(false);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
}
@Override
public void onClick(View view) {
switch (view.getId()) {
case R.id.iv_back:
onBackPressed();
break;
case R.id.rl_recording:
startStopRecording();
break;
case R.id.iv_play_audio:
playStopMediaPlayer();
break;
case R.id.iv_audio_delete:
AppDialog.showDeleteAudioDialog(this, this);
break;
case R.id.tv_save:
saveRecording();
break;
}
}
private void saveRecording() {
mViewModel.saveMediaResponse(mAssignmentIdModel, mAudioPath);
finish();
}
private void playStopMediaPlayer() {
if (mAudioManager.isMediaPlayerPlaying()) {
mBinding.ivPlayAudio.setImageResource(R.drawable.play_after_recording_icon);
setSaveButtonClickable(true);
setCrossIconClickable(true);
setPlayIconClickable(true);
mAudioManager.killMediaPlayer();
mBinding.rlRecording.setClickable(true);
mBinding.rippleBackground.stopRippleAnimation();
} else {
playRecording();
}
}
private void startStopRecording() {
switch (mAudioState.get()) {
case AudioRecordingEnum.AUDIO_IDLE_STATE:
hasAudioPermission();
break;
case AudioRecordingEnum.AUDIO_RECORDING_STATE:
pauseStopRecording();
break;
case AudioRecordingEnum.AUDIO_PAUSE_STATE:
resumeRecording();
break;
case AudioRecordingEnum.AUDIO_STOP_STATE:
AppDialog.showNewRecordingDialog(this, this);
break;
}
}
private void hasAudioPermission() {
if (PermissionUtils.hasPermissions(this, PermissionUtils.RC_REQUEST_PERMISSION_RECORD_AUDIO,
Manifest.permission.RECORD_AUDIO)) {
startRecording();
}
}
private void tick() {
long time = (mStartTime < 0) ? 0 : (SystemClock.elapsedRealtime() - mStartTime);
int minutes = (int) (time / 60000);
int seconds = (int) (time / 1000) % 60;
int milliseconds = (int) (time / 100) % 10;
mBinding.tvTimer.setText((minutes < 10 ? "0" + minutes : "00") + ":" + (seconds < 10 ? "0" + seconds : seconds));
if (mRecorder != null) {
amplitudes[i] = mRecorder.getMaxAmplitude();
LOGGER.debug("Voice Recorder", "amplitude: " + (amplitudes[i] * 100 / 32767));
if (i >= amplitudes.length - 1) {
i = 0;
} else {
++i;
}
}
}
private void deleteRecording() {
AppUtils.deleteFile(mAudioPath);
mAudioState.set(AudioRecordingEnum.AUDIO_IDLE_STATE);
setPlayIconClickable(false);
setCrossIconClickable(false);
setSaveButtonClickable(false);
mStartTime = 0;
mBinding.tvTimer.setText("00:00");
mBinding.tvStartRecording.setText(getResources().getString(R.string.txt_start_recording));
mBinding.rlRecording.setClickable(true);
}
private void playRecording() {
try {
Uri videoUri = FileProvider.getUriForFile(this,
this.getApplicationContext().getPackageName() + ".provider",
mOutputFile);
mAudioManager.playAudio(this, this, videoUri);
mBinding.ivPlayAudio.setImageResource(R.drawable.pauseicon_small);
setSaveButtonClickable(false);
setCrossIconClickable(false);
setPlayIconClickable(true);
mBinding.rlRecording.setClickable(false);
mBinding.rippleBackground.startRippleAnimation();
} catch (Exception e) {
LOGGER.error(e.getMessage());
}
}
@TargetApi(Build.VERSION_CODES.N)
private void pauseRecording() {
if (mRecorder == null) {
return;
}
try {
mRecorder.pause();
mPauseTime=SystemClock.elapsedRealtime();
mAudioState.set(AudioRecordingEnum.AUDIO_PAUSE_STATE);
mBinding.tvStartRecording.setText(getResources().getString(R.string.txt_recording_is_paused));
mHandler.removeCallbacks(mTickExecutor);
whenRecordingIsPausedOrStopped();
} catch (Exception e) {
LOGGER.error(e.getMessage());
}
}
@TargetApi(Build.VERSION_CODES.N)
private void resumeRecording() {
if (mRecorder == null) {
return;
}
try {
mRecorder.resume();
mStartTime = (SystemClock.elapsedRealtime() - mPauseTime) + mStartTime;
mHandler.postDelayed(mTickExecutor, 1000);
mAudioState.set(AudioRecordingEnum.AUDIO_RECORDING_STATE);
mBinding.tvStartRecording.setText(getResources().getString(R.string.txt_recording));
whenRecordingIsInStartState();
} catch (Exception e) {
LOGGER.error(e.getMessage());
}
}
private boolean isBuildVersionIsGreaterOrEqualN() {
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.N) {
return true;
} else {
return false;
}
}
private void pauseStopRecording() {
if (isBuildVersionIsGreaterOrEqualN()) {
pauseRecording();
} else {
stopRecording();
}
}
private void startRecording() {
whenRecordingIsInStartState();
mOutputFile = getOutputFile();
mOutputFile.getParentFile().mkdirs();
mRecorder = new MediaRecorder();
mRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
mRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
mRecorder.setOutputFile(mOutputFile.getAbsolutePath());
mRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
mRecorder.setAudioEncodingBitRate(48000);
mRecorder.setAudioSamplingRate(16000);
mRecorder.setMaxDuration((mMaxAudioTime * 1000));
mRecorder.setOnInfoListener(this);
try {
mRecorder.prepare();
mRecorder.start();
mStartTime = SystemClock.elapsedRealtime();
mHandler.postDelayed(mTickExecutor, 1000);
LOGGER.debug("Voice Recorder", "started recording to " + mOutputFile.getAbsolutePath());
} catch (IOException e) {
LOGGER.error("Voice Recorder", "prepare() failed " + e.getMessage());
}
}
private void whenRecordingIsInStartState() {
mAudioState.set(AudioRecordingEnum.AUDIO_RECORDING_STATE);
setPlayIconClickable(false);
setCrossIconClickable(false);
mBinding.tvStartRecording.setText(getResources().getString(R.string.txt_recording));
mBinding.ivRecord.setImageResource(R.drawable.pauseicon);
setSaveButtonClickable(false);
}
private void setSaveButtonClickable(boolean isClickable) {
if (isClickable) {
mBinding.tvSave.setAlpha(1.0f);
mBinding.tvSave.setClickable(true);
mBinding.tvSave.setTextColor(ContextCompat.getColor(this, R.color.colorAccent));
} else {
mBinding.tvSave.setAlpha(0.5f);
mBinding.tvSave.setClickable(false);
mBinding.tvSave.setTextColor(ContextCompat.getColor(this, R.color.colorMediumText));
}
}
private File getOutputFile() {
return new File(mAudioPath);
}
protected void stopRecording() {
mAudioState.set(AudioRecordingEnum.AUDIO_STOP_STATE);
mBinding.tvStartRecording.setText(getResources().getString(R.string.txt_recording_is_stopped));
whenRecordingIsPausedOrStopped();
mRecorder.stop();
mRecorder.release();
mStartTime = 0;
mPauseTime=0;
mRecorder = null;
mHandler.removeCallbacks(mTickExecutor);
}
private void whenRecordingIsPausedOrStopped() {
setPlayIconClickable(true);
setCrossIconClickable(true);
mBinding.ivRecord.setImageResource(R.drawable.audio_recording);
setSaveButtonClickable(true);
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions,
@NonNull int[] grantResults) {
for (int grantResult : grantResults) {
if (grantResult == PackageManager.PERMISSION_DENIED) {
AppUtils.showShortSnackBar(mBinding.tvSave, R.string.err_permission_denied);
return;
}
}
switch (requestCode) {
case PermissionUtils.RC_REQUEST_PERMISSION_RECORD_AUDIO:
startRecording();
break;
default:
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
}
}
private void setPlayIconClickable(boolean isVisible) {
if (isVisible) {
mBinding.ivPlayAudio.setClickable(true);
mBinding.ivPlayAudio.setAlpha(1.0f);
} else {
mBinding.ivPlayAudio.setAlpha(0.5f);
mBinding.ivPlayAudio.setClickable(false);
}
}
private void setCrossIconClickable(boolean isVisible) {
if (isVisible) {
mBinding.ivAudioDelete.setClickable(true);
mBinding.ivAudioDelete.setAlpha(1.0f);
} else {
mBinding.ivAudioDelete.setAlpha(0.5f);
mBinding.ivAudioDelete.setClickable(false);
}
}
@Override
public void onYesClicked() {
deleteRecording();
}
@Override
public void onVoiceComplete() {
mBinding.ivPlayAudio.setImageResource(R.drawable.play_after_recording_icon);
setCrossIconClickable(true);
setSaveButtonClickable(true);
setPlayIconClickable(true);
mBinding.rlRecording.setClickable(true);
mBinding.rippleBackground.stopRippleAnimation();
}
@Override
public void onBackPressed() {
if (mAudioState.get() == AudioRecordingEnum.AUDIO_RECORDING_STATE) {
mAudioManager.killMediaPlayer();
finish();
} else if (mAudioState.get() == AudioRecordingEnum.AUDIO_STOP_STATE) {
AppDialog.showCancelRecordingDialog(this, this);
} else {
finish();
}
}
@Override
public void onInfo(MediaRecorder mediaRecorder, int i, int i1) {
if (i == MediaRecorder.MEDIA_RECORDER_INFO_MAX_DURATION_REACHED) {
LOGGER.debug("AUDIOCAPTURE", "Maximum Duration Reached");
stopRecording();
}
}
@Override
protected void onPause() {
if (mAudioManager.isPlaying()) {
//PlayAudioManager.killMediaPlayer();
}
super.onPause();
}
@Override
public void onYesDiscardClicked() {
startRecording();
}
@Override
public void onDeleteRecording() {
AppUtils.deleteFile(mAudioPath);
finish();
}
/**
* this method will be called when any interrupt happens or home button is pressed
*/
@Override
protected void onUserLeaveHint() {
if (mRecorder != null && mAudioState.get() == AudioRecordingEnum.AUDIO_RECORDING_STATE) {
stopRecording();
}
if (mAudioManager.isPlaying()) {
//PlayAudioManager.killMediaPlayer();
}
super.onUserLeaveHint();
}
}
下面是音频播放课程
public class PlayAudioManager {
private MediaPlayer mediaPlayer;
private IVoiceCompleteListener iVoiceCompleteListener;
public PlayAudioManager() {
}
public void playAudio(IVoiceCompleteListener listener, final Context context, Uri uri) throws Exception {
if (mediaPlayer == null) {
mediaPlayer = MediaPlayer.create(context, uri);
}
iVoiceCompleteListener = listener;
mediaPlayer.setOnCompletionListener(
mp -> killMediaPlayer());
mediaPlayer.start();
}
public void pauseMediaPlayer() {
if (mediaPlayer != null && mediaPlayer.isPlaying()) {
mediaPlayer.pause();
}
}
public void playMediaPlayer() {
if (mediaPlayer != null) {
mediaPlayer.start();
}
}
public void killMediaPlayer() {
if (mediaPlayer != null) {
try {
mediaPlayer.reset();
mediaPlayer.release();
mediaPlayer = null;
} catch (Exception e) {
e.printStackTrace();
}
}
if (iVoiceCompleteListener != null) {
iVoiceCompleteListener.onVoiceComplete();
}
}
public boolean isPlaying() {
if (mediaPlayer != null && mediaPlayer.isPlaying()) {
killMediaPlayer();
return true;
}
return false;
}
public boolean isMediaPlayerPlaying() {
if (mediaPlayer != null && mediaPlayer.isPlaying()) {
return true;
}
return false;
}
public interface IVoiceCompleteListener {
void onVoiceComplete();
}
}