編輯:關於Android編程
一丶本地音樂加載相當於就是listVIew應用
扣丁音樂1.0前部分(gif圖大小限制)演示:

實體類Mp3Info(歌曲相關數據及get和set方法)
public class Mp3Info {
private long id;
private String title;//歌名
private String artist;//藝術家
private String album;//專輯
private long albumId;
private long duration;//時長
private long size;//大小
private String url;//路徑
private int isMusic;//是否為音樂
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getArtist() {
return artist;
}
public void setArtist(String artist) {
this.artist = artist;
}
public String getAlbum() {
return album;
}
public void setAlbum(String album) {
this.album = album;
}
public long getAlbumId() {
return albumId;
}
public void setAlbumId(long albumId) {
this.albumId = albumId;
}
public long getDuration() {
return duration;
}
public void setDuration(long duration) {
this.duration = duration;
}
public long getSize() {
return size;
}
public void setSize(long size) {
this.size = size;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public int getIsMusic() {
return isMusic;
}
public void setIsMusic(int isMusic) {
this.isMusic = isMusic;
}
@Override
public String toString() {
return "Mp3Info{" +
"id=" + id +
", title='" + title + '\'' +
", artist='" + artist + '\'' +
", album='" + album + '\'' +
", albumId=" + albumId +
", duration=" + duration +
", size=" + size +
", url='" + url + '\'' +
", isMusic=" + isMusic +
'}';
}
}
工具類MediaUtils(實現例如篩選歌曲長度,時間格式化,圖片處理等)
public class MediaUtils {
//獲取專輯封面的Uri
private static final Uri albumArtUri = Uri.parse("content://media/external/audio/albumart");
/**
* 獲取默認專輯圖片
*/
public static Bitmap getDefaultArtwork(Context context,boolean small){
BitmapFactory.Options opts = new BitmapFactory.Options();
opts.inPreferredConfig = Bitmap.Config.RGB_565;
if(small){
return BitmapFactory.decodeStream(context.getResources().openRawResource(R.drawable.music_play),null,opts);
}
return BitmapFactory.decodeStream(context.getResources().openRawResource(R.drawable.music_play),null,opts);
}
/**
* 從文件當中獲取專輯封面位圖
*/
private static Bitmap getArtworkFromFile(Context context,long songid,long albumid){
Bitmap bm = 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();
}
}else{
Uri uri = ContentUris.withAppendedId(albumArtUri,albumid);
ParcelFileDescriptor pfd = context.getContentResolver().openFileDescriptor(uri, "r");
if(pfd!=null){
fd = pfd.getFileDescriptor();
}
}
options.inSampleSize=1;
//只進行大小判斷
options.inJustDecodeBounds = true;
//調用此方法得到options得到圖片大小
BitmapFactory.decodeFileDescriptor(fd,null,options);
//我們的目標是在800pixel的畫面上顯示
//所以需要調用computeSampleSize得到圖片縮放的比例
options.inSampleSize = 100;
//我們得到了縮放的比例,現在開始正式讀入Bitmap數據
options.inJustDecodeBounds = false;
options.inDither = false;
options.inPreferredConfig = Bitmap.Config.ARGB_8888;
//根據options參數,減少所需要的內存
bm = BitmapFactory.decodeFileDescriptor(fd,null,options);
}catch (FileNotFoundException e){
e.printStackTrace();
}
return bm;
}
/**
* 獲取專輯封面位圖對象
*/
public static Bitmap getArtwork(Context context,long song_id,long album_id,boolean allowdefault,boolean small){
if(album_id<0){
if(song_id<0){
Bitmap bm = getArtworkFromFile(context,song_id,-1);
if(bm!=null){
return bm;
}
}
if(allowdefault){
return getDefaultArtwork(context,small);
}
return null;
}
ContentResolver res = context.getContentResolver();
Uri uri = ContentUris.withAppendedId(albumArtUri,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;
//調用此方法得到options得到圖片的大小
BitmapFactory.decodeStream(in,null,options);
//我們的目標是在你N pixel的畫面上顯示。所以需要調用computeSampleSize得到圖片縮放的比例
//這裡的target為800是根據默認專輯圖片代傲決定的,800只是測試數字但是試驗後發現完美的結合
if(small){
options.inSampleSize = computeSampleSize(options,40);
}else {
options.inSampleSize = computeSampleSize(options,600);
}
//我們得到了縮放比例,現在開始正式讀入Bitmap數據
options.inJustDecodeBounds = false;
options.inDither = false;
options.inPreferredConfig = Bitmap.Config.ARGB_8888;
in = res.openInputStream(uri);
return BitmapFactory.decodeStream(in,null,options);
}catch (FileNotFoundException e){
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,small);
}
}else if(allowdefault){
bm = getDefaultArtwork(context,small);
}
return bm;
}
}finally {
try {
if(in != null){
in.close();
}
}catch (IOException e){
e.printStackTrace();
}
}
}
return null;
}
/**
* 對圖片進行合適的縮放
*/
public 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)1){
if((h>target)&&(h/candidate)/**
* 用於從數據庫中查詢歌曲的信息,保存在List當中
*/
public static ArrayList getMp3Infos(Context context){
Cursor cursor = context.getContentResolver().query(
MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, null,
//最小音樂長度
MediaStore.Audio.Media.DURATION + ">=180000", null,
MediaStore.Audio.Media.DEFAULT_SORT_ORDER);
ArrayList mp3Infos = new ArrayList();
for(int i=0;i_ID));//id
String title = cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.TITLE));//歌名
String artist = cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.ARTIST));//藝術家
String album = cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.ALBUM));//專輯
long albumId = cursor.getLong(cursor.getColumnIndex(MediaStore.Audio.Media.ALBUM_ID));//專輯id
long duration = cursor.getLong(cursor.getColumnIndex(MediaStore.Audio.Media.DURATION));//時長
long size = cursor.getLong(cursor.getColumnIndex(MediaStore.Audio.Media.SIZE));//大小
String url = cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.DATA));//路徑
int isMusic = cursor.getInt(cursor.getColumnIndex(MediaStore.Audio.Media.IS_MUSIC));//是否為音樂
if(isMusic!=0){
mp3Info.setId(id);
mp3Info.setTitle(title);
mp3Info.setArtist(artist);
mp3Info.setAlbum(album);
mp3Info.setAlbumId(albumId);
mp3Info.setDuration(duration);
mp3Info.setSize(size);
mp3Info.setUrl(url);
mp3Infos.add(mp3Info);
}
}
cursor.close();
return mp3Infos;
}
/**
* 格式化時間,將毫秒轉換為分:秒格式
*/
public static String formatTime(long time){
String min = time / (1000 * 60)+"";
String sec = time % (1000 * 60)+"";
if(min.length()<2){
min = "0"+time / (1000 * 60)+"";
}else{
min = time / (1000 * 60)+"";
}
if(sec.length()==4){
sec = "0"+(time % (1000 * 60))+"";
}else if(sec.length()==3){
sec = "00"+(time % (1000 * 60))+"";
}else if(sec.length()==2){
sec = "000"+(time % (1000 * 60))+"";
}else if(sec.length()==1){
sec = "0000"+(time % (1000 * 60))+"";
}
return min + ":" +sec.trim().substring(0,2);
}}
activity_local_songs.xml(後面貼出)
item_music_fragment.xml(略)
很明顯這裡我和視頻顯示得不一樣,歌曲圖片不好找顯示出來也不是很美觀,於是我顯示的是歌名,歌手,專輯,時間這個xml應個人喜好可調整
LocalSongsListAdapter.java
public class LocalSongsListAdapter extends BaseAdapter{
private Context context;
private ArrayList mp3Infos;
public LocalSongsListAdapter(Context context,ArrayList mp3Infos){
this.context = context;
this.mp3Infos = mp3Infos;
}
public void setMp3Infos(ArrayList mp3Infos){
this.mp3Infos = mp3Infos;
}
@Override
public int getCount() {
return mp3Infos.size();
}
@Override
public Object getItem(int position) {
return mp3Infos.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder vh;
if(convertView==null){
convertView = LayoutInflater.from(context).inflate(R.layout.item_music_list,null);
vh = new ViewHolder();
vh.tv_song_name = (TextView)convertView.findViewById(R.id.tv_song_name);
vh.tv_song_artist = (TextView)convertView.findViewById(R.id.tv_song_artist);
vh.tv_song_album = (TextView)convertView.findViewById(R.id.tv_song_album);
vh.tv_song_duration = (TextView)convertView.findViewById(R.id.tv_song_duration);
convertView.setTag(vh);
}else{
vh = (ViewHolder)convertView.getTag();
}
//給控件賦值要寫在if語句外面,否則第一次加載數據失敗
Mp3Info mp3Info = mp3Infos.get(position);
vh.tv_song_name.setText(mp3Info.getTitle());
vh.tv_song_artist.setText(mp3Info.getArtist());
vh.tv_song_album.setText(mp3Info.getAlbum());
vh.tv_song_duration.setText(MediaUtils.formatTime(mp3Info.getDuration()));
return convertView;
}
static class ViewHolder{
TextView tv_song_name;
TextView tv_song_artist;
TextView tv_song_album;
TextView tv_song_duration;
}
}
LocalSongsActivity.java
寫到這裡LocalSongsActivity.java裡面只需要初始化控件,後面再貼出
/**
* 初始化本地音樂列表
*/
private void initDate() {
mp3Infos = MediaUtils.getMp3Infos(this);
System.out.println(mp3Infos.size());
localSongsListAdapter = new LocalSongsListAdapter(this,mp3Infos);
localSongsListAdapter.notifyDataSetChanged();
lv_local_songs_list.setAdapter(localSongsListAdapter);
}
SD卡讀取權限,網絡權限
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"></uses-permission> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"></uses-permission> <uses-permission android:name="android.permission.INTERNET"></uses-permission>
到這裡就能完成歌曲的加載了
修改android應用包名
由於項目需要,要修改已經開發好的應用包名,這本身很簡單,但是如果你沒找到門道,可能會白白浪費許多時間。修改包名有三個地方要改,這三個地方的修改一定要按順序來,否則你可能會
Android之手勢的識別與處理(雙擊onDoubleTap、滑動onFling、拖動onScroll)
概述:一般情況下,我們知道View類有個View.OnTouchListener內部接口,通過重寫他的onTouch(View v, MotionEvent event)
貝塞爾曲線開發的藝術
貝塞爾曲線開發的藝術一句話概括貝塞爾曲線:將任意一條曲線轉化為精確的數學公式。很多繪圖工具中的鋼筆工具,就是典型的貝塞爾曲線的應用貝塞爾曲線中有一些比較關鍵的名詞,解釋如
android 支付寶集成 使用常見錯誤
1:自己最近在做了支付,遇到了一下問題先總結如下 第一條: Android快捷支付SDK Demo resultStatus={4001};memo={參數錯誤};