android 第三次作业

android studio音乐播放器

 

一、实现功能:

1.读取本地SD中的所有音频文件

2.歌单列表展示,并显示音频具体信息

3.进度条显示当前播放进度,可滑动加速

4.点击歌单进行播放

5.实现暂停、播放、下一曲、上一曲

二、页面截图:

 


。。。。。。。。。。。。。。。。。。

三、关键代码实现

1.首先获取从SD卡中读取本地文件的权限:

<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

2.Android系统会在SD卡有更新的时候自动将SD卡文件分类并存入SQLite数据库,而我们要做的只是像正常读取数据库一样去读数据库的信息

新建MusicMedia类进行详细信息的保存:

package com.example.pc.music;

public class MusicMedia {
    private int id;
    private String title;
    private String artist;
    private String url;
    private String time;
    private String size;
    private int albumId;
    private String album;

在主类中获取详细信息

  /*加载媒体库里的音频*/
    public ArrayList<MusicMedia> scanAllAudioFiles(){
        //生成动态数组,并且转载数据
        ArrayList<MusicMedia> mylist = new ArrayList<MusicMedia>();
        Cursor cursor = getContentResolver().query(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, null, null, null, MediaStore.Audio.Media.DEFAULT_SORT_ORDER);
        //遍历媒体数据库
        if(cursor.moveToFirst()){
            while (!cursor.isAfterLast()) {
             //歌曲标题
                String tilte = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.TITLE));
              //歌曲的歌手名: MediaStore.Audio.Media.ARTIST
                String artist = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.ARTIST));
               //歌曲的总播放时长 :MediaStore.Audio.Media.DURATION
                int duration = cursor.getInt(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.DURATION));
                //歌曲文件的大小 :MediaStore.Audio.Media.SIZE
                Long size = cursor.getLong(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.SIZE));
                if (size >1024*800){//大于800K
                    MusicMedia musicMedia = new MusicMedia();
                    musicMedia.setId(id);
                    musicMedia.setArtist(artist);
                    musicMedia.setSize(size);
                    musicMedia.setTitle(tilte);
                    musicMedia.setTime(duration);
                    musicMedia.setUrl(url);
                    musicMedia.setAlbum(album);
                    musicMedia.setAlbumId(albumId);

                    mylist.add(musicMedia);

                }
                cursor.moveToNext();
            }
        }
        return mylist;
    }

 3.使用MediaPlayer进行点击播放:使用mediaplayer传一个地址过去,这些信息在刚读取音频的方法里都有,传一个地址过去使用一个service先播放起来

musicListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                //点击播放音乐,不过需要判断一下当前是否有音乐在播放,需要关闭正在播放的
            
                currentposition = position;
                player(currentposition);
            }
        });

新建service

<service
            android:name=".MusicPlayerService"
            android:enabled="true"
            android:exported="true">
            <intent-filter >
                <action android:name="player"></action>
            </intent-filter>
        </service>

4.进度条显示当前进度:service使用静态的变量,activity里也是使用静态的变量,然后开一个线程,1s更新一次状态,在service里直接修改seekbar

public class MusicPlayerService extends Service implements Runnable {
    private static final String TAG = "MusicPlayerService";
    private static final int NOTIFICATION_ID = 1; // 如果id设置为0,会导致不能设置为前台service
    public static MediaPlayer mediaPlayer = null;
    private String url = null;
    private String MSG = null;
    private static int curposition;//第几首音乐
    private musicBinder musicbinder = null;
    private int currentPosition = 0;// 设置默认进度条当前位置
    public MusicPlayerService() {
        Log.i(TAG,"MusicPlayerService......1");
        musicbinder = new musicBinder();
    }
    //通过bind 返回一个IBinder对象,然后改对象调用里面的方法实现参数的传递
    @Override
    public IBinder onBind(Intent intent) {
        Log.i(TAG,"onBind......");
       return null;
    }
   
   
    @Override
    public void onCreate() {
        Log.i(TAG, "onCreate......2");
        super.onCreate();
        if (mediaPlayer == null) {
           /* mediaPlayer.reset();
            mediaPlayer.release();
            mediaPlayer = null;*/
            mediaPlayer = new MediaPlayer();
        }
         // 监听播放是否完成
        mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
            @Override
            public void onCompletion(MediaPlayer mp) {
             
            }
        });
 
 
 
    }
 
    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Log.i(TAG, "onStartCommand......3");
        // /storage/emulated/0/Music/Download/Selena Gomez - Revival/Hands to Myself.mp3
        if(intent != null){
            MSG = intent.getStringExtra("MSG");
            if(MSG.equals("0")){
                url = intent.getStringExtra("url");
                Log.i(TAG, url + "......." + Thread.currentThread().getName());
                palyer();
            }else if(MSG.equals("1")){
                mediaPlayer.pause();
            }else if(MSG.equals("2")){
                mediaPlayer.start();
            }
 
        }
 
        return super.onStartCommand(intent, flags, startId);
    }
 
 
    private void palyer() {
        Log.i(TAG,"palyer......");
        
        //用户在暂停是点击其他的音乐,所以不管当前状态,都重置一下
        //下面这段代码可以实现简单的音乐播放
        try {
//            Log.i(TAG,"palyer......new....");
            mediaPlayer.reset();
 
            mediaPlayer.setDataSource(url);
            mediaPlayer.setLooping(true);
//            mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
            mediaPlayer.prepare();
            mediaPlayer.start();
            // 设置进度条最大值
           MusicActivity.audioSeekBar.setMax(mediaPlayer.getDuration());
            //开启新线程
            new Thread(this).start();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    // 刷新进度条 ,时间
 
    @Override
    public void run() {
 
        Log.i(TAG,Thread.currentThread().getName()+"......run...");
 
        int total = mediaPlayer.getDuration();// 总时长
        while (mediaPlayer != null && currentPosition < total) {
            try {
                Thread.sleep(1000);
                if (mediaPlayer != null) {
                    currentPosition = mediaPlayer.getCurrentPosition();
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            MusicActivity.audioSeekBar.setProgress(CurrentPosition);
        }
    }
    @Override
    public void onDestroy() {
        Log.i(TAG,"onDestroy......");
        super.onDestroy();
        if (mediaPlayer != null) {
            mediaPlayer.stop();
            mediaPlayer.release();
            mediaPlayer = null;
        }
        //关闭线程
        Thread.currentThread().interrupt();
        stopForeground(true);
    }
    public String toTime(int time){
        time /= 1000;
        int minute = time / 60;
        int hour = minute / 60;
        int second = time % 60;
        minute %= 60;
        return String.format("%02d:%02d", minute, second);
    }
}

还有一些播放按钮点击更改样式、判断在第一首或最后一首时点击上一首或下一首的提示等功能

四、coding链接:

https://coding.net/u/dsy1600802076/p/android3/git

 

五:APK下载:

apk下载

 

 六:录屏链接:

手机录屏已上传至优酷

 由于未知原因,上传后声音不同步,有点遗憾。

 

 

 

posted @ 2018-12-11 20:58  你总猜错  阅读(393)  评论(0编辑  收藏  举报