|
大家好我們今天研究的是Android中很重要也最為復雜的媒體播放器---MediaPlayer. Android的MediaPlayer包含了Audio和video的播放功能,在Android的界面上,Music和Video兩個應用程序都是調(diào)用MediaPlayer實現(xiàn)的。 首先來看看MediaPlayer的生命周期:
從MediaPlayer的生命周期圖或者說是狀態(tài)轉(zhuǎn)移圖上來看:
下邊是MediaPlayer提供的常用方法:
至此,可以得出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./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. */
@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();// 獲得當前播放位置
mediaPlayer.stop();
}
break;
case TelephonyManager.CALL_STATE_IDLE: //通話結(jié)束
if (playPosition > 0 && filePath != null) {
play(playPosition);
playPosition = 0;
}
break;
}
}
}
/*
// 當該窗口處于不可見的時候觸發(fā)
@Override
protected void onPause() {
if (mediaPlayer.isPlaying()) {
playPosition = mediaPlayer.getCurrentPosition();// 獲得當前播放位置
mediaPlayer.stop();
}
super.onPause();
}
// 當該窗口處于重新回到前臺時候觸發(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(); // 文件絕對路徑
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 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" />
<!-- 注意:這里要加入一個監(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在播放...
|
|
|