最近一直在看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();
}
}
到这里音乐播放的基本功能就实现了,其实还有好多地方写的不是太完善,有很多不足之处,所以笔者还是要再优化的的,希望对大家能有所帮助。