安卓應用背景音樂使用 MediaPlayer實現。
MediaPlayer創建通過方法 MediaPlayer.create(context, resId);
context爲音樂播放器的上下文,取用this.getApplication().getApplicationContext()的上下文可以防止持有外部類導致Activity無法回收。在調用create方法前必須保證MediaPlayer對象爲狀態爲空。否則將會報錯。可在調用前判斷是否爲空,不爲空則調用MediaPlayer.reset()方法進行重置。
播放音樂 MediaPlayer.start()
暫停音樂 MediaPlayer.pause()
設置音樂播放完畢事件 mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
@Override
public void onCompletion(MediaPlayer mp) {
//do something…
}
});
順序播放:
重置創建播放器,資源使用列表下一首->設置播放完畢事件->音樂播放
在播放完畢事件中回調整個方法。
隨機播放:
與順序播放區別在於,在創建播放器時隨機獲取列表中的資源
上一曲、下一曲
手動調用上述的方法即可。
進度條
使用mediaPlayer.getCurrentPosition()獲取當前播放位置, mediaPlayer.getDuration()獲取歌曲總長度,使用Timer進行不斷髮請求獲取當前位置並渲染進度條控件即可。
多個界面共享音樂播放器
在寫音樂播放器代碼時,我想要音樂按鈕不止在主界面可以使用,在數字選擇界面,在數字書寫界面等其他界面我也想能夠隨時控制音樂的播放與停止狀態。即應用的所有界面共享同一個音樂播放器。
我的思路是定義一個BasicActivity類,將音樂播放器設置爲靜態對象,在所有Activity中均繼承基本類,實現音樂播放器共享。佈局文件中按鈕有兩種狀態,音樂正在播放,音樂停止播放,當Activity切換時我們就需要根據當前播放狀態去渲染音樂按鈕,音樂按鈕可以每個佈局文件中定義,而我定義在了BasicActivity的佈局文件中,並在其他佈局文件中使用<include>標籤引用,此功能實現代碼如下。
當我們進入一個擁有音樂按鈕的界面時,需要做三件事
1.調用setContentView設置佈局文件 2.獲取按鈕並根據狀態設置背景圖片 3.播放音樂並設置播放完成切換歌曲事件
當進入主應用界面時第一次初始化音樂播放器開始播放音樂,在跳轉後不改變音樂播放器狀態,僅根據播放器狀態渲染控件。
所以講音樂播放和設置下一曲的調用放在主應用界面的Activity中,而渲染控件放在BasicActivity中進行。
效果是進入主界面即開始播放歌曲,之後任意切換界面都不影響音樂播放,並且每個界面都可以停止或播放歌曲。
若遇到程序報空指針錯誤,錯誤指向music_btn.setBackgroundResource(R.mipmap.btn_music1)等對控件操作的調用時,可能是在調用順序上出了問題,在使用findViewById時還未調用setContentView,導致獲取的控件是null。所以在使用findViewById時必須確認在此之前已經使用setContentView設置了主佈局。
具體實現代碼如下
BasicActivity
public class BasicActivity extends Activity {
static boolean isPlay = true; //播放狀態
static MediaPlayer mediaPlayer; //音樂播放器
static int musicIndex = 0; //當前播放序號
static Context context; //上下文
static int[] musicList = {R.raw.high_hopes, R.raw.don_t_miss_now, R.raw.don_t_you_worry_child}; //播放歌曲列表
Button music_btn; //前臺按鈕控件
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
context = this.getApplication().getApplicationContext();
//通過id獲取佈局文件中按鈕控件
music_btn = (Button) findViewById(R.id.btn_music);
//根據播放狀態渲染按鈕圖片
if (isPlay) {
music_btn.setBackgroundResource(R.mipmap.btn_music1);
} else {
music_btn.setBackgroundResource(R.mipmap.btn_music2);
}
//內存監視器
RefWatcher refWatcher = App.getRefWatcher(this);
refWatcher.watch(this);
}
//點擊事件,將播放器狀態置反並渲染按鈕圖片
public void onClick(View v) {
if (isPlay) {
if (mediaPlayer != null) {
mediaPlayer.pause();
music_btn.setBackgroundResource(R.mipmap.btn_music2);
isPlay = false;
}
} else {
mediaPlayer.start();
music_btn.setBackgroundResource(R.mipmap.btn_music1);
isPlay = true;
}
}
//設置播放器播放完畢回調函數,進行歌曲切換
public static void setPlayList() {
try {
mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
@Override
public void onCompletion(MediaPlayer mp) {
musicIndex++;
if (musicIndex >= musicList.length) {
musicIndex = 0;
}
playMusic(musicList[musicIndex]);
setPlayList();
}
});
} catch (Exception e) {
e.printStackTrace();
}
}
//播放歌曲,保證播放器爲空後創建新的播放器,開始播放音樂
public static void playMusic(int resId) {
if (mediaPlayer != null) {
mediaPlayer.reset();
}
mediaPlayer = MediaPlayer.create(context, resId);
mediaPlayer.start();
}
}
-------------------------BasicLayout----------------------
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="60dp"
android:layout_height="60dp"
android:layout_margin="10dp"
android:layout_alignParentBottom="true"
tools:context=".BasicActivity">
<Button
android:id="@+id/btn_music"
android:layout_width="60dp"
android:layout_height="60dp"
android:layout_margin="0dp"
android:background="@drawable/btn_music"
android:onClick="onClick" />
</RelativeLayout>
------------------------MainActivity----------------------
//繼承了BasicActivity
public class MainActivity extends BasicActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
//必須先設置視圖,而後調用BasicActivity的onCreate函數
//若順序反過來將會報空指針錯誤,因爲沒有渲染前臺控件,則沒有音樂按鈕
setContentView(R.layout.activity_main);
super.onCreate(savedInstanceState);
playMusic(musicList[musicIndex]);
setPlayList();
}
//跳轉游戲選擇界面
public void OnPlay(View v) {
startActivity(new Intent(MainActivity.this, SelectActivity.class));
}
//跳轉關於我們界面
public void OnAbout(View v) {
startActivity(new Intent(MainActivity.this, AboutActivity.class));
}
}
----------------------MainLayout----------------------
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/main_bg"
tools:context="com.example.wangjy.activity.MainActivity">
<Button
android:layout_width="60dp"
android:layout_height="60dp"
android:layout_above="@+id/btn_about"
android:layout_centerHorizontal="true"
android:background="@drawable/btn_play"
android:onClick="OnPlay" />
<include layout="@layout/activity_basic" />
<Button
android:id="@+id/btn_about"
android:layout_width="60dp"
android:layout_height="60dp"
android:layout_alignParentBottom="true"
android:layout_alignParentEnd="true"
android:layout_alignParentRight="true"
android:layout_margin="10dp"
android:background="@drawable/btn_about"
android:onClick="OnAbout" />
</RelativeLayout>