上一个实验解析补充没填好坑,还把自己埋了,惶恐……下次还是要再提早点到机房调试过再讲吧,临时发挥容易出状况……
前一个补充是讲图片轮播,自己电脑上调的好好的,到了机房就是抛异常,还是classnotfound,尴尬啊,以后还是要把版本升的高一点,机房当初只装到4.3,唉……
这次这个补充到对版本没有特别要求,但是对模拟器有点要求,要能正常运行,上课时模拟器又没有正常运行起来,DDMS里往模拟器里导文件就是read-only,后来发现原来是模拟器前面出状况过,没有正常加载,关掉重开就OK了。恩,下次一定要自己选机房自己装环境。
下面我们假设前面的所有问题都没有发生,环境都是非常理想的。
1、首先我们往模拟器里的mnt\sdcard\music里导些MP3文件进去(如果sdcard目录中没有下级子目录就表示模拟器有问题,要重开)。
2、导入完成后模拟器貌似也要重开下,真机调试就不用。然后到data\data\com.android.provides.media\databases下找到两个db文件:external和internal。主要用external.db,导出到电脑上,然后用个sqlitespy之类的查看器打开查看数据库信息,有个视图(view)叫audio的,查看数据后可以看到里面包含了刚才导入的那些mp3文件信息,基本上我们需要的字段是data、title、duration、artist(分别表示路径、歌曲名、时长和艺术家)。
3、接下来我们就需要在android里获取到这些数据。参考以前的一篇:安卓第二次实验解析里的第二点“SD卡的扫描过程”,里面用到了Cursor游标对象去检索MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,然后逐条获取,代码如下:
Cursor cursor = currentContext.getContentResolver().query(
MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, null, null, null,
null);
int totalNum=cursor.getCount();//获取数据项个数
//以下for循环遍历游标对象,并将需要的数据存放到对应的数组对象中
for (int i = 0; i < cursor.getCount(); i++) {
cursor.moveToNext();
String title = cursor.getString((cursor.getColumnIndex(MediaStore.Audio.Media.TITLE)));// 音乐标题
String uri=cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.DATA));//文件路径
String duration=cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.DURATION));//文件路径
musicTitle.add(title);
musicUri.add(uri);
musicDuration.add(duration);
}
将获取到的Title、data和duration存放到三个ArrayList对象中。
4、接下来我们需要自定义一个适配器musicAdapter,继承自BaseAdapter。以及一个和这个这个适配器对应的布局界面musit_item.xml。
(1)布局界面music_item.xml具体代码如下:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/LinearLayout1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<TextView
android:id="@+id/tvMusicTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="TextView" />
<TextView
android:id="@+id/tvMusicUri"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="TextView"
android:visibility="gone" />
<TextView
android:id="@+id/tvMusicDuration"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="TextView" />
</LinearLayout>
里面放了三个TextView分别用来存放title、uri、duration,同时因为uri的内容不需要现实,所以可以将它的visibility属性设置为gone(invisible也是不可见,但是位置空间还占着)。
(2)布局界面OK了之后就新建一个class文件,类名这边定义为musicAdapter。具体代码如下:
public class musicAdapter extends BaseAdapter {
private LayoutInflater myInflater;
private ArrayList<String> musicTitle;
private ArrayList<String> musicUri;
private ArrayList<String> musicDuration;
public musicAdapter(Context c,ArrayList<String> _title,ArrayList<String> _uri,ArrayList<String> _duration){
myInflater=LayoutInflater.from(c);
this.musicTitle=_title;
this.musicUri=_uri;
this.musicDuration=_duration;
};
@Override
public int getCount() {
// TODO Auto-generated method stub
return musicTitle.size();
}
@Override
public Object getItem(int position) {
// TODO Auto-generated method stub
return musicUri.get(position);
}
@Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
convertView=myInflater.inflate(R.layout.music_item, null);
TextView tvMusicTitle=(TextView)convertView.findViewById(R.id.tvMusicTitle);
TextView tvMusicUri=(TextView)convertView.findViewById(R.id.tvMusicUri);
TextView tvMusicDuration=(TextView)convertView.findViewById(R.id.tvMusicDuration);
tvMusicTitle.setText(musicTitle.get(position));
tvMusicUri.setText(musicUri.get(position));
tvMusicDuration.setText(musicDuration.get(position));
return convertView;
}
}
首先这里出现了LayoutInflater对象,主要用来加载布局,和我们比较熟悉的Activity的onCreate方法里的setContentView类似。我们可以查看该博文:
Android LayoutInflater原理分析,带你一步步深入了解View(一) 。我们在这个自定义类的getView方法中加载刚才我们新建的布局界面music_item。然后将内容绑定到三个TextView中。这样我们的准备工作就已经OK了。
5、最后我们就实例化一个musicAdapter对象,并将该对象作为ListView的数据源即可。代码如下:
musicAdapter myAdapter=new musicAdapter(this,musicTitle,musicUri,musicDuration);
//ArrayAdapter<String> myAdapt=new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, list);
lvMusic.setAdapter(myAdapter);
其中第一行就是实例化一个musicAdapter对象,构造函数传入四个参数:当前context、title、uri、duration;注释掉的第二行代码就是原来使用最简单的适配器的情况;第三行就是将这个适配器对象作为ListView的数据源。
这次应该将这个坑给填平了,也适当的补偿了下浪费大家的时间。下次上课会早早到,把机房教师机环境更新下再说。希望大家满意!抱歉抱歉!