音乐播放器

读取音乐的外部类

package com.example.day18;

import android.content.ContentResolver;
import android.database.Cursor;
import android.provider.MediaStore;

import java.util.ArrayList;
import java.util.List;

public class Music {
    private static List<sing> list = new ArrayList<>();

    public static List<sing> utile(Main2Activity main2Activity) {
        ContentResolver contentResolver = main2Activity.getContentResolver();

        //通过内容通知者获取对应的数据
        Cursor query = contentResolver.query(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, null, null, null, null);
        while (query.moveToNext()) {
            String tile = query.getString(query.getColumnIndex(MediaStore.Audio.Media.TITLE));
            String name = query.getString(query.getColumnIndex(MediaStore.Audio.Media.ARTIST));
            int duration = query.getInt(query.getColumnIndex(MediaStore.Audio.Media.DURATION));
            String data = query.getString(query.getColumnIndex(MediaStore.Audio.Media.DATA));
            Long size = query.getLong(query.getColumnIndex(MediaStore.Audio.Media.SIZE));

            //将大小小于正常数据的不添加进集合中
            if(size > 1000*800){
                list.add(new sing(tile, name, duration, data, size));
            }
        }
        //关闭这个游标
        query.close();
        return list;
    }

    //让毫秒时间进行类型转换
    public static String formatTime(int time) {
        if (time / 1000 % 60 < 10) {
            return time / 1000 / 60 + ":0" + time / 1000 % 60;
        } else {
            return time / 1000 / 60 + ":" + time / 1000 % 60;
        }

    }
}

将获取的音乐集合填充到适配器

package com.example.day18;

import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.TextView;

import java.util.ArrayList;
import java.util.List;

//让这个外部类设置为对应的适配器,让获取的数据集合填充进对应的listView布局控件中

class MusicApdp extends BaseAdapter {
    private List<sing> list = new ArrayList<>();
    private Main2Activity main2;
    private int i = 0;
    public MusicApdp(Main2Activity main2Activity, List<sing> utile) {
        list.addAll(utile);
        main2 = main2Activity;
    }

    @Override
    public int getCount() {
        return list.size();
    }

    @Override
    public Object getItem(int position) {
        return list.get(position);
    }

    @Override
    public long getItemId(int position) {
        return position;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        VH vh;
        if(convertView == null){
            vh = new VH();
            convertView = LayoutInflater.from(main2).inflate(R.layout.sing,null);
            vh.textView = convertView.findViewById(R.id.bh);
            vh.textView2 = convertView.findViewById(R.id.titles);
            vh.textView3 = convertView.findViewById(R.id.name);
            vh.textView4 = convertView.findViewById(R.id.tion);

            convertView.setTag(vh);
        }else{
            vh = (VH) convertView.getTag();
        }
        vh.textView.setText(String.valueOf(i++));
        vh.textView2.setText(list.get(position).getTilte());
        vh.textView3.setText(list.get(position).getArtist());

        int duration = list.get(position).getDuration();
        String s = Music.formatTime(duration);
        vh.textView4.setText(s);

        return convertView;
    }
    class VH{
        TextView textView;
        TextView textView2;
        TextView textView3;
        TextView textView4;
    }
}

音乐的实体类

package com.example.day18;
//设置对应的实体类
public class sing {
    private String tilte;
    private String artist;
    private int duration;
    private String data;
    private Long size;

    public sing(String tilte, String artist, int duration, String data, Long size) {
        this.tilte = tilte;
        this.artist = artist;
        this.duration = duration;
        this.data = data;
        this.size = size;
    }

    public sing() {
    }


    public String getTilte() {
        return tilte;
    }

    public void setTilte(String tilte) {
        this.tilte = tilte;
    }

    public String getArtist() {
        return artist;
    }

    public void setArtist(String artist) {
        this.artist = artist;
    }

    public int getDuration() {
        return duration;
    }

    public void setDuration(int duration) {
        this.duration = duration;
    }

    public String getData() {
        return data;
    }

    public void setData(String data) {
        this.data = data;
    }

    public Long getSize() {
        return size;
    }

    public void setSize(Long size) {
        this.size = size;
    }
}

对应的音乐播放器逻辑代码

package com.example.day18;

import android.Manifest;
import android.content.pm.PackageManager;
import android.media.MediaPlayer;
import android.support.annotation.NonNull;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.Button;
import android.widget.ListView;
import android.widget.SeekBar;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.Timer;
import java.util.TimerTask;

public class Main2Activity extends AppCompatActivity {

    //布局文件中的ID,需要进行逻辑判断
    private Button play;
    private SeekBar jindu;
    private ListView LV;
    private Button next;
    private Button proty;
    private Button order;



    //在实际应用中,需要利用下列参数进行逻辑判断和运行
    private int post = -1;
    private  boolean first = false;
    private  boolean ord[] = {true,false,false,false};
    private List<sing> utile = new ArrayList<>();

    //在音乐播放器中,必不可少的组件
    private MediaPlayer mediaPlayer;


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

        //将一些变量进行初始化
        play = (Button) findViewById(R.id.play);
        jindu = (SeekBar) findViewById(R.id.jindu);
        LV = (ListView) findViewById(R.id.LV);
        next = (Button) findViewById(R.id.next);
        proty = (Button) findViewById(R.id.proty);
        order = (Button) findViewById(R.id.order);

        //在第一次运行的时候,会通过这条语句对让用户对该应用授权,能够让这个应用读取SD卡中的内容
        requestPermissions(new String[]{Manifest.permission.READ_EXTERNAL_STORAGE,Manifest.permission.WRITE_EXTERNAL_STORAGE},100);

        //初始化音乐播放器组件,让这个组件实例化
        mediaPlayer = new MediaPlayer();


        //通过获取授权后,ListView的监听方法
        LV.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {

                //获取点击的ID,通过这个ID获取对应的集合中的地址,并将这个地址发送给让音乐播放器对这个数据开始准备的方法下
                post = position;
                String data = utile.get(position).getData();
                stat(data);
            }
        });

        //设置播放按钮的点击时间
            play.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {

                    //判断当前点击的状态
                    if(first == false){

                        //将音乐器暂停,更换图标,并更新判断条件
                        mediaPlayer.pause();
                        first = true;
                        play.setBackgroundResource(R.drawable.ic_action_play);
                    }else if (first == true){

                        //将音乐器打开,更换图标,并更新判断条件
                        mediaPlayer.start();
                        first = false;
                        play.setBackgroundResource(R.drawable.ic_action_pause);
                    }

                    //判断处于播放状态
                    if(first == false){
                        Timer timer = new Timer(); //设置计时器
                        timer.schedule(new TimerTask() {
                            @Override
                            public void run() {
                                runOnUiThread(new Runnable() {//打开一个UI线程,让其进行更新UI,解决异常
                                    @Override
                                    public void run() {
                                        jindu.setProgress(mediaPlayer.getCurrentPosition());//更新进度条的UI
                                    }
                                });
                            }
                        },0,1000);//每秒执行1次
                    }
                }
            });

            //进度条的改变监听事件
            jindu.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
                @Override
                public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
                    if (fromUser){//判断是否是用户更改
                        mediaPlayer.seekTo(progress);
                    }
                }

                @Override
                public void onStartTrackingTouch(SeekBar seekBar) {

                }

                @Override
                public void onStopTrackingTouch(SeekBar seekBar) {

                }
            });



            //点击下一首的点击监听事件
            next.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    nextmusic();//调用对应的方法
                }
            });


            //点击上一首的点击监听事件
            proty.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    upmusic();//调用对应的方法
                }
            });

            //当一个音乐播放完毕的时候,设置方法,让其进行下一首
            mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
                @Override
                public void onCompletion(MediaPlayer mp) {
                    mediaPlayer.reset();//将这个音乐播放器格式化(清除当下播放项目)
                    if(ord[2]){//当是单曲循环的时候
                        String data = utile.get(post).getData();//获取对应下标的数据
                        stat(data);//开启音乐播放器,让其加载这个音乐并更新进度条的最大值
                    }else{
                        nextmusic();
                    }
                }
            });

            //更改音乐播放出现问题的时候,设置方法,让其进行下一首
            mediaPlayer.setOnErrorListener(new MediaPlayer.OnErrorListener() {
                @Override
                public boolean onError(MediaPlayer mp, int what, int extra) {
                    nextmusic();
                    return false;
                }
            });

            //监听设置播放顺序的按钮
            order.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {

                    //默认顺序播放
                    if(ord[0]){//顺序播放的情况点击
                        ord[0] = false;//关闭顺序播放的判断条件
                        ord[1] = true;//打开循环播放的判断条件
                        order.setBackgroundResource(R.drawable.ic_action_circle);//更改图标
                    }
                    else if (ord[1]){//循环播放的情况点击
                        ord[1] = false;//关闭循环播放的判断条件
                        ord[2] = true;//打开单曲循环的判断条件
                        order.setBackgroundResource(R.drawable.ic_action_cycle);//更改图标
                    }
                    else if (ord[2]){//单曲循环的情况点击
                        ord[2] = false;//关闭单曲循环的判断条件
                        ord[3] = true;//打开随机播放的判断条件
                        order.setBackgroundResource(R.drawable.ic_action_randoms);//更改图标
                    }
                    else if (ord[3]){//随机播放的情况点击
                        ord[3] = false;//关闭随机播放的判断条件
                        ord[0] = true;//打开顺序播放的判断条件
                        order.setBackgroundResource(R.drawable.ic_action_order);//更改图标
                    }
                }
            });


    }
    //内置不同播放方式的上一首播放方式
    private void upmusic() {
        if(post != -1) {//判断当前是否有歌曲播放
            if(ord[0]){//顺序播放
                if (--post  < 0) {//判断是否是最后一首
                   post = 0;//便于下一首
                }
            }else if(ord[1]){//循环播放
                if (--post < 0) {//正常情况的播放
                    post = utile.size()-1;
                }
            }else if(ord[2]){//单曲循环,点击按钮,需要更换曲目
                if (--post < 0) {//正常情况的播放
                    post = utile.size()-1;
                }
            }else if(ord[3]){//随机播放
                int i = new Random().nextInt(utile.size());//随机生成数据
                post = i;//将这个数据进行设置
            }
                String data = utile.get(post).getData();//获取对应下标的数据
                stat(data);//开启音乐播放器,让其加载这个音乐并更新进度条的最大值
        }
    }

    //内置不同播放方式的下一首播放方式
    private void nextmusic() {
        if(post != -1) {//判断当前是否有歌曲播放
            if(ord[0]){//顺序播放
                if (++post  > utile.size() - 1) {//判断是否是最后一首
                    mediaPlayer.pause();
                    first = true;
                    play.setBackgroundResource(R.drawable.ic_action_play);
                    post--;//便于上一首
                    return;//退出这一个判断
                }
            }else if(ord[1]){//循环播放
                if (++post  > utile.size() - 1) {//正常情况的播放
                    post = 0;
                }
            }else if(ord[2]){//单曲循环,点击按钮,需要更换曲目
                if (++post  > utile.size() - 1) {//正常情况的播放
                    post = 0;
                }
            }else if(ord[3]){//随机播放
                int i = new Random().nextInt(utile.size());//随机生成数据
                post = i;//将这个数据进行设置
            }
                String data = utile.get(post).getData();//获取对应下标的数据
                stat(data);//开启音乐播放器,让其加载这个音乐并更新进度条的最大值
        }
    }

    private void stat(String data) {
        try {

            //将这个音乐播放器格式化(清除当下播放项目)
            mediaPlayer.reset();

            //将获取的对应地址填充进音乐播放器中
            mediaPlayer.setDataSource(data);

            //让这个音乐播放器进入一个准备状态(本地文件基本没有用)
            mediaPlayer.prepareAsync();

            //设置音乐播放器的监听是否准备完成事件
            mediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
                @Override
                public void onPrepared(MediaPlayer mp) {

                    //准备完成

                    //设置进度条的最大值
                    jindu.setMax(mediaPlayer.getDuration());

                    //将这个音乐播放器进行启动
                    mediaPlayer.start();

                    //设置对应的判断图标改动的变量

                    first = false;

                    //通过变量判断是否开启计时器
                    if(first == false){

                        //创建计时器,并利用计时器更新进度条UI
                        Timer timer = new Timer();
                        timer.schedule(new TimerTask() {
                            @Override
                            public void run() {
                                runOnUiThread(new Runnable() {//打开一个UI线程,让其进行更新UI,解决异常
                                    @Override
                                    public void run() {
                                        jindu.setProgress(mediaPlayer.getCurrentPosition());
                                    }
                                });
                            }
                        },0,1000);//等待1秒
                    }

                    //将播放按钮的图标更换
                    play.setBackgroundResource(R.drawable.ic_action_pause);

                }
            });
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    //这个方法,是监听是否获取到了对应的权限
    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);

        //判断权限是否获取
        if(requestCode == 100 && grantResults[0] == PackageManager.PERMISSION_GRANTED){

            //利用外部类写的文件读取本机信息的方法,获取对应的list集合
            utile = Music.utile(this);

            //将这个list集合与外部类自定义的适配器进行对应填充,并将这个ListView添加适配器
            MusicApdp musicApdp = new MusicApdp(this, utile);
            LV.setAdapter(musicApdp);
        }
    }
}


对应的音乐播放器的界面

<?xml version="1.0" encoding="utf-8"?>
<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"
    android:orientation="vertical"
    tools:context=".Main2Activity">

    <ListView
        android:layout_width="match_parent"
        android:layout_height="500dp"
        android:id="@+id/LV">

    </ListView>
    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="100dp"
        android:orientation="vertical">
        <Button
            android:layout_width="50dp"
            android:layout_height="50dp"
            android:id="@+id/play"
            android:layout_above="@id/jindu"
            android:background="@drawable/ic_action_play"
            android:layout_centerHorizontal="true"
            />
        <Button
            android:layout_width="50dp"
            android:layout_height="50dp"
            android:id="@+id/next"
            android:layout_above="@id/jindu"
            android:background="@drawable/ic_action_next"
            android:layout_toRightOf="@id/play"
            />
        <Button
            android:layout_width="50dp"
            android:layout_height="50dp"
            android:id="@+id/proty"
            android:layout_above="@id/jindu"
            android:background="@drawable/ic_action_previous"
           android:layout_toLeftOf="@id/play"
            />

        <Button
            android:layout_width="50dp"
            android:layout_height="50dp"
            android:id="@+id/order"
            android:layout_above="@id/jindu"
            android:layout_alignParentRight="true"
            android:background="@drawable/ic_action_order"
            />

        <ImageView
            android:layout_width="80dp"
            android:layout_height="80dp"
            android:background="@drawable/header"
            />

        <SeekBar
            android:layout_width="match_parent"
            android:layout_alignParentRight="true"
            android:layout_height="wrap_content"
            android:id="@+id/jindu"
            android:layout_alignParentBottom="true"
            />
    </RelativeLayout>


</LinearLayout>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值