效果图:
先完成布局和播放功能
<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"> <SeekBar android:id="@+id/seekbar" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_alignParentBottom="true" android:paddingBottom="30dp" /> <LinearLayout android:id="@+id/layout_button" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_above="@id/seekbar" android:orientation="horizontal"> <Button android:id="@+id/up" android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1" android:onClick="up" android:text="上一首" /> <Button android:id="@+id/play" android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1" android:onClick="play" android:text="播放" /> <Button android:id="@+id/next" android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1" android:onClick="next" android:text="下一首" /> </LinearLayout> </RelativeLayout>
public class SdcardUtils { public static boolean isMounted(){ return Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED); } public static String getPath(){ if(isMounted()){ return Environment.getExternalStorageDirectory().getAbsolutePath(); }else{ return null; } } public static void getAllMp3File(String filePath,List<String> list){ File file = new File(filePath); File[] files = file.listFiles(); for(int i = 0;i<files.length;i++){ File subFile = files[i]; if(subFile.isDirectory()){ getAllMp3File(subFile.getAbsolutePath(),list); }else{ if(subFile.getName().endsWith(".mp3")){ list.add(subFile.getAbsolutePath()); } } } } }
public class MusicService extends Service { class MyBinder extends Binder { public MusicService getService(){ return MusicService.this; } } private MediaPlayer mediaPlayer; @Override public IBinder onBind(Intent intent) { MyBinder binder = new MyBinder(); return binder; } @Override public void onCreate() { super.onCreate(); mediaPlayer = new MediaPlayer(); try { mediaPlayer.setDataSource(Environment.getExternalStorageDirectory()+"/"+Environment.DIRECTORY_MUSIC+"/a.mp3"); mediaPlayer.prepare(); } catch (IOException e) { e.printStackTrace(); } } @Override public void onDestroy() { super.onDestroy(); mediaPlayer.release(); } public void servicePlay(){ if(mediaPlayer.isPlaying()){ mediaPlayer.pause(); }else{ mediaPlayer.start(); } } public void serviceChangeMusic(String musicPath){ mediaPlayer.reset(); try { mediaPlayer.setDataSource(musicPath); mediaPlayer.prepare(); mediaPlayer.start(); } catch (IOException e) { e.printStackTrace(); } } }
public class MainActivity extends AppCompatActivity { private SeekBar seekBar; private Intent intent; private MusicServiceConnection musicServiceConnection; private MusicService musicService; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); seekBar = (SeekBar) findViewById(R.id.seekbar); intent = new Intent(this,MusicService.class); musicServiceConnection = new MusicServiceConnection(); bindService(intent,musicServiceConnection,BIND_AUTO_CREATE); } @Override protected void onDestroy() { super.onDestroy(); unbindService(musicServiceConnection); } class MusicServiceConnection implements ServiceConnection{ @Override public void onServiceConnected(ComponentName name, IBinder service) { MusicService.MyBinder myBinder = (MusicService.MyBinder) service; musicService = myBinder.getService(); } @Override public void onServiceDisconnected(ComponentName name) { } } public void play(View view){ musicService.servicePlay(); } public void up(View view){ } public void next(View view){ } }
第二步:实现上一首、下一首和完善播放键
优化MusicService类的onCreate方法和MainActivity类的play/up/next方法
@Override public void onCreate() { super.onCreate(); mediaPlayer = new MediaPlayer(); }
public void play(View view){ if(isFirst){ //判断是不是第一次点击播放键 musicService.serviceChangeMusic(musicList.get(current_position)); play.setText("暂停"); isFirst = false; }else{ String musicState = play.getText().toString(); play.setText("播放".equals(musicState)?"暂停":"播放"); musicService.servicePlay(); } } public void up(View view){ current_position --; if(current_position<0){ current_position = musicList.size()-1; } musicService.serviceChangeMusic(musicList.get(current_position)); play.setText("暂停"); } public void next(View view){ current_position++; if(current_position>=musicList.size()){ current_position = 0; } musicService.serviceChangeMusic(musicList.get(current_position)); play.setText("暂停"); }
第三步:实现滑动条同步音乐播放
优化MainActivity类且在MusicService添加方法
public class MainActivity extends AppCompatActivity { private SeekBar seekBar; private Intent intent; private MusicServiceConnection musicServiceConnection; private MusicService musicService; private List<String> musicList; private int current_position = 0; private Button play; private boolean isFirst = true; private int totalTime; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); seekBar = (SeekBar) findViewById(R.id.seekbar); play = (Button) findViewById(R.id.play); intent = new Intent(this,MusicService.class); startService(intent); musicServiceConnection = new MusicServiceConnection(); musicList = new ArrayList<String>(); SdcardUtils.getAllMp3File(SdcardUtils.getPath(), musicList); for(String music :musicList){ Log.i("music",music); } bindService(intent, musicServiceConnection, BIND_AUTO_CREATE); seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() { @Override public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { if(fromUser){ musicService.seekPosition(progress*totalTime/100); } } @Override public void onStartTrackingTouch(SeekBar seekBar) { } @Override public void onStopTrackingTouch(SeekBar seekBar) { } }); } @Override protected void onDestroy() { super.onDestroy(); unbindService(musicServiceConnection); } class MusicServiceConnection implements ServiceConnection{ @Override public void onServiceConnected(ComponentName name, IBinder service) { MusicService.MyBinder myBinder = (MusicService.MyBinder) service; musicService = myBinder.getService(); } @Override public void onServiceDisconnected(ComponentName name) { } } public void play(View view){ if(isFirst){ //判断是不是第一次点击播放键 musicService.serviceChangeMusic(musicList.get(current_position)); play.setText("暂停"); totalTime = musicService.getTotalTime(); isFirst = false; seekMusicThread(); }else{ String musicState = play.getText().toString(); play.setText("播放".equals(musicState)?"暂停":"播放"); musicService.servicePlay(); } } public void up(View view){ current_position --; if(current_position<0){ current_position = musicList.size()-1; } musicService.serviceChangeMusic(musicList.get(current_position)); play.setText("暂停"); seekMusicThread(); } public void next(View view){ current_position++; if(current_position>=musicList.size()){ current_position = 0; } musicService.serviceChangeMusic(musicList.get(current_position)); play.setText("暂停"); seekMusicThread(); } public void seekMusicThread(){ new Thread(new Runnable() { @Override public void run() { int currentTime = 0; int threadIndex = current_position; while(currentTime<=totalTime){ if(current_position!=threadIndex){ break; } seekBar.setProgress(currentTime*100/totalTime); currentTime = musicService.getCurrentTime(); } } }).start(); } }
public void seekPosition(int position){ mediaPlayer.seekTo(position); } public int getTotalTime(){ return mediaPlayer.getDuration(); } public int getCurrentTime(){ return mediaPlayer.getCurrentPosition(); }