我的Android进阶之旅------Android MediaPlayer播放mp3的实例--简易mp3播放器
大家好我們今天研究的是Android中很重要也最為復雜的媒體播放器---MediaPlayer.
Android的MediaPlayer包含了Audio和video的播放功能,在Android的界面上,Music和Video兩個應用程序都是調(diào)用MediaPlayer實現(xiàn)的。
首先來看看MediaPlayer的生命周期:
從MediaPlayer的生命周期圖或者說是狀態(tài)轉(zhuǎn)移圖上來看:
- 一個新建的MediaPlayer對象在調(diào)用getCurrentPosition(), getDuration(), getVideoHeight(), getVideoWidth(), setAudioStreamType(int), setLooping(boolean), setVolume(float,float), pause(), start(), stop(), seekTo(int), prepare(), prepareAsync()方法時,不會觸發(fā)OnErrorListener.onError()事件,但是MediaPlayer對象如果調(diào)用了reset()方法后,再使用這些方法則會觸發(fā)OnErrorListener.onError()事件。
- 當MediaPlayer對象不再被使用時,最好通過release()方法來釋放,使其處于結(jié)束狀態(tài),以免造成不必要的錯誤。當MediaPlayer處于結(jié)束狀態(tài)是,便不能再使用。
- MediaPlayer對象被新建時處于空閑狀態(tài),如果通過creat()方法創(chuàng)建之后便處于準備狀態(tài)。
下邊是MediaPlayer提供的常用方法:
| 方法 | 說明 |
| MediaPlayer | 構(gòu)造方法 |
| create | 創(chuàng)建一個要播放的多媒體 |
| getCurrentPosition | 得到當前播放位置 |
| getDuration | 得到文件的時間 |
| getVideoHeight | 得到視頻的高度 |
| getVideoWidth | 得到視頻的寬度 |
| isLooping | 是否循環(huán)播放 |
| isPlaying | 是否正在播放 |
| pause | 暫停 |
| prepare | 準備(同步) |
| prepareAsync | 準備(異步) |
| release | 釋放MediaPlayer對象 |
| reset | 重置MediaPlayer對象 |
| seekTo | 指定播放的位置(以毫秒為單位的時間) |
| setAudioStreamType | 設(shè)置流媒體的類型 |
| setDataSource | 設(shè)置多媒體數(shù)據(jù)來源 |
| setDisplay | 設(shè)置用SurfaceHolder來顯示多媒體 |
| setLooping | 設(shè)置是否循環(huán)播放 |
| setOnButteringUpdateListener | 網(wǎng)絡流媒體的緩沖監(jiān)聽 |
| setOnErrorListener | 設(shè)置錯誤信息監(jiān)聽 |
| setOnVideoSizeChangedListener | 視頻尺寸監(jiān)聽 |
| setScreenOnWhilePlaying | 設(shè)置是否使用SurfaceHolder來保持屏幕顯示 |
| setVolume | 設(shè)置音量 |
| start | 開始播放 |
| stop | 停止播放 |
至此,可以得出Android中通過MediaPlayer來播放音樂的步驟:
MediaPlayer mp = new MediaPlayer();//構(gòu)建MediaPlayer對象mp.setDataSource("/sdcard/test.mp3");//設(shè)置文件路徑mp.prepare();//準備mp.start();//開始播放
? MediaPlayer在底層是基于OpenCore(PacketVideo)的庫實現(xiàn)的,為了構(gòu)建一個MediaPlayer程序,上層還包含了進程間通訊等內(nèi)容,這種進程間通訊的基礎(chǔ)是Android基本庫中的Binder機制。
而我們今天的例子只是利用MediaPlayer來播放res/raw文件夾中一首非常動聽的英文哥Avril Lavigne - Complicated.mp3.程序有4個ImageButton按鈕,播放,停止,重播和暫停!4個按鈕的功能我就不用多說.下面我將Step By Step教你如何完成本Demo的實現(xiàn).本實例可以實現(xiàn)音樂播放器除了來電的時候會暫停播放,通話結(jié)束后恢復播放外,打開其他的Activity都可以繼續(xù)播放音樂,享受一邊聽音樂一邊做其他的事情。
Step 1 :新建一個Android工程,命名為AudioPlayer
Step 2 :準備素材,將Avril Lavigne - Complicated.mp3導入到SDCard中
Step 3: 設(shè)計UI布局,在main.xml里放入4個ImageButton,代碼如下:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:orientation="vertical" android:layout_width="fill_parent"android:layout_height="fill_parent"><TextView android:layout_width="wrap_content"android:layout_height="40dp" android:text="@string/file_name"android:id="@+id/textView" /><EditText android:layout_width="fill_parent"android:layout_height="wrap_content" android:id="@+id/file_name" android:text="Avril Lavigne - Complicated.mp3"/><LinearLayout android:orientation="horizontal"android:layout_width="fill_parent" android:layout_height="wrap_content"><Button android:layout_width="wrap_content"android:layout_height="wrap_content" android:text="@string/button_play"android:onClick="mediaPlay" android:id="@+id/button_play" /><Button android:layout_width="wrap_content"android:layout_height="wrap_content" android:text="@string/button_pause"android:onClick="mediaPlay" android:id="@+id/button_pause" /><Button android:layout_width="wrap_content"android:layout_height="wrap_content" android:text="@string/button_replay"android:onClick="mediaPlay" android:id="@+id/button_replay" /><Button android:layout_width="wrap_content"android:layout_height="wrap_content" android:text="@string/button_stop"android:onClick="mediaPlay" android:id="@+id/button_stop" /></LinearLayout> </LinearLayout>
string.xml
<?xml version="1.0" encoding="utf-8"?> <resources><string name="hello">Hello World, MainActivity!</string><string name="app_name">音樂播放器</string><string name="file_name">請輸入音樂文件名</string><string name="file_noexist">音樂文件不存在</string><string name="button_play">播放</string><string name="button_pause">暫停</string><string name="button_continue">繼續(xù)</string><string name="button_replay">重播</string><string name="button_stop">停止</string> </resources>
Step 4 :主控制程序MainActivity.java的實現(xiàn),代碼如下:
package cn.roco.mp3;import java.io.File;import android.app.Activity; import android.content.Context; import android.media.MediaPlayer; import android.os.Bundle; import android.os.Environment; import android.telephony.PhoneStateListener; import android.telephony.TelephonyManager; import android.view.View; import android.widget.Button; import android.widget.EditText; import android.widget.TextView; import android.widget.Toast;public class MainActivity extends Activity {private TextView textView;private EditText file_name_Text;private String filePath;private MediaPlayer mediaPlayer;private boolean pause;private int playPosition;/** Called when the activity is first created. */@Overridepublic void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.main);textView=(TextView) this.findViewById(R.id.textView);file_name_Text = (EditText) this.findViewById(R.id.file_name);mediaPlayer = new MediaPlayer();TelephonyManager telephonyManager=(TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);telephonyManager.listen(new MyPhoneListener(), PhoneStateListener.LISTEN_CALL_STATE);}/*** 只有電話來了之后才暫停音樂的播放*/private final class MyPhoneListener extends android.telephony.PhoneStateListener{@Overridepublic void onCallStateChanged(int state, String incomingNumber) {switch (state) {case TelephonyManager.CALL_STATE_RINGING://電話來了if (mediaPlayer.isPlaying()) {playPosition = mediaPlayer.getCurrentPosition();// 獲得當前播放位置mediaPlayer.stop();}break;case TelephonyManager.CALL_STATE_IDLE: //通話結(jié)束if (playPosition > 0 && filePath != null) {play(playPosition);playPosition = 0;}break;}}}/*// 當該窗口處于不可見的時候觸發(fā)@Overrideprotected void onPause() {if (mediaPlayer.isPlaying()) {playPosition = mediaPlayer.getCurrentPosition();// 獲得當前播放位置mediaPlayer.stop();}super.onPause();}// 當該窗口處于重新回到前臺時候觸發(fā)@Overrideprotected void onResume() {if (playPosition > 0 && filePath != null) {play();mediaPlayer.seekTo(playPosition);playPosition = 0;}super.onResume();}*/@Overrideprotected void onDestroy() {mediaPlayer.release();mediaPlayer = null;super.onDestroy();}public void mediaPlay(View v) {switch (v.getId()) {// 播放按鈕case R.id.button_play:String fileName = file_name_Text.getText().toString();File audio = new File(Environment.getExternalStorageDirectory(),fileName);if (audio.exists()) {// 文件存在filePath = audio.getAbsolutePath(); // 文件絕對路徑play(0); // 播放音樂textView.setText("音樂開始播放...");} else {filePath = null;Toast.makeText(getApplicationContext(), R.string.file_noexist,1).show();}break;// 暫停按鈕case R.id.button_pause:if (mediaPlayer.isPlaying()) {// 如果正在播放mediaPlayer.pause();// 暫停pause = true;textView.setText("音樂暫停播放..."); ((Button) v).setText(R.string.button_continue);// 文字:暫停-->繼續(xù)} else {if (pause) {// 如果處于暫停狀態(tài)mediaPlayer.start();// 繼續(xù)播放pause = false;textView.setText("音樂繼續(xù)播放..."); ((Button) v).setText(R.string.button_pause);// 文字:繼續(xù)-->暫停}}break;// 重播按鈕case R.id.button_replay:if (mediaPlayer.isPlaying()) {textView.setText("音樂重新播放..."); mediaPlayer.seekTo(0);// 從開始位置開始播放音樂} else {if (filePath != null) {play(0);}}break;// 停止按鈕case R.id.button_stop:if (mediaPlayer.isPlaying()) {textView.setText("音樂停止播放..."); mediaPlayer.stop();}break;}}/*** 播放音樂* @param playPosition */private void play(int playPosition) {try {mediaPlayer.reset();// 把各項參數(shù)恢復到初始狀態(tài)/*** 通過MediaPlayer.setDataSource() 的方法,將URL或文件路徑以字符串的方式傳入.使用setDataSource ()方法時,要注意以下三點:1.構(gòu)建完成的MediaPlayer 必須實現(xiàn)Null 對像的檢查.2.必須實現(xiàn)接收IllegalArgumentException 與IOException 等異常,在很多情況下,你所用的文件當下并不存在.3.若使用URL 來播放在線媒體文件,該文件應該要能支持pragressive 下載.*/mediaPlayer.setDataSource(filePath);mediaPlayer.prepare();// 進行緩沖mediaPlayer.setOnPreparedListener(new MyPreparedListener(playPosition));} catch (Exception e) {e.printStackTrace();}}private final class MyPreparedListener implementsandroid.media.MediaPlayer.OnPreparedListener {private int playPosition;public MyPreparedListener(int playPosition) {this.playPosition=playPosition;}@Overridepublic void onPrepared(MediaPlayer mp) {mediaPlayer.start();// 開始播放if (playPosition>0) {mediaPlayer.seekTo(playPosition);}}}}
Step 5:由于加入了監(jiān)聽電話的功能,所以要在AndroidManifest.xml中配置權(quán)限
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android"package="cn.roco.mp3"android:versionCode="1"android:versionName="1.0"><uses-sdk android:minSdkVersion="8" /><!-- 注意:這里要加入一個監(jiān)聽電話的權(quán)限 --><uses-permission android:name="android.permission.READ_PHONE_STATE"></uses-permission><application android:icon="@drawable/icon" android:label="@string/app_name"><activity android:name=".MainActivity"android:label="@string/app_name"><intent-filter><action android:name="android.intent.action.MAIN" /><category android:name="android.intent.category.LAUNCHER" /></intent-filter></activity></application> </manifest> Step 6: 運行效果如下,一首動聽的Avril Lavigne - Complicated.mp3在播放...
? (1)?(2)(3)?(4)(5)?(6)
如果想加入進度條等功能 ?可以參考 Android MediaPlayer播放網(wǎng)絡音頻的實例--網(wǎng)絡mp3播放器? ? 這篇文章
==================================================================================================
? 作者:歐陽鵬 ?歡迎轉(zhuǎn)載,與人分享是進步的源泉!
? 轉(zhuǎn)載請保留原文地址:http://blog.csdn.net/ouyang_peng
==================================================================================================
轉(zhuǎn)載于:https://www.cnblogs.com/ouyangpeng/archive/2013/04/09/8538414.html
總結(jié)
以上是生活随笔為你收集整理的我的Android进阶之旅------Android MediaPlayer播放mp3的实例--简易mp3播放器的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: insert /*+ APPEND */
- 下一篇: Android实现通用的Activity