歌曲列表是來顯示SD卡或手機內存中的歌曲,因為android會自動掃描媒體對象,直接使用MediaStore就可以顯示歌曲名稱、藝術家、縮略圖等。再次使用ListView來顯示這些信息,xml布局很簡單就是一個ListView:
[html]
<SPAN style="FONT-SIZE: 14px"><?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<ListView
android:id="@+id/music_list"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="@drawable/listbg"
android:cacheColorHint="#00000000" >
</ListView>
</LinearLayout></SPAN><PRE class=java name="code"><SPAN style="FONT-SIZE: 14px">
</SPAN></PRE>
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<ListView
android:id="@+id/music_list"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="@drawable/listbg"
android:cacheColorHint="#00000000" >
</ListView>
</LinearLayout>[java] view plaincopyprint?<SPAN style="FONT-SIZE: 14px"> </SPAN>
既然使用ListView來顯示歌曲信息,例如歌曲標題、歌手、縮略圖以及時長等等。那麼如何獲取這些信息以及如何顯示到ListView中呢?要分為兩個步驟:
(1)使用MediaStore獲取歌曲信息
(2)自定義Adapter將MediaStore獲取歌曲信息顯示出來
[html]
/**
*
*/
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;
}
}
/**
*
*/
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,這裡有一點要說明的是,獲取歌曲內置的圖片比較麻煩一些。
[java]
<SPAN style="FONT-SIZE: 14px">/**
*
*/
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("<unknown>")) {
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;
}
}
</SPAN>
/**
*
*/
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("<unknown>")) {
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);
} www.2cto.com
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;
}
}