效果圖:
1.獲取本地音樂
2.播放音樂
MediaPlayer 音樂播放類
MediaPlayer其實是一個封裝的很好的音頻、視頻流媒體操作類,如果查看其源碼,會發現其內部是調用的native方法,所以它其實是有C++實現的。
既然是一個流媒體操作類,那么必然涉及到,播放、暫停、停止等操作,實際上MediaPlayer也為我們提供了相應的方法來直接操作流媒體。
- void statr():開始或恢復播放。
- void stop():停止播放。
- void pause():暫停播放。
通過上面三個方法,只要設定好流媒體數據源,即可在應用中播放流媒體資源,為了更好的操作流媒體,MediaPlayer還為我們提供了一些其他的方法,這里列出一些常用的,詳細內容參閱官方文檔。
- int getDuration():獲取流媒體的總播放時長,單位是毫秒。
- int getCurrentPosition():獲取當前流媒體的播放的位置,單位是毫秒。
- void seekTo(int msec):設置當前MediaPlayer的播放位置,單位是毫秒。
- void setLooping(boolean looping):設置是否循環播放。
- boolean isLooping():判斷是否循環播放。
- boolean isPlaying():判斷是否正在播放。
- void prepare():同步的方式裝載流媒體文件。
- void prepareAsync():異步的方式裝載流媒體文件。
- void release ():回收流媒體資源。
- void setAudioStreamType(int streamtype):設置播放流媒體類型。
- void setWakeMode(Context context, int mode):設置CPU喚醒的狀態。
- setNextMediaPlayer(MediaPlayer next):設置當前流媒體播放完畢,下一個播放的MediaPlayer。
一,本地音樂獲取
package com.hejun.music.biz; import android.content.ContentResolver; import android.content.ContentUris; import android.content.Context; import android.content.res.Resources; import android.database.Cursor; import android.database.CursorIndexOutOfBoundsException; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.drawable.BitmapDrawable; import android.graphics.drawable.Drawable; import android.net.Uri; import android.os.ParcelFileDescriptor; import android.provider.MediaStore; import com.hejun.music.R; import com.hejun.music.bean.Song; import java.io.FileDescriptor; import java.io.FileNotFoundException; import java.io.IOException; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Date; import java.util.List; public class SongBIZ { private static SongBIZ songBiz = null; public static SongBIZ getInstangce() { if (songBiz == null) { songBiz = new SongBIZ(); } return songBiz; } public List<Song> getAllMusic(Context context) { List<Song> songs = new ArrayList<>(); Cursor cursor = context.getContentResolver().query(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, new String[]{ MediaStore.Audio.Media._ID, MediaStore.Audio.Media.DISPLAY_NAME, MediaStore.Audio.Media.TITLE, MediaStore.Audio.Media.DURATION, MediaStore.Audio.Media.ARTIST, MediaStore.Audio.Media.ALBUM, MediaStore.Audio.Media.YEAR, MediaStore.Audio.Media.MIME_TYPE, MediaStore.Audio.Media.SIZE, MediaStore.Audio.Media.DATA, MediaStore.Audio.Media.ALBUM_ID, }, MediaStore.Audio.Media.MIME_TYPE + "=? or " + MediaStore.Audio.Media.MIME_TYPE + "=?", new String[]{"audio/mpeg", "audio/x-ms-wma"}, null); if (cursor.moveToFirst()) { Song song = null; do { song = new Song(); // 文件名 song.setFileName(cursor.getString(1)); // 歌曲名 song.setTitle(cursor.getString(2)); // 時長 long time = cursor.getInt(3); SimpleDateFormat simpleDateFormat = new SimpleDateFormat("mm:ss");//12小時制 Date date = new Date(); date.setTime(time); String time1 = simpleDateFormat.format(date); song.setDuration(time1); // 歌手名 song.setSinger(cursor.getString(4)); // 專輯名 song.setAlbum(cursor.getString(5)); song.setAlbumID(cursor.getInt(10)); // 年代 if (cursor.getString(6) != null) { song.setYear(cursor.getString(6)); } else { song.setYear("未知"); } // 歌曲格式 if ("audio/mpeg".equals(cursor.getString(7).trim())) { song.setType("mp3"); } else if ("audio/x-ms-wma".equals(cursor.getString(7).trim())) { song.setType("wma"); } // 文件大小 if (cursor.getString(8) != null) { float size = cursor.getInt(8) / 1024f / 1024f; song.setSize((size + "").substring(0, 4) + "M"); } else { song.setSize("未知"); } // 文件路徑 if (cursor.getString(9) != null) { song.setFileUrl(cursor.getString(9)); } songs.add(song); } while (cursor.moveToNext()); cursor.close(); } return songs; } public Bitmap getAlbumArt(Context context,int album_id) { String mUriAlbums = "content://media/external/audio/albums"; String[] projection = new String[]{"album_art"}; Cursor cur = context.getContentResolver().query(Uri.parse(mUriAlbums + "/" + Integer.toString(album_id)), projection, null, null, null); String album_art = null; if (cur.getCount() > 0 && cur.getColumnCount() > 0) { cur.moveToNext(); album_art = cur.getString(0); } cur.close(); Bitmap bm = null; if (album_art != null) { bm = BitmapFactory.decodeFile(album_art); } else { /* int[] pic = new int[]{ R.drawable.aelbum, R.drawable.first, R.drawable.second, R.drawable.third, }; int i = (int) (Math.random()*4);*/ bm = BitmapFactory.decodeResource(context.getResources(), R.drawable.first); } return bm; } }
Service類
package com.hejun.music; import android.app.Service; import android.content.Intent; import android.media.MediaPlayer; import android.net.Uri; import android.os.Binder; import android.os.Environment; import android.os.IBinder; import android.util.Log; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; public class MusicService extends Service { public MediaPlayer mediaPlayer; private String path; public MusicService() { } @Override public void onCreate() { super.onCreate(); } @Override public int onStartCommand(Intent intent, int flags, int startId) { mediaPlayer = new MediaPlayer(); path = intent.getStringExtra("path"); try { path = intent.getStringExtra("path"); File file = new File(path); FileInputStream fis = new FileInputStream(file); mediaPlayer.setDataSource(fis.getFD()); mediaPlayer.prepare(); mediaPlayer.setLooping(true); // mediaPlayer.start(); } catch (Exception e) { e.printStackTrace(); } return super.onStartCommand(intent, flags, startId); } // 通過 Binder 來保持 Activity 和 Service 的通信 public MyBinder binder = new MyBinder(); public class MyBinder extends Binder { MusicService getService() { return MusicService.this; } } public void play() { Log.e("tag", "play: " + mediaPlayer ); mediaPlayer.start(); } public void pause() { if (mediaPlayer.isPlaying()) { mediaPlayer.pause(); } } public void playOrPause() { if (mediaPlayer.isPlaying()) { mediaPlayer.pause(); } else { mediaPlayer.start(); } } public void stop() { if (mediaPlayer != null) { mediaPlayer.stop(); try { mediaPlayer.reset(); mediaPlayer.setDataSource(path); mediaPlayer.prepare(); mediaPlayer.seekTo(0); } catch (Exception e) { e.printStackTrace(); } } } @Override public boolean onUnbind(Intent intent) { return super.onUnbind(intent); } @Override public IBinder onBind(Intent intent) { return binder; } }
主要播放流程:
啟動activity ---> 獲取歌曲信息-----> 綁定,啟動服務(MediaPlayer加載資源)----->調用MediaPlayer.start()方法