基于Service的音乐播放器

效果

在这里插入图片描述

代码

Service.java

public class MusicFunctionService extends Service {

    public ArrayList<String> musicList = null;
    public ArrayList<Song> songs = new ArrayList<>();
    public MediaPlayer mediaPlayer;
    public Handler handler;
    private SeekBar seekBar;
    public int type = 1;
    public int current = 0;


    public class MusicBinder extends Binder{
        public MusicFunctionService get(){
            return MusicFunctionService.this;
        }
    }

    @Override
    public void onCreate() {
        super.onCreate();
        handler = new Handler();
        seekBar = MediaPlayerTestActivity.seekBar;
        initDate();
    }

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return new MusicBinder();
    }

    public void initDate(){
        musicList = new ArrayList<>();
        if(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){
            File file0 = Environment.getExternalStorageDirectory();
            File[] files = file0.listFiles(); //所有的文件和文件夹
            for(int i = 0;i<files.length;i++){
                if(files[i].isFile() && files[i].getName().endsWith(".mp3")){
                    musicList.add(files[i].getAbsolutePath());
                }
            }
        }
    }

    public void playMusic(String path){

        if(mediaPlayer != null && mediaPlayer.isPlaying()){
            stopMusic();
        }
        if(mediaPlayer == null){
            try {
                mediaPlayer = new MediaPlayer();
                mediaPlayer.setDataSource(path);
                mediaPlayer.prepareAsync();
                mediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
                    @Override
                    public void onPrepared(MediaPlayer mp) {
                        mediaPlayer.start();
                        //最大值
                        seekBar.setMax(mediaPlayer.getDuration());
                        //进度条要移动多次 while() 子线程  每隔多久 sleep()
                        Thread t = new Thread(){
                            @Override
                            public void run() {
                                super.run();

                                if(mediaPlayer!= null && mediaPlayer.isPlaying()){
                                    seekBar.setProgress(mediaPlayer.getCurrentPosition());
                                    handler.postDelayed(this,1000);
                                }
                            }
                        };
                        handler.post(t);
                    }
                });
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        else {
            mediaPlayer.start();
        }

        //监听音乐播放完
        mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
            @Override
            public void onCompletion(MediaPlayer mp) {
                if(mediaPlayer != null)
                    stopMusic();

                switch (type){
                    case 1:
                        if(current < musicList.size() -1){
                            playMusic(musicList.get(++current));
                        }
                        else
                            playMusic(musicList.get(current));
                        break;
                    case 2:
                        int index = new Random().nextInt(musicList.size()-1);//0-3
                        playMusic(musicList.get(index));
                        break;
                    case 3:
                        playMusic(musicList.get(current));
                        break;
                }
            }
        });
    }

    public void stopMusic(){
        mediaPlayer.stop();
        mediaPlayer.release();
        mediaPlayer = null;
    }

    public void pauseMusic(){
        if(mediaPlayer != null && mediaPlayer.isPlaying()){
            mediaPlayer.pause();
        }
    }
}

Activity.java

public class MediaPlayerTestActivity extends AppCompatActivity {


    private ListView listView;
    public static SeekBar seekBar;
    public MusicFunctionService mService;
    public Intent intent;
    public static final int ORDER_PLAY= 1;
    public static final int RANDOM_PLAY= 2;
    public static final int LOOPING_PLAY= 3;

    ServiceConnection connection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            mService = ((MusicFunctionService.MusicBinder)service).get();
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {

        }
    };


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_media_player_test);

        listView = findViewById(R.id.list_music);
        seekBar = findViewById(R.id.pro1);

        if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M){
            requestPermissions(new String[]{Manifest.permission.READ_EXTERNAL_STORAGE,
                    Manifest.permission.WRITE_EXTERNAL_STORAGE},100);
        }

        intent = new Intent(this,MusicFunctionService.class);
        bindService(intent,connection,BIND_AUTO_CREATE);
    }

    public void init(){
        //listView 适配器有三种:ArrayAdapter(1个TextView)  simpleAdapte  baseAdapter
        ArrayAdapter<String> arrayAdapter = new ArrayAdapter<String>(this,R.layout.support_simple_spinner_dropdown_item,mService.musicList);
        listView.setAdapter(arrayAdapter);

        listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                String musicPath = mService.musicList.get(position);
                mService.current = position;
                //播放
                mService.playMusic(musicPath);
            }
        });

        seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
            @Override
            public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
                //fromUser 是否为用户用滑动的
                if(mService.mediaPlayer != null && mService.mediaPlayer.isPlaying() && fromUser == true){
                    mService.mediaPlayer.seekTo(progress); //手动改动播放进度
                }
            }

            @Override
            public void onStartTrackingTouch(SeekBar seekBar) {

            }

            @Override
            public void onStopTrackingTouch(SeekBar seekBar) {

            }
        });
    }

    public void play(View view) {

    }

    public void pause(View view) {
        //正在播放
        mService.pauseMusic();
    }

    public void stop(View view) {
        if(mService.mediaPlayer != null && mService.mediaPlayer.isPlaying())
            mService.stopMusic();
    }

    //循环播放
    public void circular(View view) {
        mService.type = Type.LOOPING_PLAY.index;
    }

    //顺序播放
    public void orderPlay(View view) {
        mService.type = Type.ORDER_PLAY.index;
    }

    public void randomPlay(View view) {
        mService.type = Type.RANDOM_PLAY.index;
    }

    public void next(View view) {
    }

    public void loadDate(View view){
        init();
    }
}

布局

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MediaPlayerTestActivity"
    android:orientation="vertical">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal">

        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="上一首"
            android:onClick="next"/>

        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="暂停"
            android:onClick="pause"/>

        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="停止"
            android:onClick="stop"/>
        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="下一首"/>
    </LinearLayout>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="单曲循环"
            android:onClick="circular"/>

        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="顺序播放"
            android:onClick="orderPlay"/>


        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="随机播放"
            android:onClick="randomPlay"/>
        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:onClick="loadDate"
            android:text="获取数据"/>

    </LinearLayout>

   <SeekBar
       android:id="@+id/pro1"
       android:layout_width="match_parent"
       android:layout_height="wrap_content"
       android:layout_marginTop="10dp"/>

    <ListView
        android:id="@+id/list_music"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
    </ListView>
</LinearLayout>

清单文件

<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    
<service android:name=".service.MusicFunctionService" />
  • 0
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值