运行结果:
具体实现步骤:
Step1: activity_main.xml
<?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:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:background="@mipmap/bg"
tools:context="com.victor.a1000phone.mysonymusicplayer.MainActivity">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="播放列表"
android:textSize="28sp"
android:id="@+id/txt_title"
android:textColor="#ffffff"
android:layout_centerHorizontal="true"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_marginBottom="80dp"
android:text="00:00"
android:id="@+id/txt_currentTime"
android:textColor="#ffffff"
android:textSize="19sp"
/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#ffffff"
android:textSize="19sp"
android:id="@+id/txt_totalTime"
android:layout_alignParentBottom="true"
android:layout_alignParentRight="true"
android:text="00:00"
android:layout_marginBottom="80dp"/>
<SeekBar
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/seekbar"
android:layout_toRightOf="@id/txt_currentTime"
android:layout_alignParentBottom="true"
android:layout_toLeftOf="@id/txt_totalTime"
android:layout_marginBottom="80dp"/>
<ListView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/lv_musicList"
android:layout_below="@id/txt_title"
android:layout_margin="8dp"
android:layout_above="@id/txt_currentTime">
</ListView>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_alignParentBottom="true"
android:gravity="center"
android:layout_marginBottom="2dp">
<Button
android:layout_width="50dp"
android:layout_height="50dp"
android:id="@+id/btn_back"
android:layout_margin="10dp"
android:background="@mipmap/back"
android:onClick="onClick"/>
<Button
android:layout_width="50dp"
android:layout_height="50dp"
android:id="@+id/btn_pause"
android:background="@mipmap/begin"
android:layout_margin="10dp"
android:onClick="onClick"/>
<Button
android:layout_width="50dp"
android:layout_height="50dp"
android:id="@+id/btn_stop"
android:background="@mipmap/stop"
android:layout_margin="10dp"
android:onClick="onClick"/>
<Button
android:layout_width="50dp"
android:layout_height="50dp"
android:id="@+id/btn_next"
android:background="@mipmap/next"
android:layout_margin="10dp"
android:onClick="onClick"/>
</LinearLayout>
</RelativeLayout>
Step2: MainActivity.java
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.ServiceConnection;
import android.os.Environment;
import android.os.IBinder;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.Window;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ListView;
import android.widget.SeekBar;
import android.widget.TextView;
import java.io.File;
import java.io.FileFilter;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;
public class MainActivity extends AppCompatActivity implements ServiceConnection {
private File[] musicFile;
private ListView mLvMusicList;
private List<String> musics = new ArrayList<>();
;
private ArrayAdapter<String> adapter;
private PlayMusicService playMusicService;
private Button mBtnPause;
private TextView mTxtMusicTotalTime, mTxtMusicCurrentTime;
//暂停或继续播放的标志位
private boolean isGoOn = false;
//时间存储变量
private int totalTime;
private int currentTime;
private SeekBar mseekBar;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.activity_main);
musicFile = getMusicFiles();
initView();
//绑定Service
Intent intent = new Intent(this, PlayMusicService.class);
intent.putExtra("musicFiles", new MusicFiles(musicFile));
boolean isBindSuccess = bindService(intent, this, Context.BIND_AUTO_CREATE);
Log.i("1607", isBindSuccess + "");
//注册接受音乐时长的广播接收器
MusicDurationReceiver musicDurationReceiver = new MusicDurationReceiver();
IntentFilter intentFilterMusicduration = new IntentFilter();
intentFilterMusicduration.addAction("com.musicTime");
registerReceiver(musicDurationReceiver, intentFilterMusicduration);
//注册接受音乐当前时长的广播接收器
MusicPositionReceiver musicPositionReceiver = new MusicPositionReceiver();
IntentFilter intentFilterMusicCurrent = new IntentFilter();
intentFilterMusicCurrent.addAction("com.current");
registerReceiver(musicPositionReceiver, intentFilterMusicCurrent);
}
private void initView() {
mLvMusicList = (ListView) findViewById(R.id.lv_musicList);
mBtnPause = (Button) findViewById(R.id.btn_pause);
mTxtMusicTotalTime = (TextView) findViewById(R.id.txt_totalTime);
mTxtMusicCurrentTime = (TextView) findViewById(R.id.txt_currentTime);
mseekBar = (SeekBar) findViewById(R.id.seekbar);
adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, musics);
mLvMusicList.setAdapter(adapter);
mLvMusicList.setOnItemClickListener(listener);
mseekBar.setOnSeekBarChangeListener(listenerSeekBar);
}
/**
* SeekBar的监听器
*/
SeekBar.OnSeekBarChangeListener listenerSeekBar = new SeekBar.OnSeekBarChangeListener() {
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
Log.i("1607", "Seekbar被改变的进度为:" + seekBar.getProgress());
if (fromUser){
int currentPase = seekBar.getProgress() * totalTime / 100;
Intent intent=new Intent("com.currentPase");
intent.putExtra("currentPase",currentPase);
sendBroadcast(intent);
}
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
Log.i("1607", "Seekbar被拖动的进度为:" + seekBar.getProgress());
}
};
/**
* ListView 的点击监听
*/
AdapterView.OnItemClickListener listener = new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
isGoOn = true;
mBtnPause.setBackgroundResource(R.mipmap.pause);
playMusicService.prepareMusic(position);
//将用户的选择通过广播传到Service中
Intent intent = new Intent();
intent.setAction("com.userChooseMusic");
intent.putExtra("position", position);
sendBroadcast(intent);
}
};
private File[] getMusicFiles() {
File file = new File(Environment.getExternalStorageDirectory().getAbsolutePath() + File.separator + "myplaylist"
+ File.separator + "audios");
musicFile = file.listFiles(new FileFilter() {
@Override
public boolean accept(File pathname) {
String fileName = pathname.getName();
if (fileName.endsWith(".mp3")) {
musics.add(fileName);
return true;
} else {
return false;
}
}
});
return musicFile;
}
public void onClick(View view) {
switch (view.getId()) {
case R.id.btn_back://上一曲
playMusicService.back();
break;
case R.id.btn_pause://暂停或继续播放
isGoOn = !isGoOn;
if (isGoOn) {
mBtnPause.setBackgroundResource(R.mipmap.pause);
playMusicService.startMusic();
} else {
mBtnPause.setBackgroundResource(R.mipmap.begin);
playMusicService.pauseMusic();
}
break;
case R.id.btn_stop://停止
playMusicService.stopMusic();
mTxtMusicTotalTime.setText("00:00");
break;
case R.id.btn_next://下一曲
playMusicService.next();
break;
}
}
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
PlayMusicService.MyService service1 = (PlayMusicService.MyService) service;
playMusicService = service1.getService();
}
@Override
public void onServiceDisconnected(ComponentName name) {
}
/**
* @param time int类型,从Service端获取
* @return 音乐播放时间,格式为:00:00
*/
public String getTimeFormat(int time) {
SimpleDateFormat format = new SimpleDateFormat("mm:ss");
String musicTime = format.format(time);
return musicTime;
}
//=============================来自PlayMusicService发送来的广播监听器============================
/**
* 接受音乐总时长的监听器
*/
class MusicDurationReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
totalTime = intent.getIntExtra("musicTime", 0);
String totalTimeShow = getTimeFormat(totalTime);
mTxtMusicTotalTime.setText(totalTimeShow);
}
}
/**
* 接受音乐当前进度的监听器
*/
class MusicPositionReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
currentTime = intent.getIntExtra("currentPositionMusic", 0);
String current = getTimeFormat(currentTime);
mTxtMusicCurrentTime.setText(current);
//计算当前的SeekBar应该显示的进度
double currentRate = currentTime / (double) (totalTime);
double progressDouble = currentRate * 100;
mseekBar.setProgress((int) progressDouble);
}
}
}
Step3 : MusicFiles.java
import java.io.File;
import java.io.Serializable;
/**
* Created by Victor on 2016/9/23.
*/
public class MusicFiles implements Serializable {
public File[] musicFiles;
public MusicFiles(File[] musicFiles){
this.musicFiles=musicFiles;
}
public File[] getMusicFiles() {
return musicFiles;
}
}
Step4 : PlayMusicService.java
import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.media.MediaPlayer;
import android.os.Binder;
import android.os.IBinder;
import android.support.annotation.Nullable;
import android.util.Log;
import android.widget.Toast;
import java.io.File;
import java.io.IOException;
/**
* Created by Administrator on 2016/9/23.
*/
public class PlayMusicService extends Service {
private MediaPlayer mediaPlayer;
private int currentPosition = 0;
private boolean isStop = true;
private File[] musicFiles;
private int musicDuration;
private int currentPositionMusic;
public PlayMusicService() {
}
@Override
public void onCreate() {
super.onCreate();
if (mediaPlayer == null) {
mediaPlayer = new MediaPlayer();
}
mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
@Override
public void onCompletion(MediaPlayer mp) {
currentPosition++;
if (currentPosition == musicFiles.length) {
currentPosition = 0;
}
prepareMusic(currentPosition);
}
});
//注册用户选择音乐位置监听的广播接收者
UserChooseMusic userChooseMusic = new UserChooseMusic();
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction("com.userChooseMusic");
registerReceiver(userChooseMusic, intentFilter);
//注册用户拖动SeekBar改变音乐进度的监听器
CurrentProgressReceiver currentProgressReceiver = new CurrentProgressReceiver();
IntentFilter intentFilterProgress = new IntentFilter();
intentFilterProgress.addAction("com.currentPase");
registerReceiver(currentProgressReceiver, intentFilterProgress);
}
/**
* 重新开始一首歌
*/
public void prepareMusic(int currentPosition) {
try {
mediaPlayer.reset();
mediaPlayer.setDataSource(musicFiles[currentPosition].getAbsolutePath());
mediaPlayer.prepare();
mediaPlayer.start();
isStop = false;
//得到歌曲的总时长,并传送给Mainctivity
musicDuration = mediaPlayer.getDuration();
//发送广播传递到Mainctivity
Intent intent = new Intent("com.musicTime");
intent.putExtra("musicTime", musicDuration);
sendBroadcast(intent);
getCurrentPositionOfMusic();
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 开启另一个线程,每隔一秒读取MediaPlayer当前的进度:getCurrentPosion
* 并将进度发送到MainActivity
*/
private void getCurrentPositionOfMusic() {
new Thread(new Runnable() {
@Override
public void run() {
currentPositionMusic = mediaPlayer.getCurrentPosition();
try {
while (currentPositionMusic <= musicDuration) {
//发送广播,将当前音乐的播放进度发送给MainActivity
Intent intent = new Intent("com.current");
intent.putExtra("currentPositionMusic", currentPositionMusic);
sendBroadcast(intent);
currentPositionMusic = mediaPlayer.getCurrentPosition();
Thread.sleep(1000);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}).start();
}
/**
* 暂停之后继续播放一首歌
*/
public void startMusic() {
if (mediaPlayer != null && !isStop) {
mediaPlayer.start();
} else {
Toast.makeText(this, "您已经停止播放,请选择想要播放的歌曲", Toast.LENGTH_SHORT).show();
}
}
/**
* 暂停播放歌曲
*/
public void pauseMusic() {
if (mediaPlayer != null && mediaPlayer.isPlaying()) {
mediaPlayer.pause();
} else {
Toast.makeText(this, "当前没有歌曲在播放", Toast.LENGTH_SHORT).show();
}
}
/**
* 停止歌曲
*/
public void stopMusic() {
if (mediaPlayer != null) {
mediaPlayer.stop();
isStop = true;
}
}
/**
* 上一首歌曲
*/
public void back() {
if (mediaPlayer != null) {
currentPosition--;
if (currentPosition < 0) {
currentPosition = musicFiles.length - 1;
}
prepareMusic(currentPosition);
}
}
/**
* 下一首歌曲
*/
public void next() {
if (mediaPlayer != null) {
currentPosition++;
if (currentPosition == musicFiles.length) {
currentPosition = 0;
}
prepareMusic(currentPosition);
}
}
class MyService extends Binder {
public PlayMusicService getService() {
return PlayMusicService.this;
}
}
@Nullable
@Override
public IBinder onBind(Intent intent) {
musicFiles = ((MusicFiles) (intent.getSerializableExtra("musicFiles"))).getMusicFiles();
return new MyService();
}
@Override
public boolean onUnbind(Intent intent) {
return super.onUnbind(intent);
}
@Override
public void onDestroy() {
super.onDestroy();
}
//======================================广播接收器=================================
class UserChooseMusic extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
currentPosition = intent.getIntExtra("position", 0);
Log.i("1607", "用户选择的是第" + currentPosition + "首歌");
}
}
class CurrentProgressReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
int currentProgress = intent.getIntExtra("currentPase", 0);
//将音乐播放器移至currentProgress进度处
mediaPlayer.seekTo(currentProgress);
}
}
}
Step5 : AndroidManifest.xml**(这里的设置非常重要,决定能不能成功运行)**
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.victor.a1000phone.mysonymusicplayer">
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".MainActivity"
android:theme="@style/Theme.AppCompat.Light.NoActionBar">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service android:name=".PlayMusicService"
android:exported="true"
android:enabled="true"/>
</application>
</manifest>
Step6 :环境配置
模拟器:
1.如果你用模拟器运行,就建立一个”mymusiclist”文件夹, 里面再建一个”audios”文件夹.
2.把你的MP3文件全部放到”audios”文件夹中。
3.把“mymusiclist”文件夹拖到“sdcard”文件夹中。如图***
4.运行项目程序
自己的手机
1.在SD卡根目录下建立一个”mymusiclist”文件夹, 里面再建一个”audios”文件夹.
2.把你的MP3文件全部放到”audios”文件夹中。
3.运行项目程序
PS: 代码里有每个模块的注释,在这里就不啰嗦了。大家有不明白的地方可以留言哈,一起讨论,一起进步。