您的位置:首页 > 其它

音乐播放器-DAO之MusicUtils

2015-09-04 17:30 393 查看
写着写着发现其实不用对每句都解释,只需要把每几个类似的方法拿出一个解释就OK了

包括以后的5个DAO(app我的首页的gridview的5个数据)也只拿出个例子就行了

package com.ldw.music.utils;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

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.provider.MediaStore.Audio.Albums;
import android.provider.MediaStore.Audio.Media;
import android.provider.MediaStore.Files.FileColumns;
import android.text.TextUtils;

import com.ldw.music.activity.IConstants;
import com.ldw.music.db.AlbumInfoDao;
import com.ldw.music.db.ArtistInfoDao;
import com.ldw.music.db.FavoriteInfoDao;
import com.ldw.music.db.FolderInfoDao;
import com.ldw.music.db.MusicInfoDao;
import com.ldw.music.model.AlbumInfo;
import com.ldw.music.model.ArtistInfo;
import com.ldw.music.model.FolderInfo;
import com.ldw.music.model.MusicInfo;
import com.ldw.music.storage.SPStorage;

/**
* 查询各主页信息,获取封面图片等
*
* @author longdw(longdawei1988@gmail.com)
*
*/
public class MusicUtils implements IConstants {
/**
* MusicUtils是数据层(Model层)的顶层类
*/
/**
* 该类主要是提供对5个DAO的封装,这5个DAO正式app开启的时候弹出的第一个界面的gridview的5项:
* 我的音乐,我的最爱,文件夹,歌手,专辑 起名叫util也是想把这个工具提供给其他使用 4个get方法供5个query方法调用,提供数据
* 另外一个核心的数据是sArtCache该hashmap保存图标
* getCachedArtwork调用getArtworkQuick(Context, long, int, int)创建音乐的图标
*/
/**
* MediaStore.Audio.Media.在该类里面存储了许多系统指定的字符串,根据名字我们可以知道有 音乐的id,名字
* 二进制内容,所在的唱片的id 艺术家,艺术家id 音乐的时间--一共7项 proj_music proj_album proj_artist
* proj_folder一共4个,“我喜欢”不在这里面
*/
private static String[] proj_music = new String[] {
MediaStore.Audio.Media._ID, MediaStore.Audio.Media.TITLE,
MediaStore.Audio.Media.DATA, MediaStore.Audio.Media.ALBUM_ID,
MediaStore.Audio.Media.ARTIST, MediaStore.Audio.Media.ARTIST_ID,
MediaStore.Audio.Media.DURATION };

private static String[] proj_album = new String[] { Albums.ALBUM,
Albums.NUMBER_OF_SONGS, Albums._ID, Albums.ALBUM_ART };

private static String[] proj_artist = new String[] {
MediaStore.Audio.Artists.ARTIST,
MediaStore.Audio.Artists.NUMBER_OF_TRACKS };

private static String[] proj_folder = new String[] { FileColumns.DATA };

public static final int FILTER_SIZE = 1 * 1024 * 1024;// 1MB
public static final int FILTER_DURATION = 1 * 60 * 1000;// 1分钟
private static final BitmapFactory.Options sBitmapOptionsCache = new BitmapFactory.Options();
private static final BitmapFactory.Options sBitmapOptions = new BitmapFactory.Options();
private static final HashMap<Long, Bitmap> sArtCache = new HashMap<Long, Bitmap>();
// 获取音乐的内置图片http://blog.csdn.net/tao_zi7890/article/details/8851512
private static final Uri sArtworkUri = Uri
.parse("content://media/external/audio/albumart");

static {
// for the cache,
// 565 is faster to decode and display
// and we don't want to dither here because the image will be scaled
// down later
sBitmapOptionsCache.inPreferredConfig = Bitmap.Config.RGB_565;// 缩小图片尺寸
sBitmapOptionsCache.inDither = false;/* 不进行图片抖动处理 */
// sBitmapOptions没有用到
sBitmapOptions.inPreferredConfig = Bitmap.Config.RGB_565;
sBitmapOptions.inDither = false;
}

// 歌曲信息数据库
private static MusicInfoDao mMusicInfoDao;
// 专辑信息数据库
private static AlbumInfoDao mAlbumInfoDao;
// 歌手信息数据库
private static ArtistInfoDao mArtistInfoDao;
// 文件夹信息数据库
private static FolderInfoDao mFolderInfoDao;
// 我的收藏信息数据库
private static FavoriteInfoDao mFavoriteDao;

public static List<MusicInfo> queryFavorite(Context context) {
if (mFavoriteDao == null) {
mFavoriteDao = new FavoriteInfoDao(context);
}
return mFavoriteDao.getMusicInfo();// 通过DAO获取信息
}

/**
* 获取包含音频文件的文件夹信息
*
* @param context
* @return
*/
public static List<FolderInfo> queryFolder(Context context) {
if (mFolderInfoDao == null) {
mFolderInfoDao = new FolderInfoDao(context);
}
//比源文件把if语句提前了,这样用不到的就不用创建
if (mFolderInfoDao.hasData()) {
return mFolderInfoDao.getFolderInfo();
} else {
SPStorage sp = new SPStorage(context);
Uri uri = MediaStore.Files.getContentUri("external");
// 获得该activity 的contentResolver
ContentResolver cr = context.getContentResolver();
// 构造sql语句
StringBuilder mSelection = new StringBuilder(FileColumns.MEDIA_TYPE
+ " = " + FileColumns.MEDIA_TYPE_AUDIO + " and " + "("
+ FileColumns.DATA + " like'%.mp3' or " + Media.DATA
+ " like'%.wma')");
// 查询语句:检索出.mp3为后缀名,时长大于1分钟,文件大小大于1MB的媒体文件
if (sp.getFilterSize()) {
mSelection.append(" and " + Media.SIZE + " > " + FILTER_SIZE);
}
if (sp.getFilterTime()) {
mSelection.append(" and " + Media.DURATION + " > "
+ FILTER_DURATION);
}
mSelection.append(") group by ( " + FileColumns.PARENT);
//源文件if所在位置
List<FolderInfo> list = getFolderList(cr.query(uri, proj_folder,
mSelection.toString(), null, null));
mFolderInfoDao.saveFolderInfo(list);
return list;
}
}

在上面构造sql的时候需要有些数据库知识,当然,sqlite行,其他数据库mysql sqlserver都可以,

StringBuilder和StringBuffer都有append方法,StringBuffer开销大,只用来当需要线程安全的使用,

线程安全就是指同一时刻一段代码,或者一个变量只能有一个线程访问,java创建线程的方fa,,,

public static List<MusicInfo> queryMusic(Context context,
String selections, String selection, int from) {
if (mMusicInfoDao == null) {
mMusicInfoDao = new MusicInfoDao(context);
}
SPStorage sp = new SPStorage(context);//看源文件是为了存取sharepreference用的
Uri uri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
ContentResolver cr = context.getContentResolver();
//源文件里面是有 的" 1=1 ",我试了试没有 " 1=1 "也行,于是看这个http://biancheng.dnbcw.info/mssql/173052.html
StringBuffer select = new StringBuffer();//" 1=1 "
// 查询语句:检索出.mp3为后缀名,时长大于1分钟,文件大小大于1MB的媒体文件
if (sp.getFilterSize()) {
select.append( Media.SIZE + " > " + FILTER_SIZE);//" and " +
}
if (sp.getFilterTime()) {
select.append(" and " + Media.DURATION + " > " + FILTER_DURATION);
}

if (!TextUtils.isEmpty(selections)) {
select.append(selections);
}

switch (from) {
case START_FROM_LOCAL:
if (mMusicInfoDao.hasData()) {
return mMusicInfoDao.getMusicInfo();
} else {
List<MusicInfo> list = getMusicList(cr.query(uri, proj_music,
select.toString(), null,
MediaStore.Audio.Media.ARTIST_KEY));
mMusicInfoDao.saveMusicInfo(list);
return list;
}
case START_FROM_ARTIST:
if (mMusicInfoDao.hasData()) {
return mMusicInfoDao.getMusicInfoByType(selection,
START_FROM_ARTIST);
} else {
// return getMusicList(cr.query(uri, proj_music,
// select.toString(), null,
// MediaStore.Audio.Media.ARTIST_KEY));
}
case START_FROM_ALBUM:
if (mMusicInfoDao.hasData()) {
return mMusicInfoDao.getMusicInfoByType(selection,
START_FROM_ALBUM);
}
case START_FROM_FOLDER:
if (mMusicInfoDao.hasData()) {
return mMusicInfoDao.getMusicInfoByType(selection,
START_FROM_FOLDER);
}
default:
return null;
}

}


下面的getMusicList里面用到了Cursor,是什么呢?类似于List<Map<k,v>>,也就是所以就需要while取出信息,

好了下一节将讲解MusicInfoDao,这几个DAO其实除了favorate都差不多,因为favorite不是系统的,是属于该app的,顺便就把Sqlite带上


内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: