【项目】音乐播放器

效果图:

先完成布局和播放功能

<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();
    }

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值