大家好我們今天研究的是Android中很重要也最為復(fù)雜的媒體播放器---MediaPlayer. Android的MediaPlayer包含了Audio和video的播放功能,在Android的界面上,Music和Video兩個(gè)應(yīng)用程序都是調(diào)用MediaPlayer實(shí)現(xiàn)的。 首先來看看MediaPlayer的生命周期: 從MediaPlayer的生命周期圖或者說是狀態(tài)轉(zhuǎn)移圖上來看:
下邊是MediaPlayer提供的常用方法:
至此,可以得出Android中通過MediaPlayer來播放音樂的步驟: MediaPlayer mp = new MediaPlayer();//構(gòu)建MediaPlayer對(duì)象 mp.setDataSource("/sdcard/test.mp3");//設(shè)置文件路徑 mp.prepare();//準(zhǔn)備 mp.start();//開始播放 MediaPlayer在底層是基于OpenCore(PacketVideo)的庫實(shí)現(xiàn)的,為了構(gòu)建一個(gè)MediaPlayer程序,上層還包含了進(jìn)程間通訊等內(nèi)容,這種進(jìn)程間通訊的基礎(chǔ)是Android基本庫中的Binder機(jī)制。 而我們今天的例子只是利用MediaPlayer來播放res/raw文件夾中一首非常動(dòng)聽的英文哥Avril Lavigne - Complicated.mp3.程序有4個(gè)ImageButton按鈕,播放,停止,重播和暫停!4個(gè)按鈕的功能我就不用多說.下面我將Step By Step教你如何完成本Demo的實(shí)現(xiàn).本實(shí)例可以實(shí)現(xiàn)音樂播放器除了來電的時(shí)候會(huì)暫停播放,通話結(jié)束后恢復(fù)播放外,打開其他的Activity都可以繼續(xù)播放音樂,享受一邊聽音樂一邊做其他的事情。 Step 1 :新建一個(gè)Android工程,命名為AudioPlayer Step 2 :準(zhǔn)備素材,將Avril Lavigne - Complicated.mp3導(dǎo)入到SDCard中 Step 3: 設(shè)計(jì)UI布局,在main.xml里放入4個(gè)ImageButton,代碼如下: <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas./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">請(qǐng)輸入音樂文件名</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的實(shí)現(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. */ @Override public 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{ @Override public void onCallStateChanged(int state, String incomingNumber) { switch (state) { case TelephonyManager.CALL_STATE_RINGING://電話來了 if (mediaPlayer.isPlaying()) { playPosition = mediaPlayer.getCurrentPosition();// 獲得當(dāng)前播放位置 mediaPlayer.stop(); } break; case TelephonyManager.CALL_STATE_IDLE: //通話結(jié)束 if (playPosition > 0 && filePath != null) { play(playPosition); playPosition = 0; } break; } } } /* // 當(dāng)該窗口處于不可見的時(shí)候觸發(fā) @Override protected void onPause() { if (mediaPlayer.isPlaying()) { playPosition = mediaPlayer.getCurrentPosition();// 獲得當(dāng)前播放位置 mediaPlayer.stop(); } super.onPause(); } // 當(dāng)該窗口處于重新回到前臺(tái)時(shí)候觸發(fā) @Override protected void onResume() { if (playPosition > 0 && filePath != null) { play(); mediaPlayer.seekTo(playPosition); playPosition = 0; } super.onResume(); } */ @Override protected 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(); // 文件絕對(duì)路徑 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();// 把各項(xiàng)參數(shù)恢復(fù)到初始狀態(tài) /** * 通過MediaPlayer.setDataSource() 的方法,將URL或文件路徑以字符串的方式傳入.使用setDataSource ()方法時(shí),要注意以下三點(diǎn): 1.構(gòu)建完成的MediaPlayer 必須實(shí)現(xiàn)Null 對(duì)像的檢查. 2.必須實(shí)現(xiàn)接收IllegalArgumentException 與IOException 等異常,在很多情況下,你所用的文件當(dāng)下并不存在. 3.若使用URL 來播放在線媒體文件,該文件應(yīng)該要能支持pragressive 下載. */ mediaPlayer.setDataSource(filePath); mediaPlayer.prepare();// 進(jìn)行緩沖 mediaPlayer.setOnPreparedListener(new MyPreparedListener(playPosition)); } catch (Exception e) { e.printStackTrace(); } } private final class MyPreparedListener implements android.media.MediaPlayer.OnPreparedListener { private int playPosition; public MyPreparedListener(int playPosition) { this.playPosition=playPosition; } @Override public 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./apk/res/android" package="cn.roco.mp3" android:versionCode="1" android:versionName="1.0"> <uses-sdk android:minSdkVersion="8" /> <!-- 注意:這里要加入一個(gè)監(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: 運(yùn)行效果如下,一首動(dòng)聽的Avril Lavigne - Complicated.mp3在播放...
|
|