MediaPlayer是Android设计的媒体播放器,不仅仅可以播放音频文件,还可以播放视频文件
播放:Audio(音频,.mp3)相关
播放:Video(视频,.mp4)相关
以下图,是Android官方提供:MediaPlayer时序图:
只要会看这个图:就能实现音频/视频播放,暂停,继续,停止,重播,等等
看图规律:
1.蓝色椭圆形是状态,例如:Initialized已初始化状态,Prepared准备状态,Started启动状态,Stopped停止状态,End结束状态,等等;
2.单箭头是方法调用:例如:调用reset方法重置,调用prepare方法准备,调用start方法播放,等等;
3.双箭头是监听回调:例如:onError回调错误,等等
此MediaPlayer播放使用普通准备,不使用异步准备
package liudeli.my_media1; import android.database.Cursor; import android.media.MediaPlayer; import android.net.Uri; import android.os.SystemClock; import android.provider.MediaStore; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.util.Log; import android.view.View; import android.widget.Button; import android.widget.TextView; import android.widget.Toast; /** * 此MediaPlayer播放使用普通准备,不使用异步准备 */ public class MediaPlayAudioActivity extends AppCompatActivity { private TextView tvPlayerPath; // 显示播放的路径 private TextView tvAudioInfo; // 歌曲时长/歌手/专辑 private TextView tvAudioThisDuration; // 当前播放的时长 /** * 媒体播放器,可以播放(音频/视频) * 播放(音频/视频)操作一模一样 */ private MediaPlayer mediaPlayer; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_play_audio); tvPlayerPath = findViewById(R.id.tv_player_path); tvAudioInfo = findViewById(R.id.tv_audio_info); tvAudioThisDuration = findViewById(R.id.tv_audio_this_duration); mediaPlayer = new MediaPlayer(); // 为了测试,这样写,真实开发中,不这样写 new Thread(){ @Override public void run() { super.run(); while (true) { runOnUiThread(new Runnable() { @Override public void run() { if (mediaPlayer.isPlaying()) { tvAudioThisDuration.setText("当前时长:" + postions(mediaPlayer.getCurrentPosition())); } } }); SystemClock.sleep(1000); } } }.start(); /** * 监听播放完成 */ mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() { @Override public void onCompletion(MediaPlayer mp) { Log.d("mp", "播放完成"); Toast.makeText(MediaPlayAudioActivity.this, "播放完成", Toast.LENGTH_SHORT).show(); tvAudioThisDuration.setText("当前时长:-"); } }); /** * 去获取第一条外置存储的音频文件.mp3 的路径 * 通过Uri uri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI; 获取外置存储音频文件 * getContentResolver.query(uri) */ initAudioPlayerPath(); } /** * 去获取第一条外置存储的音频文件.mp3 的路径 */ private void initAudioPlayerPath() { Uri uri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI; // 查询的列 String[] projection = new String[]{MediaStore.Audio.Media.DATA, // 音频路径 MediaStore.Audio.Media.DURATION, // 音频时长 MediaStore.Audio.Media.ARTIST, // 歌手 MediaStore.Audio.Media.ALBUM // 专辑 }; // 让Android系统也会去读取外置存储 Cursor cursor = getContentResolver().query(uri, projection, null, null, null, null); if (cursor.moveToFirst()) { tvPlayerPath.setText(cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.DATA))); String duration = cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.DURATION)); String artist = cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.ARTIST)); String album = cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.ALBUM)); tvAudioInfo.setText("歌曲时长:" + postions(Integer.parseInt(duration)) + " \n歌手:" + artist + " \n专辑:" + album); } } /** * 转换时长值 */ private String postions(int postion) { int musicTime = postion / 1000; return musicTime / 60 + ":" + musicTime % 60; } /** * 开始播放:此次播放使用普通准备,不使用异步准备 * @param view */ public void player(View view) { try { // 重置 mediaPlayer.reset(); // 设置音频文件路径 mediaPlayer.setDataSource(tvPlayerPath.getText().toString().trim()); // 准备:是操作硬件在播放,所以需要准备 mediaPlayer.prepare(); // 开始 mediaPlayer.start(); } catch (Exception e) { e.printStackTrace(); } } /** * 暂停播放 继续播放 * @param view */ public void pause(View view) { /** * 这种方式可以拿到控件 */ Button pause_continue = (Button) view; if (mediaPlayer.isPlaying()) { pause_continue.setText("继续"); // 暂停 mediaPlayer.pause(); } else { pause_continue.setText("暂停"); // 继续播放 mediaPlayer.start(); } } /** * 停止播放 */ public void stop(View view) { // 停止播放 mediaPlayer.stop(); } /** * 重播 * @param view */ public void recorded(View view) { try { /** * 一定要seekTo * 因为由于没有执行reset,mediaPlayer不会从0开始播放,所以要设置 */ mediaPlayer.seekTo(0); // 准备:是操作硬件在播放,所以需要准备 mediaPlayer.prepare(); // 播放 mediaPlayer.start(); } catch (Exception e) { e.printStackTrace(); } } /** * 此Activity销毁后,一定要 * mediaPlayer.release(); * mediaPlayer = null; * 因为 MediaPlayer 是操作硬件在播放,所以一定要释放资源 */ @Override protected void onDestroy() { super.onDestroy(); mediaPlayer.release(); mediaPlayer = null; System.gc(); } }
AndroidManifest.xml 配置 外部存储读取权限:
Android系统也会去读取外置存储,需要读取外部存储的权限
<!-- getContentResolver().query(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, ...) Android系统也会去读取外置存储,需要读取外部存储的权限 --> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
布局文件:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MediaPlayAudioActivity" android:orientation="vertical"> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:padding="10dp"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="播放音频.mp3路径:" /> <TextView android:id="@+id/tv_player_path" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="/mnt/sdcard/" /> </LinearLayout> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal"> <Button android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:text="播放" android:onClick="player" /> <Button android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:text="暂停" android:onClick="pause" /> <Button android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:text="停止" android:onClick="stop" /> <Button android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:text="重播" android:onClick="recorded" /> </LinearLayout> <TextView android:id="@+id/tv_audio_info" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_margin="10dp" android:text="test" /> <TextView android:id="@+id/tv_audio_this_duration" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_margin="10dp" android:text="歌曲时长:-" /> </LinearLayout>
播放效果: