android local music

Add Listing Service Configuration 

<service android:name="music.PlayingMusicServices" android:exported="true" android:enabled="true"/>

Open Service

//播放本地音乐
    public static void playingmusic(int type) {//启动服务,播放音乐
        Intent intent = new Intent(MyApplication.getContext(), PlayingMusicServices.class);
        intent.putExtra(PlayingMusicServices.TYPE, type);
        MyApplication.getContext().startService(intent);//音乐服务
    }

Play music service


/**
 * 播放本地音乐
 */
public class PlayingMusicServices extends Service {
    public static final int PLAT_MUSIC = 1;
    public static final int PAUSE_MUSIC = 2;
    public static final int STOP_MUSIC = 3;
    public static final int CHANGE_MUSIC = 4;
    public static final String TYPE = "type";
    //用于播放音乐等媒体资源
    private MediaPlayer mediaPlayer;
    //标志判断播放歌曲是否是停止之后重新播放,还是继续播放
    public boolean isStop = true;
    public List<Music> musicList = new ArrayList<>();

    /**
     * onBind,返回一个IBinder,可以与Activity交互
     * 这是Bind Service的生命周期方法
     *
     * @param intent
     * @return
     */
    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    //在此方法中服务被创建
    @Override
    public void onCreate() {
        super.onCreate();
        if (mediaPlayer == null) {
            mediaPlayer = new MediaPlayer();
            initSongs();
            //为播放器添加播放完成时的监听器
            /*mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
                @Override
                public void onCompletion(MediaPlayer mp) {
                    //发送广播到MainActivity
                    Intent intent = new Intent();
                    intent.setAction(Url.MUSICRECEIVE);
                    sendBroadcast(intent);
                }
            });*/
        }
    }


    /**
     * 在此方法中,可以执行相关逻辑,如耗时操作
     *
     * @param intent  :由Activity传递给service的信息,存在intent中
     * @param flags   :规定的额外信息
     * @param startId :开启服务时,如果有规定id,则传入startid
     * @return 返回值规定此startservice是哪种类型,粘性的还是非粘性的
     * START_STICKY:粘性的,遇到异常停止后重新启动,并且intent=null
     * START_NOT_STICKY:非粘性,遇到异常停止不会重启
     * START_REDELIVER_INTENT:粘性的,重新启动,并且将Context传递的信息intent传递
     * 此方法是唯一的可以执行很多次的方法
     */
    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        switch (intent.getIntExtra(TYPE, -1)) {
            case PLAT_MUSIC:
                if (isStop) {
                    try {
                        //重置mediaplayer
                        mediaPlayer.reset();
                        //将需要播放的资源与之绑定
                        //mediaPlayer = MediaPlayer.create(this, R.raw.beep);//直接播放文件
                        Random random = new Random();
                        if(null != musicList && musicList.size() > 0){
                            int position = random.nextInt(musicList.size()) + 1;
                            mediaPlayer.setDataSource(musicList.get(position).path);
                            mediaPlayer.prepare(); // 开始播放前的准备工作,加载多媒体资源,获取相关信息
                            mediaPlayer.start();//开始播放
                            //mediaPlayer.setLooping(false);//是否循环播放
                            isStop = false;
                        }else {
                            Toasts.showToast("本地没有发现mp3");
                        }
                    } catch (IOException e) {
                        e.printStackTrace();
                        Toasts.showToast("文件有问题");
                    }
                } else if (!isStop && mediaPlayer != null) {//继续播放
                    mediaPlayer.start();
                    isStop = false;
                }
                break;
            case PAUSE_MUSIC: //播放器不为空,并且正在播放
                if (mediaPlayer != null && mediaPlayer.isPlaying()) {
                    mediaPlayer.pause();
                }
                break;
            case STOP_MUSIC://停止之后要开始播放音乐
                if (mediaPlayer != null) {
                    mediaPlayer.stop();
                    isStop = true;
                }
                break;
            case CHANGE_MUSIC:
                changeMusic();
                break;
        }
        return START_NOT_STICKY;
    }

    /*public class MyBroadCastReceiver extends BroadcastReceiver {
        @Override
        public void onReceive(Context context, Intent intent) {
            isStop = true;//Url.MUSICRECEIVE
        }
    }*/

    private void changeMusic() {
        Random random = new Random();
        if(null != musicList && musicList.size() > 0){
            int position = random.nextInt(musicList.size()) + 1;
            try {
                // 切歌之前先重置,释放掉之前的资源
                mediaPlayer.reset();
                // 设置播放源
                mediaPlayer.setDataSource(musicList.get(position).path);
                // 开始播放前的准备工作,加载多媒体资源,获取相关信息
                mediaPlayer.prepare();
                // 开始播放
                mediaPlayer.start();
            } catch (IOException e) {
                Toasts.showToast(musicList.get(position).path+"文件有问题");
                e.printStackTrace();
            }
        }
    }

    //nitListView()实现对手机中MediaDataBase的扫描
    private void initSongs() {
        musicList.clear();
        //获取ContentResolver的对象,并进行实例化
        ContentResolver resolver = MyApplication.getContext().getContentResolver();
        //获取游标
        Cursor cursor = resolver.query(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, null, null, null, MediaStore.Audio.Media.DEFAULT_SORT_ORDER); //创建游标MediaStore.Audio.Media.EXTERNAL_CONTENT_URI获取音频的文件,后面的是关于select筛选条件,这里填土null就可以了
        //游标归零
        if(cursor.moveToFirst()){
            do {
                String title = cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.TITLE));            //获取歌名
                String artist = cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.ARTIST));         //获取歌唱者
                String album = cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.ALBUM));           //获取专辑名
                int albumID = cursor.getInt(cursor.getColumnIndex(MediaStore.Audio.Media.ALBUM_ID));            //获取专辑图片id
                int length = cursor.getInt(cursor.getColumnIndex(MediaStore.Audio.Media.DURATION));
                String path = cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.DATA));
                //创建Music对象,并赋值
                Music music = new Music();
                music.length = length;
                music.title = title;
                music.artist = artist;
                music.album = album;
                music.path = path;
                //将music放入musicList集合中
                musicList.add(music);
            }  while (cursor.moveToNext());
        }else {
            Toasts.showToast("本地没有音乐哦");
        }
        cursor.close();                                                                         //关闭游标
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        if (mediaPlayer.isPlaying()) {
            mediaPlayer.stop();
        }
        if (mediaPlayer != null) {
            mediaPlayer.stop();
        }
    }
}

Bean class

public class Music {
    /**
     * 在这里所有的属性都是用public修饰的,所以在以后调用时直接调用就可以了
     * 如果用private修饰是需要构建set和get方法
     */
    //歌名
    public String title;
    //歌唱者
    public String artist;
    //专辑名
    public String album;
    public  int length;
    //专辑图片
    public Bitmap albumBip;
    public String path;
    public boolean isPlaying;
}

 

Guess you like

Origin blog.csdn.net/dubo_csdn/article/details/90543652