Android編程開發(fā)音樂播放器實(shí)例
本文實(shí)例講述了Android編程開發(fā)音樂播放器,分享給大家供大家參考,具體如下:
音樂播放器中綜合了以下內(nèi)容:
SeekBar、ListView、廣播接收者(以代碼的形式注冊(cè)Receiver)、系統(tǒng)服務(wù)、MediaPlayer
實(shí)現(xiàn)的功能:
1.暫停/播放、下一首/上一首,點(diǎn)擊某一首時(shí)播放
2.支持拖動(dòng)進(jìn)度條快進(jìn)
3.列表排序
4.來(lái)電話時(shí),停止播放,掛斷后繼續(xù)播放
5.可在后臺(tái)播放
效果圖:

界面:
main.xml:
<?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:id="@+id/name"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
/>
<SeekBar
android:id="@+id/seekBar"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="5dp"
/>
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="20dp"
>
<Button
android:layout_width="40dp"
android:layout_height="40dp"
android:text="|◀"
android:onClick="previous"
/>
<Button
android:id="@+id/pp"
android:layout_width="40dp"
android:layout_height="40dp"
android:text="▶"
android:onClick="pp"
/>
<Button
android:layout_width="40dp"
android:layout_height="40dp"
android:text="▶|"
android:onClick="next"
/>
</LinearLayout>
<ListView
android:id="@+id/list"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
/>
</LinearLayout>
item.xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:padding="10dp"
>
<TextView
android:id="@+id/mName"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textSize="15sp"
/>
</LinearLayout>
MainActivity:
package cn.test.audio;
import java.io.File;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.media.MediaPlayer;
import android.media.MediaPlayer.OnCompletionListener;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.telephony.PhoneStateListener;
import android.telephony.TelephonyManager;
import android.view.View;
import android.widget.AdapterView;
import android.widget.Button;
import android.widget.ListView;
import android.widget.SeekBar;
import android.widget.SimpleAdapter;
import android.widget.TextView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.SeekBar.OnSeekBarChangeListener;
public class MainActivity extends Activity {
private TextView nameTextView;
private SeekBar seekBar;
private ListView listView;
private List<Map<String, String>> data;
private int current;
private MediaPlayer player;
private Handler handler = new Handler();
private Button ppButton;
private boolean isPause;
private boolean isStartTrackingTouch;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
nameTextView = (TextView) findViewById(R.id.name);
seekBar = (SeekBar) findViewById(R.id.seekBar);
listView = (ListView) findViewById(R.id.list);
ppButton = (Button) findViewById(R.id.pp);
//創(chuàng)建一個(gè)音樂播放器
player = new MediaPlayer();
//顯示音樂播放列表
generateListView();
//進(jìn)度條監(jiān)聽器
seekBar.setOnSeekBarChangeListener(new MySeekBarListener());
//播放器監(jiān)聽器
player.setOnCompletionListener(new MyPlayerListener());
//意圖過(guò)濾器
IntentFilter filter = new IntentFilter();
//播出電話暫停音樂播放
filter.addAction("android.intent.action.NEW_OUTGOING_CALL");
registerReceiver(new PhoneListener(), filter);
//創(chuàng)建一個(gè)電話服務(wù)
TelephonyManager manager = (TelephonyManager) getSystemService(TELEPHONY_SERVICE);
//監(jiān)聽電話狀態(tài),接電話時(shí)停止播放
manager.listen(new MyPhoneStateListener(), PhoneStateListener.LISTEN_CALL_STATE);
}
/*
* 監(jiān)聽電話狀態(tài)
*/
private final class MyPhoneStateListener extends PhoneStateListener {
public void onCallStateChanged(int state, String incomingNumber) {
pause();
}
}
/*
* 播放器監(jiān)聽器
*/
private final class MyPlayerListener implements OnCompletionListener {
//歌曲播放完后自動(dòng)播放下一首歌曲
public void onCompletion(MediaPlayer mp) {
next();
}
}
/*
* 下一首按鈕
*/
public void next(View view) {
next();
}
/*
* 前一首按鈕
*/
public void previous(View view) {
previous();
}
/*
* 播放前一首歌
*/
private void previous() {
current = current - 1 < 0 ? data.size() - 1 : current - 1;
play();
}
/*
* 播放下一首歌
*/
private void next() {
current = (current + 1) % data.size();
play();
}
/*
* 進(jìn)度條監(jiān)聽器
*/
private final class MySeekBarListener implements OnSeekBarChangeListener {
//移動(dòng)觸發(fā)
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
}
//起始觸發(fā)
public void onStartTrackingTouch(SeekBar seekBar) {
isStartTrackingTouch = true;
}
//結(jié)束觸發(fā)
public void onStopTrackingTouch(SeekBar seekBar) {
player.seekTo(seekBar.getProgress());
isStartTrackingTouch = false;
}
}
/*
* 顯示音樂播放列表
*/
private void generateListView() {
List<File> list = new ArrayList<File>();
//獲取sdcard中的所有歌曲
findAll(Environment.getExternalStorageDirectory(), list);
//播放列表進(jìn)行排序,字符順序
Collections.sort(list);
data = new ArrayList<Map<String, String>>();
for (File file : list) {
Map<String, String> map = new HashMap<String, String>();
map.put("name", file.getName());
map.put("path", file.getAbsolutePath());
data.add(map);
}
SimpleAdapter adapter = new SimpleAdapter(this, data, R.layout.item, new String[] { "name" }, new int[] { R.id.mName });
listView.setAdapter(adapter);
listView.setOnItemClickListener(new MyItemListener());
}
private final class MyItemListener implements OnItemClickListener {
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
current = position;
play();
}
}
private void play() {
try {
//重播
player.reset();
//獲取歌曲路徑
player.setDataSource(data.get(current).get("path"));
//緩沖
player.prepare();
//開始播放
player.start();
//顯示歌名
nameTextView.setText(data.get(current).get("name"));
//設(shè)置進(jìn)度條長(zhǎng)度
seekBar.setMax(player.getDuration());
//播放按鈕樣式
ppButton.setText("||");
//發(fā)送一個(gè)Runnable, handler收到之后就會(huì)執(zhí)行run()方法
handler.post(new Runnable() {
public void run() {
// 更新進(jìn)度條狀態(tài)
if (!isStartTrackingTouch)
seekBar.setProgress(player.getCurrentPosition());
// 1秒之后再次發(fā)送
handler.postDelayed(this, 1000);
}
});
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 查找文件路徑中所有mp3文件
* @param file 要找的目錄
* @param list 用來(lái)裝文件的List
*/
private void findAll(File file, List<File> list) {
File[] subFiles = file.listFiles();
if (subFiles != null)
for (File subFile : subFiles) {
if (subFile.isFile() && subFile.getName().endsWith(".mp3"))
list.add(subFile);
else if (subFile.isDirectory())//如果是目錄
findAll(subFile, list); //遞歸
}
}
/*
* 暫停/播放按鈕
*/
public void pp(View view) {
//默認(rèn)從第一首歌曲開始播放
if (!player.isPlaying() && !isPause) {
play();
return;
}
Button button = (Button) view;
//暫停/播放按鈕
if ("||".equals(button.getText())) {
pause();
button.setText("▶");
} else {
resume();
button.setText("||");
}
}
/*
* 開始操作
*/
private void resume() {
if (isPause) {
player.start();
isPause = false;
}
}
/*
* 暫停操作
*/
private void pause() {
if (player != null && player.isPlaying()) {
player.pause();
isPause = true;
}
}
/*
* 收到廣播時(shí)暫停
*/
private final class PhoneListener extends BroadcastReceiver {
public void onReceive(Context context, Intent intent) {
pause();
}
}
/*
* 恢復(fù)播放
* @see android.app.Activity#onResume()
*/
protected void onResume() {
super.onResume();
resume();
}
}
注冊(cè)權(quán)限:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="cn.itcast.audio"
android:versionCode="1"
android:versionName="1.0">
<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>
<uses-sdk android:minSdkVersion="8" />
<!-- 監(jiān)聽電話呼出 -->
<uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS"/>
<!-- 監(jiān)聽電話狀態(tài)改變 -->
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
</manifest>
希望本文所述對(duì)大家Android程序設(shè)計(jì)有所幫助。
- Android實(shí)現(xiàn)簡(jiǎn)單音樂播放器(MediaPlayer)
- Android簡(jiǎn)易音樂播放器實(shí)現(xiàn)代碼
- 教你輕松制作Android音樂播放器
- android暫停或停止其他音樂播放器的播放實(shí)現(xiàn)代碼
- Android音樂播放器制作 掃描本地音樂顯示在手機(jī)(一)
- android實(shí)現(xiàn)音樂播放器進(jìn)度條效果
- Android MediaPlayer實(shí)現(xiàn)音樂播放器實(shí)例代碼
- 簡(jiǎn)單實(shí)現(xiàn)Android本地音樂播放器
- Android 音樂播放器的開發(fā)實(shí)例詳解
- Android實(shí)現(xiàn)簡(jiǎn)單的音樂播放器
相關(guān)文章
Android程序自動(dòng)更新功能模塊的實(shí)現(xiàn)方法【附完整demo源碼下載】
這篇文章主要介紹了Android程序自動(dòng)更新功能模塊的實(shí)現(xiàn)方法,具備完整的自動(dòng)檢測(cè)更新及下載、安裝等功能,并附帶完整的demo源碼供大家下載參考,需要的朋友可以參考下2016-08-08
Kotlin 擴(kuò)展函數(shù)和擴(kuò)展屬性的使用方法
這篇文章主要介紹了Kotlin 擴(kuò)展函數(shù)和擴(kuò)展屬性的使用方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-10-10
ffmpeg實(shí)現(xiàn)去水印以及切分視頻demo
這篇文章主要為大家介紹了ffmpeg實(shí)現(xiàn)去水印以及切分視頻demo,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-11-11
Android開發(fā)筆記之:用Enum(枚舉類型)取代整數(shù)集的應(yīng)用詳解
本篇文章是對(duì)Android中用Enum(枚舉類型)取代整數(shù)集的應(yīng)用進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下2013-05-05
Android頂部工具欄和底部工具欄的簡(jiǎn)單實(shí)現(xiàn)代碼
Android頂部工具欄和底部工具欄的簡(jiǎn)單實(shí)現(xiàn)代碼,需要的朋友可以參考一下2013-05-05

