最近做了一个android音乐播放器,个人感觉最难的就是“后台播放”以及有关“播放列表”的部分,但是总算是找到了实现的方式。不同的人实现的方式可能不一样,这里我就分享一下自己对“播放列表”这个模块的一些实现方法,“后台播放”会在下一篇博文中进行介绍,希望大家也能分享一下自己的一些思路。
android使用ContentProvider来支持不同应用程序的数据共享,为了方便其他应用程序对sdcard中的数据进行操作,sdcard也提供了ContentProvider接口,这里就以访问音频文件为例,视频以及图片的操作也类似,这里就不在赘述。
访问sdcard中的音频文件的URI为MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,为了使播放列表显示所以音乐文件的信息,这里需要查询sdcard里的音频文件,并把查询到的信息保存在Cursor中,具体代码如下:
?
<PRE>Cursor c =
this
.getContentResolver().</PRE>
<PRE>query(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,</PRE>
|
?
new
String[]{MediaStore.Video.Media.TITLE,
MediaStore.Audio.Media.DURATION,
MediaStore.Audio.Media.ARTIST,
MediaStore.Audio.Media._ID,
MediaStore.Audio.Media.DISPLAY_NAME,
MediaStore.Audio.Media.DATA
},
null
,
null
,
null
);
|
通过MediaStore.Audio.Media.XXX来访问音乐文件的一些信息,这里只列出了一部分,可以根据需要进行增添和删除。
至此,Cursor c就已经保存了sdcard内所以音频文件的信息,下面的操作就是围绕这个Cursor展开的。
首先定义三个数组:
?
private
int
[] _ids;
private
String[] _titles;
private
String[] _path;
|
_ids保存了所有音乐文件的_ID,用来确定到底要播放哪一首歌曲,_titles存放音乐名,用来显示在播放界面,而_path存
放音乐文件的路径(删除文件时会用到)。
接下来再定义一个变量,用来定位选择的是哪一首音乐:
private int pos;
接下来将音乐文件的信息存放在相应的数组中:
?
c.moveToFirst();
_ids =
new
int
[c.getCount()];
_titles =
new
String[c.getCount()];
_path =
new
String[c.getCount()];
for
(
int
i=0;i<c.getCount();i++){
_ids[i] = c.getInt(3);
_titles[i] = c.getString(0);
_path[i] = c.getString(5).substring(4);
c.moveToNext();
}
|
有人可能会问为什么获取路径的格式是_path[i]=c.geString(5).substring(4)?因为MediaStore.Audio.Media.DATA
得到的内容格式为/mnt/sdcard/[子文件夹名/]音乐文件名,而我们想要得到的是/sdcard/[子文件夹名]音乐文件名,
所以要做相应的裁剪操作。
接下来把Cursor中的信息显示到listview中:
?
MusicListAdapter adapter =
new
MusicListAdapter(
this
, c);
listview.setAdapter(adapter);
|
MusicListAdapter是一个自定义的Adapter,继承自BaseAdapter,这里只贴出代码,不做讲解。
?
package com.alex.video;
import android.content.Context;
import android.database.Cursor;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.TextView;
public
class
MusicListAdapter extends BaseAdapter{
private
Context myCon;
private
Cursor myCur;
private
int
pos=-1;
public
MusicListAdapter(Context con,Cursor cur){
this
.myCon = con;
this
.myCur = cur;
}
@Override
public
int
getCount() {
return
this
.myCur.getCount();
}
@Override
public
Object getItem(
int
position) {
return
position;
}
@Override
public
long
getItemId(
int
position) {
return
position;
}
@Override
public
View getView(
int
position, View convertView, ViewGroup parent) {
convertView = LayoutInflater.from(myCon).inflate(R.layout.musiclist,
null
);
myCur.moveToPosition(position);
TextView videoTitle = (TextView)convertView.findViewById(R.id.musictitle);
if
(myCur.getString(0).length()>24){
try
{
String musicTitle = bSubstring(myCur.getString(0).trim(),24);
videoTitle.setText(musicTitle);
}
catch
(Exception e) {
e.printStackTrace();
}
}
else
{
videoTitle.setText(myCur.getString(0).trim());
}
TextView videoArtist = (TextView)convertView.findViewById(R.id.musicartist);
if
(myCur.getString(2).equals(
"<unknown>"
)){
videoArtist.setText(
"未知艺术家"
);
}
else
{
videoArtist.setText(myCur.getString(2));
}
TextView videoTime = (TextView)convertView.findViewById(R.id.musictime);
videoTime.setText(toTime(myCur.getInt(1)));
ImageView videoItem = (ImageView)convertView.findViewById(R.id.musicitem);
videoItem.setImageResource(R.drawable.item);
return
convertView;
}
public
String toTime(
int
time) {
time /= 1000;
int
minute = time / 60;
int
hour = minute / 60;
int
second = time % 60;
minute %= 60;
return
String.format(
"%02d:%02d"
, minute, second);
}
public
static
String bSubstring(String s,
int
length) throws Exception
{
byte
[] bytes = s.getBytes(
"Unicode"
);
int
n = 0;
int
i = 2;
for
(; i < bytes.length && n < length; i++)
{
if
(i % 2 == 1)
{
n++;
}
else
{
if
(bytes[i] != 0)
{
n++;
}
}
}
if
(i % 2 == 1)
{
if
(bytes[i - 1] != 0)
i = i - 1;
else
i = i + 1;
}
return
new
String(bytes, 0, i,
"Unicode"
);
}
}
|
这样,音乐的信息就显示在了列表中了
下一节将讲解更新列表的操作。
转自:http://www.cnblogs.com/zchajax/archive/2011/04/26/2029832.html