本篇实现音乐播放的功能,利用拖动条,listview以及广播返回消息给活动,更新UI界面。
效果演示:
这里无法听到音乐,这里只关注界面效果吧。
代码分析:
1.创建服务类,播放相应路径下的音乐:
这里音乐的路径是由主活动中的intent中存放的,开启服务时直接传过来即可。
2.注册服务:
这里由于服务类的包和活动的包不是同一个包,所以需要写全称。
3.创建Listview:
创建Listview的适配器:
@TargetApi(Build.VERSION_CODES.GINGERBREAD_MR1)
public class MusicAdapter extends BaseAdapter {
private LayoutInflater inflater;
private File[] musics;
private MediaMetadataRetriever mmr ;
public MusicAdapter(LayoutInflater inflater, File[] musics) {
this.inflater = inflater;
this.musics = musics;
}
@Override
public int getCount() {
// TODO Auto-generated method stub
return musics.length;
}
@Override
public Object getItem(int arg0) {
// TODO Auto-generated method stub
return arg0;
}
@Override
public long getItemId(int arg0) {
// TODO Auto-generated method stub
return arg0;
}
@Override
public View getView(int position, View convertView, ViewGroup arg2) {
// TODO Auto-generated method stub
ViewHolder vh = null;
if (convertView == null) {
vh = new ViewHolder();
convertView = inflater.inflate(R.layout.music_item_list, null);
vh.textviewName = (TextView) convertView.findViewById(R.id.textview_music_name);
vh.imgPic = (ImageView) convertView.findViewById(R.id.img_pic);
vh.textviewArtist = (TextView) convertView.findViewById(R.id.textview_artist);
convertView.setTag(vh);
} else {
vh = (ViewHolder) convertView.getTag();
}
// 放资源
vh.textviewName.setText(musics[position].getName());
// 放音乐图片和艺术家
mmr = new MediaMetadataRetriever();
mmr.setDataSource(musics[position].getAbsolutePath());
String author = mmr.extractMetadata(MediaMetadataRetriever.METADATA_KEY_ARTIST);
if (author != null) {
vh.textviewArtist.setText("艺术家:" + author);
} else {
vh.textviewArtist.setText("艺术家:未知");
}
// 放图片
byte[] imag = mmr.getEmbeddedPicture();// 得到图片
if (imag != null) {
Bitmap bitmap = BitmapFactory.decodeByteArray(imag, 0, imag.length);
vh.imgPic.setImageBitmap(bitmap);
} else {
vh.imgPic.setImageResource(R.drawable.den);
}
return convertView;
}
class ViewHolder {
ImageView imgPic;
TextView textviewName;
TextView textviewArtist;
}
}
Listview适配器这里不做详解,但需要注意,获取music中自带的图片和艺术家等自带信息的方法:
要通过MediaMetadataRetriever类:获取其实例,然后设置Source,现在的MediaMetadataRetriever就可以去获得这个指定路径音乐的信息。
MediaMetadataRetriever mmr = new MediaMetadataRetriever();
mmr.setDataSource(musics[position].getAbsolutePath());
这里仅介绍了获取图片和艺术家的方法:
获取艺术家名称:mmr.extractMetadata(MediaMetadataRetriever.METADATA_KEY_ARTIST);
获取图片:
mmr.getEmbeddedPicture();//获得的是图片的字节流
Bitmap bitmap = BitmapFactory.decodeByteArray(imag, 0, imag.length);//获得Bitmap形式的图片
即:
创建音乐列表,并加到Listview中:
添加到适配器
4.为Listview创建点击事件:
在listview的点击事件中开启服务,并携带音乐列表相应音乐的路径。
这里同时携带的还有一个type类型,用于服务判断,收到的指示是开始播放音乐,还是跳转音乐到相应位置,添加这个type是因为后面需要拖动seekbar来改变播放位置。
5.服务播放音乐后,将信息传给活动,改变seekBar位置,用广播实现:
活动里创建广播子类接收消息,接收seekbar的最大值及进程位置:
接收到广播,通过type(注:这是另一个type,和之前的不同)来判断接收的是音乐的总时长,还是当前的进度。