/* * Copyright (c) 2010-2011, The MiCode Open Source Community (www.micode.net) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package net.micode.notes.ui; import android.app.Dialog; import android.content.Context; import android.media.MediaPlayer; import android.os.Bundle; import android.os.Handler; import android.view.View; import android.widget.Button; import android.widget.SeekBar; import android.widget.TextView; import net.micode.notes.R; import net.micode.notes.tool.AudioTool; import java.io.File; import java.io.IOException; /** * 音频播放对话框 */ public class AudioPlayerDialog extends Dialog implements MediaPlayer.OnPreparedListener, MediaPlayer.OnCompletionListener, View.OnClickListener, SeekBar.OnSeekBarChangeListener { private TextView mTitleTextView; private TextView mCurrentPositionTextView; private TextView mDurationTextView; private Button mPlayPauseButton; private SeekBar mSeekBar; private MediaPlayer mMediaPlayer; private Handler mHandler = new Handler(); private Runnable mUpdateProgressTask; private String mAudioFileName; private boolean mIsPlaying = false; private boolean mIsSeeking = false; public AudioPlayerDialog(Context context, String audioFileName) { super(context); this.mAudioFileName = audioFileName; } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.audio_player_dialog); setTitle(R.string.audio_file); // 初始化视图 mTitleTextView = findViewById(R.id.tv_audio_title); mCurrentPositionTextView = findViewById(R.id.tv_current_position); mDurationTextView = findViewById(R.id.tv_duration); mPlayPauseButton = findViewById(R.id.btn_play_pause); mSeekBar = findViewById(R.id.audio_seekbar); // 设置文件名称 mTitleTextView.setText(mAudioFileName); // 设置监听器 mPlayPauseButton.setOnClickListener(this); mSeekBar.setOnSeekBarChangeListener(this); // 创建进度更新任务 mUpdateProgressTask = new Runnable() { @Override public void run() { if (mMediaPlayer != null && mIsPlaying && !mIsSeeking) { int currentPosition = mMediaPlayer.getCurrentPosition(); updateProgress(currentPosition); mHandler.postDelayed(this, 100); } } }; initializeMediaPlayer(); } private void initializeMediaPlayer() { try { File audioFile = new File(AudioTool.getNotesAudioDir(getContext()), mAudioFileName); if (!audioFile.exists()) { dismiss(); return; } mMediaPlayer = new MediaPlayer(); mMediaPlayer.setDataSource(audioFile.getAbsolutePath()); mMediaPlayer.setOnPreparedListener(this); mMediaPlayer.setOnCompletionListener(this); mMediaPlayer.prepare(); } catch (IOException e) { e.printStackTrace(); dismiss(); } } @Override public void onPrepared(MediaPlayer mp) { // 获取音频时长 int duration = mp.getDuration(); mSeekBar.setMax(duration); mDurationTextView.setText(formatTime(duration)); mPlayPauseButton.setEnabled(true); } @Override public void onCompletion(MediaPlayer mp) { // 播放完成,更新UI mIsPlaying = false; mPlayPauseButton.setText(R.string.audio_play); mHandler.removeCallbacks(mUpdateProgressTask); // 重置进度 mSeekBar.setProgress(0); mCurrentPositionTextView.setText(formatTime(0)); } @Override public void onClick(View v) { if (v.getId() == R.id.btn_play_pause) { if (mIsPlaying) { pausePlayback(); } else { startPlayback(); } } } private void startPlayback() { if (mMediaPlayer != null) { mMediaPlayer.start(); mIsPlaying = true; mPlayPauseButton.setText(R.string.audio_pause); mHandler.post(mUpdateProgressTask); } } private void pausePlayback() { if (mMediaPlayer != null && mMediaPlayer.isPlaying()) { mMediaPlayer.pause(); mIsPlaying = false; mPlayPauseButton.setText(R.string.audio_play); mHandler.removeCallbacks(mUpdateProgressTask); } } private void updateProgress(int currentPosition) { mSeekBar.setProgress(currentPosition); mCurrentPositionTextView.setText(formatTime(currentPosition)); } private String formatTime(int timeMs) { int seconds = timeMs / 1000; int minutes = seconds / 60; seconds = seconds % 60; return String.format("%02d:%02d", minutes, seconds); } @Override public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { if (fromUser && mMediaPlayer != null) { mCurrentPositionTextView.setText(formatTime(progress)); } } @Override public void onStartTrackingTouch(SeekBar seekBar) { mIsSeeking = true; } @Override public void onStopTrackingTouch(SeekBar seekBar) { if (mMediaPlayer != null) { mMediaPlayer.seekTo(seekBar.getProgress()); } mIsSeeking = false; if (mIsPlaying) { mHandler.post(mUpdateProgressTask); } } @Override public void onDetachedFromWindow() { super.onDetachedFromWindow(); // 释放资源 releaseMediaPlayer(); mHandler.removeCallbacks(mUpdateProgressTask); } private void releaseMediaPlayer() { if (mMediaPlayer != null) { if (mMediaPlayer.isPlaying()) { mMediaPlayer.stop(); } mMediaPlayer.release(); mMediaPlayer = null; } } }