歌曲列表是来显示SD卡或手机内存中的歌曲,因为android会自动扫描媒体对象,直接使用MediaStore就可以显示歌曲名称、艺术家、缩略图等。再次使用ListView来显示这些信息,xml布局很简单就是一个ListView:
既然使用ListView来显示歌曲信息,例如歌曲标题、歌手、缩略图以及时长等等。那么如何获取这些信息以及如何显示到ListView中呢?要分为两个步骤:
(1)使用MediaStore获取歌曲信息
(2)自定义Adapter将MediaStore获取歌曲信息显示出来
/**
*
*/
package com.android.musicplayer.activity;
import java.io.File;
import com.android.musicplayer.adapter.MusicListAdapter;
import com.android.musicplayer.util.ScanSdReceiver;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
import android.database.Cursor;
import android.media.AudioManager;
import android.os.Bundle;
import android.provider.MediaStore;
import android.view.ContextMenu;
import android.view.KeyEvent;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.View.OnCreateContextMenuListener;
import android.widget.AdapterView;
import android.widget.ListView;
import android.widget.AdapterView.OnItemClickListener;
/**
* @author Administrator
*
*/
public class SongsActivity extends Activity {
private int[] _ids;// 保存音乐ID临时数组
private String[] _artists;// 保存艺术家
private String[] _titles;// 标题临时数组
private ListView listView;// 列表对象
private Cursor cursor;
private MusicListAdapter musicListAdapter;
private AlertDialog ad = null;
private AlertDialog.Builder builder = null;
private static final String MUSIC_LIST = "com.android.musicplayer.activity.list";
/**
* 定义查找音乐信息数组,1.标题 2.音乐时间 3.艺术家 4.音乐id 5.显示名字 6.数据
*/
String[] media_music_info = new String[] { MediaStore.Audio.Media.TITLE,
MediaStore.Audio.Media.DURATION, MediaStore.Audio.Media.ARTIST,
MediaStore.Audio.Media._ID, MediaStore.Audio.Media.DISPLAY_NAME,
MediaStore.Audio.Media.DATA, MediaStore.Audio.Media.ALBUM_ID };
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_songs);
listView = (ListView) findViewById(R.id.music_list);
listView.setOnItemClickListener(new MusicListOnClickListener());// 创建一个ListView监听器对象
showMusicList();
}
private void showMusicList() {
cursor = getContentResolver().query(
MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, media_music_info,
null, null, MediaStore.Audio.Media.DEFAULT_SORT_ORDER);
cursor.moveToFirst();// 将游标移动到初始位置
_ids = new int[cursor.getCount()];// 返回int的一个列
_artists = new String[cursor.getCount()];// 返回String的一个列
_titles = new String[cursor.getCount()];// 返回String的一个列
for (int i = 0; i < cursor.getCount(); i++) {
_ids[i] = cursor.getInt(3);
_titles[i] = cursor.getString(0);
_artists[i] = cursor.getString(2);
cursor.moveToNext();// 将游标移到下一行
}
musicListAdapter = new MusicListAdapter(this, cursor);
listView.setAdapter(musicListAdapter);// 用setAdapter装载数据
listView.setOnCreateContextMenuListener(new ContextMenuListener());
}
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK) {
if (scanSdReceiver != null)
unregisterReceiver(scanSdReceiver);
Intent intent = new Intent();
intent.setClass(this, MainActivity.class);
startActivity(intent);
finish();
}
return true;
}
}
同样的使用自定义Adapter来显示歌曲:MusicListAdapter,这里有一点要说明的是,获取歌曲内置的图片比较麻烦一些。
/**
*
*/
package com.android.musicplayer.adapter;
import java.io.FileDescriptor;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import com.android.musicplayer.activity.R;
import android.content.ContentResolver;
import android.content.ContentUris;
import android.content.Context;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.ParcelFileDescriptor;
import android.provider.MediaStore;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.TextView;
/**
* @author Administrator
*
*/
public class MusicListAdapter extends BaseAdapter {
private Context myContext;
private Cursor myCursor;
private int pos = -1;
public MusicListAdapter(Context context, Cursor cursor) {
myContext = context;
myCursor = cursor;
}
@Override
public int getCount() {
return myCursor.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) {
ViewHolder holder = null;
View vi = convertView;
if (convertView == null) {
holder = new ViewHolder();
vi = LayoutInflater.from(myContext).inflate(R.layout.musiclist,
null);
holder.tv_music = (TextView) vi.findViewById(R.id.music1);
holder.tv_singer = (TextView) vi.findViewById(R.id.singer);
holder.tv_time = (TextView) vi.findViewById(R.id.time);
holder.img = (ImageView) vi.findViewById(R.id.listitem);
vi.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
myCursor.moveToPosition(position);
if (myCursor.getString(0).length() > 15) {
try {
String musicTitle = myCursor.getString(0).trim()
.substring(0, 12)
+ "...";
holder.tv_music.setText(musicTitle);
} catch (Exception e) {
e.printStackTrace();
}
} else {
holder.tv_music.setText(myCursor.getString(0).trim());
}
if (myCursor.getString(2).equals("")) {
holder.tv_singer.setText("未知艺术家?");
} else {
holder.tv_singer.setText(myCursor.getString(2));
}
if (position == pos) {
holder.img.setImageResource(R.drawable.isplaying);
} else {
// img.setImageResource(R.drawable.item);
Bitmap bm = getArtwork(myContext, myCursor.getInt(3),
myCursor.getInt(myCursor
.getColumnIndex(MediaStore.Audio.Media.ALBUM_ID)),
true);
holder.img.setImageBitmap(bm);
}
return vi;
}
public void setItemIcon(int position) {
pos = position;
}
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 Bitmap getArtwork(Context context, long song_id,
long album_id, boolean allowdefault) {
Log.v("ADW", "getArtwork");
if (album_id < 0) {
// This is something that is not in the database, so get the album
// art directly
// from the file.
if (song_id >= 0) {
Bitmap bm = getArtworkFromFile(context, song_id, -1);
if (bm != null) {
return bm;
}
}
if (allowdefault) {
return getDefaultArtwork(context);
}
return null;
}
ContentResolver res = context.getContentResolver();
Uri uri = ContentUris.withAppendedId(sArtworkUri, album_id);
if (uri != null) {
InputStream in = null;
try {
in = res.openInputStream(uri);
BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = 1;
options.inJustDecodeBounds = true;
BitmapFactory.decodeStream(in, null, options);
options.inSampleSize = computeSampleSize(options, 30);
options.inJustDecodeBounds = false;
options.inDither = false;
options.inPreferredConfig = Bitmap.Config.ARGB_8888;
in = res.openInputStream(uri);
return BitmapFactory.decodeStream(in, null, options);
} catch (FileNotFoundException ex) {
// The album art thumbnail does not actually exist. Maybe the
// user deleted it, or
// maybe it never existed to begin with.
Bitmap bm = getArtworkFromFile(context, song_id, album_id);
if (bm != null) {
if (bm.getConfig() == null) {
bm = bm.copy(Bitmap.Config.RGB_565, false);
if (bm == null && allowdefault) {
return getDefaultArtwork(context);
}
}
} else if (allowdefault) {
bm = getDefaultArtwork(context);
}
return bm;
} finally {
try {
if (in != null) {
in.close();
}
} catch (IOException ex) {
}
}
}
return null;
}
private static Bitmap getArtworkFromFile(Context context, long songid,
long albumid) {
Bitmap bm = null;
byte[] art = null;
String path = null;
if (albumid < 0 && songid < 0) {
throw new IllegalArgumentException(
"Must specify an album or a song id");
}
try {
BitmapFactory.Options options = new BitmapFactory.Options();
FileDescriptor fd = null;
if (albumid < 0) {
Uri uri = Uri.parse("content://media/external/audio/media/"
+ songid + "/albumart");
ParcelFileDescriptor pfd = context.getContentResolver()
.openFileDescriptor(uri, "r");
if (pfd != null) {
fd = pfd.getFileDescriptor();
// bm = BitmapFactory.decodeFileDescriptor(fd,null,options);
}
} else {
Uri uri = ContentUris.withAppendedId(sArtworkUri, albumid);
ParcelFileDescriptor pfd = context.getContentResolver()
.openFileDescriptor(uri, "r");
if (pfd != null) {
fd = pfd.getFileDescriptor();
// bm = BitmapFactory.decodeFileDescriptor(fd,null,options);
}
}
Log.v("ADW", "getArtworkFromFile");
options.inSampleSize = 1;
options.inJustDecodeBounds = true;
BitmapFactory.decodeFileDescriptor(fd, null, options);
options.inSampleSize = 500;// computeSampleSize(options, 800);
options.inJustDecodeBounds = false;
options.inDither = false;
options.inPreferredConfig = Bitmap.Config.ARGB_8888;
bm = BitmapFactory.decodeFileDescriptor(fd, null, options);
} catch (FileNotFoundException ex) {
}
if (bm != null) {
mCachedBit = bm;
}
return bm;
}
static int computeSampleSize(BitmapFactory.Options options, int target) {
int w = options.outWidth;
int h = options.outHeight;
int candidateW = w / target;
int candidateH = h / target;
int candidate = Math.max(candidateW, candidateH);
if (candidate == 0)
return 1;
if (candidate > 1) {
if ((w > target) && (w / candidate) < target)
candidate -= 1;
}
if (candidate > 1) {
if ((h > target) && (h / candidate) < target)
candidate -= 1;
}
Log.v("ADW", "candidate:" + candidate);
return candidate;
}
private static Bitmap getDefaultArtwork(Context context) {
BitmapFactory.Options opts = new BitmapFactory.Options();
opts.inPreferredConfig = Bitmap.Config.RGB_565;
return BitmapFactory.decodeStream(context.getResources()
.openRawResource(R.drawable.item), null, opts);
}
private static final Uri sArtworkUri = Uri
.parse("content://media/external/audio/albumart");
private static final BitmapFactory.Options sBitmapOptions = new BitmapFactory.Options();
private static Bitmap mCachedBit = null;
class ViewHolder {
public TextView tv_music, tv_singer, tv_time;
public ImageView img;
}
}