Android之简易音乐播放器,MediaPlayer的使用

 

当前实现的音乐播放器的功能有:获取本地音乐、音乐播放、暂停、歌曲切换、进度条显示、进度条控制播放位置等基本功能

主要使用了:RecyclerView显示音乐列表

MediaPlayer播放音乐

SeekBar显示进度条并控制音乐进度

ContentProvider获取本地音乐

完成后效果如下:

 Android之简易音乐播放器,MediaPlayer的使用_第1张图片

 

MainActivity.class

 

 

   
public class MainActivity extends AppCompatActivity implements View.OnClickListener,        SeekBar.OnSeekBarChangeListener, MediaPlayer.OnCompletionListener {    private MediaPlayer mediaPlayer;    private MusicAdapter musicAdapter;//recyclerView的适配器,用于显示音乐列表    private List musicList;    private AppCompatSeekBar seekBar;    private TextView timeStart, timeEnd;    private int mPosition = -1;//定位当前播放的音乐    private Button playB;//播放、暂停Button    @SuppressLint("HandlerLeak")    private Handler handler = new Handler(new Handler.Callback() {  //在这里实现seekBar的动态更新        @Override        public boolean handleMessage(Message message) {            seekBar.setProgress(mediaPlayer.getCurrentPosition());            timeStart.setText(parseDate(mediaPlayer.getCurrentPosition()));            updateProgress();//发送更新seekBar的消息            return true;        }    });    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        requestPermission();//获取权限,6.0之后读文件被设为危险权限,需要运行时请求        initView();        queryMusic();    }    private void requestPermission() {        if (ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {            ActivityCompat.requestPermissions(MainActivity.this, new String[]{                    Manifest.permission.WRITE_EXTERNAL_STORAGE}, 1);        }    }    @Override    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {        if (requestCode == 1) {            if (grantResults.length > 0 && grantResults[0] != PackageManager.PERMISSION_GRANTED) {                Toast.makeText(this, "拒绝权限将无法正常使用程序!", Toast.LENGTH_SHORT).show();                finish();            }        }    }    @Override//退出程序时要销毁mediaPlayer    protected void onDestroy() {        super.onDestroy();        if (mediaPlayer != null) {            mediaPlayer.stop();            mediaPlayer.release();        }    }    private void initView() {        timeStart = findViewById(R.id.time_start);        timeEnd = findViewById(R.id.time_end);        seekBar = findViewById(R.id.seek_bar);        seekBar.setOnSeekBarChangeListener(this);        playB = findViewById(R.id.music_play);        Button lastB = findViewById(R.id.last_music);        Button nextB = findViewById(R.id.next_music);        playB.setOnClickListener(this);        lastB.setOnClickListener(this);        nextB.setOnClickListener(this);        //初始化RecyclerView        final RecyclerView musicListView = findViewById(R.id.music_list);        musicList = new ArrayList<>();        musicListView.setLayoutManager(new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false));        musicAdapter = new MusicAdapter(musicList);        musicListView.setAdapter(musicAdapter);        musicAdapter.setSelected(-1);        musicAdapter.setOnItemClickListener(new MusicAdapter.OnItemClickListener() {            @Override            public void onItemClick(View v, int position) {                changeMusic(position);                mPosition = position;            }        });        musicListView.addItemDecoration(new DividerItemDecoration(this, DividerItemDecoration.VERTICAL));    }    private void queryMusic() {        //通过Cursor找出本地音乐文件(MP3)        Cursor cursor = getContentResolver().query(                MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, null, null, null,                MediaStore.Audio.Media.DEFAULT_SORT_ORDER);        if (cursor != null) {            musicList.clear();            while (cursor.moveToNext()) {                //从属性名很容易看出所代表的音乐文件属性,所以一下属性不做讲解了                String id = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media._ID));                String title = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.TITLE));                String singer = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.ARTIST));                String album = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.ALBUM));                String path = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.DATA));                int time = cursor.getInt(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.DURATION));                int size = cursor.getInt(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.SIZE));                //myMusic是我自己定义的一个javaBean,用来存放音乐文件                MyMusic myMusic = new MyMusic(id, title, singer, path, size, time, album);                musicList.add(myMusic);            }            musicAdapter.notifyDataSetChanged();        }    }    //每秒发送一个空的message,提示handler更新    private void updateProgress() {        handler.sendMessageDelayed(Message.obtain(), 1000);    }    //音乐播放    private void playMusic(MyMusic myMusic) {        try {            if (mediaPlayer == null) {  //判断是否为空,避免重复创建                mediaPlayer = new MediaPlayer();                mediaPlayer.setOnCompletionListener(this);            }            mediaPlayer.reset();//播放前重置播放器,其实第一次播放时不需要做此操作,但为了这一方法复用性我选择在这里使用            mediaPlayer.setDataSource(myMusic.getPath());//设置播放源            mediaPlayer.prepare();//准备,这一步很关键,在新播放一首歌的时候必不可少            mediaPlayer.start();//开始播放            timeEnd.setText(parseDate(mediaPlayer.getDuration()));//用来显示音乐时长            seekBar.setMax(mediaPlayer.getDuration());//设置seekBar的时长与音乐文件相同            updateProgress();//开启seekBar的更新        } catch (IOException e) {            e.printStackTrace();        }    }    private String parseDate(int time) {//cursor获取的时间是毫秒,这里将它转成常用的时间格式        time = time / 1000;        int min = time / 60;        int second = time % 60;        return min + ":" + second;    }    private void changeMusic(int position) {    //实现歌曲的切换        if (position < 0) {            mPosition = musicList.size() - 1;            playMusic(musicList.get(mPosition));        } else if (position > musicList.size() - 1) {            mPosition = 0;            playMusic(musicList.get(0));        } else {            playMusic(musicList.get(position));        }        musicAdapter.setSelected(mPosition);    //设置选中音乐        //更新RecyclerView,有这一步的原因是我设置了两个布局,正在播放的音乐行布局变更        musicAdapter.notifyDataSetChanged();        playB.setBackgroundResource(R.drawable.ic_playing); //更新播放、暂停键的图标    }    private void startOrPause() {   //播放或暂停逻辑实现        if (mediaPlayer.isPlaying()) {            mediaPlayer.pause();            playB.setBackgroundResource(R.drawable.ic_pause);        } else {            mediaPlayer.start();            playB.setBackgroundResource(R.drawable.ic_playing);        }    }    @Override    public void onClick(View view) {        switch (view.getId()) {            case R.id.last_music:   //上一首                changeMusic(--mPosition);                break;            case R.id.music_play:   //播放/暂停                if (mediaPlayer == null) {                    changeMusic(0);                } else {                    startOrPause();                }                break;            case R.id.next_music://下一首                changeMusic(++mPosition);                break;        }    }    //下面三个方法是OnSeekBarChangeListener需重写的方法,此处只需重写第三个    @Override    public void onProgressChanged(SeekBar seekBar, int i, boolean b) {    }    @Override    public void onStartTrackingTouch(SeekBar seekBar) {    }    @Override    public void onStopTrackingTouch(SeekBar seekBar) {        mediaPlayer.seekTo(seekBar.getProgress());//将音乐定位到seekBar指定的位置        updateProgress();    }    @Override    public void onCompletion(MediaPlayer mediaPlayer) { //OnCompletionListener 重写方法,实现轮播效果        changeMusic(++mPosition);    }}

   

MusicAdapter.class
public class MusicAdapter extends RecyclerView.Adapter implements View.OnClickListener {    private int selected;    private List musicList;    private OnItemClickListener onItemClickListener;    private Context mContext;    @Override    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {        mContext=parent.getContext();        View view = LayoutInflater.from(mContext).inflate(R.layout.item_music_content, parent, false);        ViewHolder holder = new ViewHolder(view);        view.setOnClickListener(this);        return holder;    }    @Override    public void onBindViewHolder(ViewHolder holder, int position) {        MyMusic music = musicList.get(position);        holder.content.removeAllViews();        if (position==selected){            holder.content.addView(addFocusView());            TextView textView=holder.content.findViewById(R.id.music_playing);            textView.setText("正在播放:"+music.getName());        }else{            holder.content.addView(addNormalView());            TextView musicName=holder.content.findViewById(R.id.music_name);            TextView musicSinger=holder.content.findViewById(R.id.music_singer);            musicName.setText(music.getName());            musicSinger.setText(music.getSinger());        }        holder.itemView.setTag(position);    }    @Override    public int getItemCount() {        return musicList.size();    }    @Override    public void onClick(View view) {        if (onItemClickListener != null) {            onItemClickListener.onItemClick(view, (Integer) view.getTag());        }    }    class ViewHolder extends RecyclerView.ViewHolder {        RelativeLayout content;        ViewHolder(View itemView) {            super(itemView);            content=itemView.findViewById(R.id.content);        }    }    private View addFocusView(){        return LayoutInflater.from(mContext).inflate(R.layout.item_music_focus,null,false);    }    private View addNormalView(){        return LayoutInflater.from(mContext).inflate(R.layout.item_music_list,null,false);    }    public void setSelected(int selected) {        this.selected = selected;    }    public MusicAdapter(List musicList) {        this.musicList = musicList;    }    public void setOnItemClickListener(OnItemClickListener onItemClickListener) {        this.onItemClickListener = onItemClickListener;    }    public interface OnItemClickListener {        void onItemClick(View v, int position);    }}

更多相关文章

  1. Android 代码混淆及反编译方法
  2. android传值方法之一
  3. android实现app通过jni调用C/C++方法
  4. android为按钮添加事件的三种方法
  5. Android在初始化时弹出popwindow的方法 .
  6. android开发环境搭建最新方法
  7. Android自定义属性 及 TypedArray的使用方法
  8. android程序退出当前activity的方法

随机推荐

  1. IntentService解析
  2. ANDROID 一键搞定JNI创建C头文件
  3. Android返回键的捕捉与完全退出
  4. Android中ViewPager的简单使用(底部圆点)
  5. Android(安卓)self_adaption of screen
  6. Android中不混淆类中函数
  7. 【android】/storage/sdcard, /sdcard, /mn
  8. Android(安卓)MVVM+DataBinding结合Dagge
  9. 全志A10平板电脑安装ubuntu 10.04LTS(与An
  10. 安卓开发_浅谈Android动画(二)