Android獲取本機各種型別檔案列表(音樂、視訊、圖片、文件等)
介紹
本篇介紹Android獲取本機各種型別檔案的方法,已經封裝成工具類,末尾有原始碼下載地址。
提示
獲取音樂、視訊、圖片、文件等檔案是需要有讀取SD卡的許可權的,如果是6.0以下的系統,則直接在清單檔案中宣告SD卡讀取許可權即可;如果是6.0或以上,則需要動態申請許可權。
FileManager的使用
FileManager是封裝好的用於獲取本機各類檔案的工具類,使用方式如:FileManager.getInstance(Context context).getMusics(),使用的是單例模式建立:
privatestaticFileManager mInstance;
privatestaticContext mContext;
publicstaticContentResolver mContentResolver;
privatestaticObject mLock = newObject();
publicstaticFileManager getInstance(Context context){
if(mInstance == null){
synchronized(mLock){
if(mInstance == null){
mInstance = newFileManager();
mContext = context;
mContentResolver = context.getContentResolver();
}
}
}
returnmInstance;
}
獲取音樂列表/**
* 獲取本機音樂列表
* @return
*/
privatestaticList
ArrayList
Cursor c = null;
try{
c = mContentResolver.query(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, null, null, null,
MediaStore.Audio.Media.DEFAULT_SORT_ORDER);
while(c.moveToNext()) {
String path = c.getString(c.getColumnIndexOrThrow(MediaStore.Audio.Media.DATA)); // 路徑
if(FileUtils.isExists(path)) {
continue;
}
String name = c.getString(c.getColumnIndexOrThrow(MediaStore.Audio.Media.DISPLAY_NAME)); // 歌曲名
String album = c.getString(c.getColumnIndexOrThrow(MediaStore.Audio.Media.ALBUM)); // 專輯
String artist = c.getString(c.getColumnIndexOrThrow(MediaStore.Audio.Media.ARTIST)); // 作者
longsize = c.getLong(c.getColumnIndexOrThrow(MediaStore.Audio.Media.SIZE)); // 大小
intduration = c.getInt(c.getColumnIndexOrThrow(MediaStore.Audio.Media.DURATION)); // 時長
inttime = c.getInt(c.getColumnIndexOrThrow(MediaStore.Audio.Media._ID)); // 歌曲的id
// int albumId = c.getInt(c.getColumnIndexOrThrow(MediaStore.Audio.Media.ALBUM_ID));
Music music = newMusic(name, path, album, artist, size, duration);
musics. add(music);
}
} catch(Exception e) {
e.printStackTrace();
} finally{
if(c != null) {
c.close();
}
}
returnmusics;
}
FileUtils中判斷檔案是否存在的方法isExists(String path),程式碼為:
/**
* 判斷檔案是否存在
* @parampath 檔案的路徑
* @return
*/
publicstaticbooleanisExists(String path){
File file = newFile(path);
returnfile.exists();
}
音樂的bean類Music程式碼為:
publicclassMusicimplementsComparable
/**歌曲名*/
privateString name;
/**路徑*/
privateString path;
/**所屬專輯*/
privateString album;
/**藝術家(作者)*/
privateString artist;
/**檔案大小*/
privatelongsize;
/**時長*/
privateintduration;
/**歌曲名的拼音,用於字母排序*/
privateString pinyin;
publicMusic(String name, String path, String album, String artist, longsize, intduration){
this.name = name;
this.path = path;
this.album = album;
this.artist = artist;
this.size = size;
this.duration = duration;
pinyin = PinyinUtils.getPinyin(name);
}
... //此處省略setter和getter方法
}
PinyinUtils根據名字獲取拼音,主要是用於音樂列表A-Z的排序,需要依賴pinyin4j.jar,獲取拼音的方法getPinyin(String name)程式碼為:
publicstaticString getPinyin(String str){
// 設定拼音結果的格式
HanyuPinyinOutputFormat format = newHanyuPinyinOutputFormat();
format.setCaseType(HanyuPinyinCaseType.UPPERCASE); // 設定為大寫形式
format.setToneType(HanyuPinyinToneType.WITHOUT_TONE); // 不用加入聲調
StringBuilder sb = newStringBuilder();
char[] charArray = str.toCharArray();
for( inti = 0; i < charArray.length; i++) {
charc = charArray[i];
if(Character.isWhitespace(c)) { // 如果是空格則跳過
continue;
}
if(isHanZi(c)) { // 如果是漢字
String s = "";
try{
// toHanyuPinyinStringArray 返回一個字串陣列是因為該漢字可能是多音字,此處只取第一個結果
s = PinyinHelper.toHanyuPinyinStringArray(c, format)[ 0];
sb.append(s);
} catch(BadHanyuPinyinOutputFormatCombination e) {
e.printStackTrace();
sb.append(s);
}
} else{
// 不是漢字
if(i == 0) {
if(isEnglish(c)) { // 第一個屬於字母,則返回該字母
returnString.valueOf(c).toUpperCase(Locale.ENGLISH);
}
return"#"; // 不是的話返回#號
}
}
}
returnsb.toString();
}
獲取視訊列表/**
* 獲取本機視訊列表
* @return
*/
privatestaticList{
List
Cursor c = null;
try{
// String[] mediaColumns = { "_id", "_data", "_display_name",
// "_size", "date_modified", "duration", "resolution" };
c = mContentResolver.query(MediaStore.Video.Media.EXTERNAL_CONTENT_URI, null, null, null, MediaStore.Video.Media.DEFAULT_SORT_ORDER);
while(c.moveToNext()) {
String path = c.getString(c.getColumnIndexOrThrow(MediaStore.Video.Media.DATA)); // 路徑
if(!FileUtils.isExists(path)) {
continue;
}
intid = c.getInt(c.getColumnIndexOrThrow(MediaStore.Video.Media._ID)); // 視訊的id
String name = c.getString(c.getColumnIndexOrThrow(MediaStore.Video.Media.DISPLAY_NAME)); // 視訊名稱
String resolution = c.getString(c.getColumnIndexOrThrow(MediaStore.Video.Media.RESOLUTION)); //解析度
longsize = c.getLong(c.getColumnIndexOrThrow(MediaStore.Video.Media.SIZE)); // 大小
longduration = c.getLong(c.getColumnIndexOrThrow(MediaStore.Video.Media.DURATION)); // 時長
longdate = c.getLong(c.getColumnIndexOrThrow(MediaStore.Video.Media.DATE_MODIFIED)); //修改時間
Video video = newVideo(id, path, name, resolution, size, date, duration);
videos. add(video);
}
} catch(Exception e) {
e.printStackTrace();
} finally{
if(c != null) {
c.close();
}
}
returnvideos;
}
其中,視訊的bean類Video程式碼為:
publicclassVideo{
privateintid = 0;
privateString path = null;
privateString name = null;
privateString resolution = null; // 解析度
privatelongsize = 0;
privatelongdate = 0;
privatelongduration = 0;
publicVideo(intid, String path, String name, String resolution, longsize, longdate, longduration) {
this.id = id;
this.path = path;
this.name = name;
this.resolution = resolution;
this.size = size;
this.date = date;
this.duration = duration;
}
... //此處省略setter和getter方法
}
通過本地視訊id獲取視訊縮圖// 獲取視訊縮圖
privatestaticBitmap getVideoThumbnail(intid) {
Bitmap bitmap = null;
BitmapFactory.Options options = newBitmapFactory.Options();
options.inDither = false;
options.inPreferredConfig = Bitmap.Config.ARGB_8888;
bitmap = MediaStore.Video.Thumbnails.getThumbnail(mContentResolver, id, MediaStore.Images.Thumbnails.MICRO_KIND, options);
returnbitmap;
}
上面獲取視訊列表的方法中,Video物件中有一個屬性是id,通過傳入這個id可以獲取到視訊縮圖的Bitmap物件。
獲取本機所有圖片資料夾/**
* 得到圖片資料夾集合
*/
private staticList
List
// 掃描圖片
Cursor c = null;
try{
c = mContentResolver.query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, null,
MediaStore.Images.Media.MIME_TYPE + "= ? or "+ MediaStore.Images.Media.MIME_TYPE + "= ?",
newString[]{ "image/jpeg", "image/png"}, MediaStore.Images.Media.DATE_MODIFIED);
List< String> mDirs = newArrayList< String>(); //用於儲存已經新增過的資料夾目錄
while(c.moveToNext()) {
Stringpath = c.getString(c.getColumnIndex(MediaStore.Images.Media.DATA)); // 路徑
File parentFile = newFile(path).getParentFile();
if(parentFile == null)
continue;
Stringdir = parentFile.getAbsolutePath();
if(mDirs.contains(dir)) //如果已經新增過
continue;
mDirs.add(dir); //新增到儲存目錄的集合中
ImgFolderBean folderBean = newImgFolderBean();
folderBean.setDir(dir);
folderBean.setFistImgPath(path);
if(parentFile.list() == null)
continue;
intcount = parentFile.list( newFilenameFilter() {
@Override
public boolean accept(File dir, Stringfilename) {
if(filename.endsWith( ".jpeg") || filename.endsWith( ".jpg") || filename.endsWith( ".png")) {
returntrue;
}
returnfalse;
}
}).length;
folderBean.setCount(count);
folders.add(folderBean);
}
} catch(Exception e) {
e.printStackTrace();
} finally{
if(c != null) {
c.close();
}
}
returnfolders;
}
其中,圖片資料夾的bean類ImgFolderBean程式碼為:
publicclassImgFolderBean{
/**當前資料夾的路徑*/
privateString dir;
/**第一張圖片的路徑,用於做資料夾的封面圖片*/
privateString fistImgPath;
/**資料夾名*/
privateString name;
/**資料夾中圖片的數量*/
privateintcount;
publicImgFolderBean(String dir, String fistImgPath, String name, intcount){
this.dir = dir;
this.fistImgPath = fistImgPath;
this.name = name;
this.count = count;
}
... //此處省略setter和getter方法
}
獲取圖片資料夾下的圖片路徑的集合/**
* 通過圖片資料夾的路徑獲取該目錄下的圖片
*/
private staticList< String> getImgListByDir( Stringdir) {
ArrayList< String> imgPaths = newArrayList<>();
File directory = newFile(dir);
if(directory == null|| !directory.exists()) {
returnimgPaths;
}
File[] files = directory.listFiles();
for(File file : files) {
Stringpath = file.getAbsolutePath();
if(FileUtils.isPicFile(path)) {
imgPaths.add(path);
}
}
returnimgPaths;
}
獲取本機已安裝應用列表/**
* 獲取已安裝apk的列表
*/
privatestaticList
ArrayList
//獲取到包的管理者
PackageManager packageManager = mContext.getPackageManager();
//獲得所有的安裝包
List
//遍歷每個安裝包,獲取對應的資訊
for(PackageInfo packageInfo : installedPackages) {
AppInfo appInfo = newAppInfo();
appInfo.setApplicationInfo(packageInfo.applicationInfo);
appInfo.setVersionCode(packageInfo.versionCode);
//得到icon
Drawable drawable = packageInfo.applicationInfo.loadIcon(packageManager);
appInfo.setIcon(drawable);
//得到程式的名字
String apkName = packageInfo.applicationInfo.loadLabel(packageManager).toString();
appInfo.setApkName(apkName);
//得到程式的包名
String packageName = packageInfo.packageName;
appInfo.setApkPackageName(packageName);
//得到程式的資原始檔夾
String sourceDir = packageInfo.applicationInfo.sourceDir;
File file = newFile(sourceDir);
//得到apk的大小
longsize = file.length();
appInfo.setApkSize(size);
System. out.println( "---------------------------");
System. out.println( "程式的名字:"+ apkName);
System. out.println( "程式的包名:"+ packageName);
System. out.println( "程式的大小:"+ size);
//獲取到安裝應用程式的標記
intflags = packageInfo.applicationInfo.flags;
if((flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
//表示系統app
appInfo.setIsUserApp( false);
} else{
//表示使用者app
appInfo.setIsUserApp( true);
}
if((flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
//表示在sd卡
appInfo.setIsRom( false);
} else{
//表示記憶體
appInfo.setIsRom( true);
}
appInfos. add(appInfo);
}
returnappInfos;
}
其中,安裝包資訊的bean類AppInfo程式碼為:
publicclassAppInfo{
privateApplicationInfo applicationInfo;
privateintversionCode = 0;
/**
* 圖片的icon
*/
privateDrawable icon;
/**
* 程式的名字
*/
privateString apkName;
/**
* 程式大小
*/
privatelongapkSize;
/**
* 表示到底是使用者app還是系統app
* 如果表示為true 就是使用者app
* 如果是false表示系統app
*/
privateboolean isUserApp;
/**
* 放置的位置
*/
privateboolean isRom;
/**
* 包名
*/
privateString apkPackageName;
... //此處省略setter和getter方法
}
獲取文件、壓縮包、apk安裝包等/**
* 通過檔案型別得到相應檔案的集合
**/
privatestaticList
List
// 掃描files檔案庫
Cursor c = null;
try{
c = mContentResolver.query(MediaStore.Files.getContentUri( "external"), newString[]{ "_id", "_data", "_size"}, null, null, null);
intdataindex = c.getColumnIndex(MediaStore.Files.FileColumns.DATA);
intsizeindex = c.getColumnIndex(MediaStore.Files.FileColumns.SIZE);
while(c.moveToNext()) {
String path = c.getString(dataindex);
if(FileUtils.getFileType(path) == fileType) {
if(!FileUtils.isExists(path)) {
continue;
}
longsize = c.getLong(sizeindex);
FileBean fileBean = newFileBean(path, FileUtils.getFileIconByPath(path));
files. add(fileBean);
}
}
} catch(Exception e) {
e.printStackTrace();
} finally{
if(c != null) {
c.close();
}
}
returnfiles;
}
傳入的fileType檔案型別是在FileUtils定義的檔案型別宣告:
/**文件型別*/
publicstaticfinal intTYPE_DOC = 0;
/**apk型別*/
publicstaticfinal intTYPE_APK = 1;
/**壓縮包型別*/
publicstaticfinal intTYPE_ZIP = 2;
其中,FileUtils根據檔案路徑獲取檔案型別的方法getFileType(String path)為:
public static int getFileType(String path) {
path= path.toLowerCase();
if( path.endsWith( ".doc") || path.endsWith( ".docx") || path.endsWith( ".xls") || path.endsWith( ".xlsx")
|| path.endsWith( ".ppt") || path.endsWith( ".pptx")) {
returnTYPE_DOC;
} elseif( path.endsWith( ".apk")) {
returnTYPE_APK;
} elseif( path.endsWith( ".zip") || path.endsWith( ".rar") || path.endsWith( ".tar") || path.endsWith( ".gz")) {
returnTYPE_ZIP;
} else{
return-1;
}
}
檔案的bean類FileBean程式碼為:
publicclassFileBean{
/** 檔案的路徑*/
publicString path;
/**檔案圖片資源的id,drawable或mipmap檔案中已經存放doc、xml、xls等檔案的圖片*/
publicinticonId;
publicFileBean(String path, inticonId){
this.path = path;
this.iconId = iconId;
}
}
FileUtils根據檔案型別獲取圖片資源id的方法,getFileIconByPath(path)程式碼為:
/**通過檔名獲取檔案圖示*/
public static int getFileIconByPath(String path){
path= path.toLowerCase();
int iconId = R.mipmap.unknow_file_icon;
if( path.endsWith( ".txt")){
iconId = R.mipmap.type_txt;
} elseif( path.endsWith( ".doc") || path.endsWith( ".docx")){
iconId = R.mipmap.type_doc;
} elseif( path.endsWith( ".xls") || path.endsWith( ".xlsx")){
iconId = R.mipmap.type_xls;
} elseif( path.endsWith( ".ppt") || path.endsWith( ".pptx")){
iconId = R.mipmap.type_ppt;
} elseif( path.endsWith( ".xml")){
iconId = R.mipmap.type_xml;
} elseif( path.endsWith( ".htm") || path.endsWith( ".html")){
iconId = R.mipmap.type_html;
}
returniconId;
}
上述各種檔案型別的圖片放置在mipmap中,用於展示檔案列表時展示。
FileManager以及其他類的原始碼,可以點選下面的網址跳轉檢視和下載。
檢視原始碼:
https://github.com/chaychan/BlogFileResource/tree/master/phone