最近一直在看android媒体播放的MediaPlayer类,本来以为用MediaPlayer的几个方法就可以完成基本音乐播放的功能了,然并卵,其中有好多需要自己去思考完善的,待我一一道来。
一.在手机的SOLitaDatebase中获取音频文件
要实现手机音乐播放的功能,首先要扫描手机数据库中的音频文件,这就要用到Cursor了,用它来存储音频文件,关于Cursor的用用法这里不做过多解释,像多了解的直接百度,通过SQLiteDatabase中的query方法来获取,query有5个参数Uri uri,String [] projection,String selection,String []selectionargs,sortOrder,这里边最重要的就是Uri了,它是一个明确的量,MediaStore.Audio.Media.EXTERNAL_CONTENT_URI然后sortOred就是通过那种顺序来获取,有时间,大小,等,大家可以按照自己需要去选择。其它的可以不去用它,一般直接赋null。下面附上代码。
public class MusicLoader { public List<Song> musicList = new ArrayList<Song>(); private ContentResolver contentResolver; private Uri contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI; private String projection[]={ MediaStore.Audio.Media._ID, MediaStore.Audio.Media.DISPLAY_NAME, MediaStore.Audio.Media.DATA, MediaStore.Audio.Media.ALBUM, MediaStore.Audio.Media.ARTIST, MediaStore.Audio.Media.DURATION, MediaStore.Audio.Media.SIZE, }; private String sortOrder =MediaStore.Audio.Media.ARTIST; public Cursor Loader(ContentResolver context){ contentResolver = context; Cursor cursor = contentResolver.query(contentUri, projection, null, null, sortOrder); if(cursor.equals(null)){ System.out.println("There is no songs"); } else if(!cursor.moveToFirst()){ System.out.println("False"); } else{ int disPlayNameCol = cursor.getColumnIndex(MediaStore.Audio.Media.DISPLAY_NAME); int albumCol = cursor.getColumnIndex(MediaStore.Audio.Media.ALBUM); int idCol = cursor.getColumnIndex(MediaStore.Audio.Media._ID); int timeCol = cursor.getColumnIndex(MediaStore.Audio.Media.DURATION); int sizeCol = cursor.getColumnIndex(MediaStore.Audio.Media.SIZE); int artistCol = cursor.getColumnIndex(MediaStore.Audio.Media.ARTIST); int uriCol = cursor.getColumnIndex(MediaStore.Audio.Media.DATA); do{ String Title = cursor.getString(disPlayNameCol); String Album = cursor.getString(albumCol); double Id = cursor.getDouble(idCol); double Time = cursor.getDouble(timeCol); double Size = cursor.getDouble(sizeCol); String Artist = cursor.getString(artistCol); String Uri = cursor.getString(uriCol); Song song = new Song(Id,Title,Artist,Album); song.setMusicid(Id); song.setMusictime(Time); song.setMusicSize(Size); song.setMusicUri(Uri); song.setMusicName(Title); song.setMusicAlbum(Album); song.setMusicArtist(Artist); musicList.add(song); } while(cursor.moveToNext()); } return contentResolver.query(contentUri, projection, null, null, sortOrder); } public MusicLoader(){} public List<Song> getMusicList(){ return musicList; } public String getUri(Cursor cursor,int pos) { cursor.moveToPosition(pos); String uri = cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.DATA)); return uri; } public int playNextMusic(int count,int pos,List list){ if(count == 1||count == 2){ if(pos == list.size()){ pos = 0; }else { pos++; } }else { pos = (int) (Math.random() * list.size()); } return pos; } public void play(Intent intent){ String uri; if(MusicService.mp != null && intent.getStringExtra("play").equals("play")){ if (MusicService.mp.isPlaying()) { MusicService.mp.pause(); } else { MusicService.mp.start(); } }else { try { if (null != MusicService.mp) { MusicService.mp.release(); } MusicService.mp = new MediaPlayer(); uri = intent.getStringExtra("uri"); MusicService.mp.setDataSource(uri); MusicService.mp.prepare(); } catch (IOException e) { e.printStackTrace(); } MusicService.mp.start(); } } }
通过上面的操作就可以把手机里的音频文件添加到musicList这个集合中了(要事先把歌曲Song的这个类封装好)。
public class Song { private double musicId; private double musicTime; private double musicSize; private String musicUri; private String musicName; private String musicArtist; private String musicAlbum; public Song(double id, String musicName, String musicArtist,String musicAlbum){ this.musicId = id; this.musicName = musicName; this.musicArtist = musicArtist; this.musicAlbum = musicAlbum; } public double getMusicid(){ return musicId; } public double getMusictime(){ return musicTime; } public double getMusicSize(){ return musicSize; } public String getMusicUri(){ return musicUri; } public String getMusicName(){ return musicName; } public String getMusicArtist(){ return musicArtist; } public String getMusicAlbum() { return musicAlbum; } public void setMusicid(double musicIdd){ this.musicId = musicId; } public void setMusictime(double musictime){ this.musicTime = musictime; } public void setMusicSize(double musicSize){ this.musicSize = musicSize; } public void setMusicUri(String musicUri){ this.musicUri = musicUri; } public void setMusicName(String musicName){ this.musicName = musicName; } public void setMusicArtist(String musicArtist){ this.musicArtist = musicArtist; } public void setMusicAlbum(String musicAlbum) { this.musicAlbum = musicAlbum; } }
二.以列表的形式把歌曲显示出
前边已经把音频文件存放到musicList这个集合中了,现在就要把它们显示在列表中,这就要用到Adapter类了,直接上代码。
public class Adapter extends BaseAdapter { private List<Song> musicList; private LayoutInflater inflater; public Adapter (Context context,List<Song> musicList){ this.musicList = musicList; this.inflater =LayoutInflater.from(context); } @Override public int getCount() { return musicList.size(); } @Override public Object getItem(int position) { return musicList.get(position); } @Override public long getItemId(int position) { return position; } @Override public View getView(int position, View convertView, ViewGroup parent) { Song song = musicList.get(position); LinearLayout listView = (LinearLayout)inflater.inflate(R.layout.local,null); TextView musicName = (TextView)listView.findViewById(R.id.musicName); musicName.setText(song.getMusicName()); TextView musicArtist = (TextView)listView.findViewById(R.id.musicArtist); musicArtist.setText(song.getMusicArtist()); return listView; } } public class Local extends Activity { public int pos; public long count; public View v; public String Uri; public Button pause; public Button next; public Button disPlay; public Cursor cursor; public ListView listView; MusicLoader ML = new MusicLoader(); @TargetApi(Build.VERSION_CODES.JELLY_BEAN) protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); requestWindowFeature(Window.FEATURE_NO_TITLE); setContentView(R.layout.listview); pause = (Button)findViewById(R.id.pause); if(MusicService.mp != null){ if(MusicService.mp.isPlaying()){ pause.setBackground(getResources().getDrawable(R.drawable.pause)); }else{ pause.setBackground(getResources().getDrawable(R.drawable.play)); } } cursor = ML.Loader(getContentResolver()); disPlay = (Button)findViewById(R.id.display); next = (Button)findViewById(R.id.next); Listener listener = new Listener(); disPlay.setOnClickListener(listener); pause.setOnClickListener(listener); next.setOnClickListener(listener); listView = (ListView) findViewById(R.id.lv); ListListener listListener = new ListListener(); listView.setOnItemClickListener(listListener); Adapter adapter = new Adapter(getApplicationContext(), ML.getMusicList()); listView.setAdapter(adapter); } public class ListListener implements AdapterView.OnItemClickListener { @TargetApi(Build.VERSION_CODES.JELLY_BEAN) public void onItemClick(AdapterView<?> parent, View view, int position, long id){ /* int musicName = cursor.getColumnIndex(MediaStore.Audio.Media.DISPLAY_NAME); int artist = cursor.getColumnIndex(MediaStore.Audio.Media.ARTIST); */ pause.setBackground(getResources().getDrawable(R.drawable.pause)); v = view; pos = position; count = id; Uri = ML.getUri(cursor,pos); Intent intent = new Intent(Local.this, MusicService.class); intent.putExtra("uri", Uri); intent.putExtra("play","pause"); if(MusicService.mp != null){ if(MusicService.mp.isPlaying()){ MusicService.mp.stop(); } } startService(intent); } } public class Listener implements View.OnClickListener { @TargetApi(Build.VERSION_CODES.JELLY_BEAN) @Override public void onClick(View v) { if (v.getId() == R.id.display) { disPlay.setBackgroundColor(1); Intent intent = new Intent(Local.this, Play.class); startActivity(intent); } if (v.getId() == R.id.pause) { int pos = (int) (Math.random() * ML.getMusicList().size()); Uri = ML.getUri(cursor, pos); Intent intent = new Intent(Local.this, MusicService.class); intent.putExtra("uri", Uri); intent.putExtra("pos", pos); intent.putExtra("play", "play"); if (MusicService.mp != null) { if (MusicService.mp.isPlaying()) { v.setBackground(getResources().getDrawable(R.drawable.play)); } else { v.setBackground(getResources().getDrawable(R.drawable.pause)); } } else v.setBackground(getResources().getDrawable(R.drawable.pause)); startService(intent); } if (v.getId() == R.id.next) { pause.setBackground(getResources().getDrawable(R.drawable.pause)); pos = ML.playNextMusic(Play.getCount(), pos, ML.getMusicList()); Uri = ML.getUri(cursor, pos); Intent intent = new Intent(Local.this, MusicService.class); intent.putExtra("uri", Uri); intent.putExtra("pos", pos); intent.putExtra("play", "pause"); if (MusicService.mp != null) { MusicService.mp.stop(); } startService(intent); } } } }
三.接下来就是播放了,最激动的时候
播放这里一定尽量用Service实现,不然当你退出程序时,它就不会播放了。
public class MusicService extends Service { public static MediaPlayer mp; public Intent intent; MusicLoader ML = new MusicLoader(); String uri = null; Message message = new Message(); Cursor cursor; int pos = 0; android.os.Handler handler = new android.os.Handler() { @Override public void handleMessage(Message msg) { super.handleMessage(msg); int i = (int)msg.obj ; if(i == 1){ ML.play(intent); if (mp.getDuration() == mp.getCurrentPosition()) { cursor = ML.Loader(getContentResolver()); pos = ML.playNextMusic(Play.getCount(),intent.getIntExtra("pos",pos),ML.getMusicList()); uri = ML.getUri(cursor,pos); message.obj = 1; handler.sendMessage(message); } } } }; public IBinder onBind(Intent intent) { return null; } public void onCreate(){ super.onCreate(); } @TargetApi(Build.VERSION_CODES.JELLY_BEAN) public int onStartCommand(Intent intent,int flags,int startId){ this.intent = intent; ML.play(intent); if (mp.getDuration() == mp.getCurrentPosition()) { cursor = ML.Loader(getContentResolver()); pos = ML.playNextMusic(Play.getCount(),intent.getIntExtra("pos",pos),ML.getMusicList()); uri = ML.getUri(cursor,pos); message.obj = 1; handler.sendMessage(message); } return 1; } public void onDestroy(){ super.onDestroy(); mp.release(); stopSelf(); } }