Android获取本机各种类型文件的方法
作者:Chay_Chan
介绍
本篇介绍Android获取本机各种类型文件的方法,已经封装成工具类,末尾有源码下载地址。
提示
获取音乐、视频、图片、文档等文件是需要有读取SD卡的权限的,如果是6.0以下的系统,则直接在清单文件中声明SD卡读取权限即可;如果是6.0或以上,则需要动态申请权限。
FileManager的使用
FileManager是封装好的用于获取本机各类文件的工具类,使用方式如:FileManager.getInstance(Context context).getMusics(),使用的是单例模式创建:
private static FileManager mInstance; private static Context mContext; public static ContentResolver mContentResolver; private static Object mLock = new Object(); public static FileManager getInstance(Context context){ if (mInstance == null){ synchronized (mLock){ if (mInstance == null){ mInstance = new FileManager(); mContext = context; mContentResolver = context.getContentResolver(); } } } return mInstance; }
获取音乐列表
/** * 获取本机音乐列表 * @return */ private static List<Music> getMusics() { ArrayList<Music> musics = new 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)); // 作者 long size = c.getLong(c.getColumnIndexOrThrow(MediaStore.Audio.Media.SIZE));// 大小 int duration = c.getInt(c.getColumnIndexOrThrow(MediaStore.Audio.Media.DURATION));// 时长 int time = c.getInt(c.getColumnIndexOrThrow(MediaStore.Audio.Media._ID));// 歌曲的id // int albumId = c.getInt(c.getColumnIndexOrThrow(MediaStore.Audio.Media.ALBUM_ID)); Music music = new Music(name, path, album, artist, size, duration); musics.add(music); } } catch (Exception e) { e.printStackTrace(); } finally { if (c != null) { c.close(); } } return musics; }
FileUtils中判断文件是否存在的方法isExists(String path),代码为:
/** * 判断文件是否存在 * @param path 文件的路径 * @return */ public static boolean isExists(String path) { File file = new File(path); return file.exists(); }
音乐的bean类Music代码为:
public class Music implements Comparable<Music> { /**歌曲名*/ private String name; /**路径*/ private String path; /**所属专辑*/ private String album; /**艺术家(作者)*/ private String artist; /**文件大小*/ private long size; /**时长*/ private int duration; /**歌曲名的拼音,用于字母排序*/ private String pinyin; public Music(String name, String path, String album, String artist, long size, int duration) { 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)代码为:
public static String getPinyin(String str) { // 设置拼音结果的格式 HanyuPinyinOutputFormat format = new HanyuPinyinOutputFormat(); format.setCaseType(HanyuPinyinCaseType.UPPERCASE);// 设置为大写形式 format.setToneType(HanyuPinyinToneType.WITHOUT_TONE);// 不用加入声调 StringBuilder sb = new StringBuilder(); char[] charArray = str.toCharArray(); for (int i = 0; i < charArray.length; i++) { char c = 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)) {// 第一个属于字母,则返回该字母 return String.valueOf(c).toUpperCase(Locale.ENGLISH); } return "#"; // 不是的话返回#号 } } } return sb.toString(); }
获取视频列表
/** * 获取本机视频列表 * @return */ private static List<Video> getVideos() { List<Video> videos = new ArrayList<Video>(); 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; } int id = 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)); //分辨率 long size = c.getLong(c.getColumnIndexOrThrow(MediaStore.Video.Media.SIZE));// 大小 long duration = c.getLong(c.getColumnIndexOrThrow(MediaStore.Video.Media.DURATION));// 时长 long date = c.getLong(c.getColumnIndexOrThrow(MediaStore.Video.Media.DATE_MODIFIED));//修改时间 Video video = new Video(id, path, name, resolution, size, date, duration); videos.add(video); } } catch (Exception e) { e.printStackTrace(); } finally { if (c != null) { c.close(); } } return videos; }
其中,视频的bean类Video代码为:
public class Video { private int id = 0; private String path = null; private String name = null; private String resolution = null;// 分辨率 private long size = 0; private long date = 0; private long duration = 0; public Video(int id, String path, String name, String resolution, long size, long date, long duration) { this.id = id; this.path = path; this.name = name; this.resolution = resolution; this.size = size; this.date = date; this.duration = duration; } ... //此处省略setter和getter方法 }
通过本地视频id获取视频缩略图
// 获取视频缩略图 private static Bitmap getVideoThumbnail(int id) { Bitmap bitmap = null; BitmapFactory.Options options = new BitmapFactory.Options(); options.inDither = false; options.inPreferredConfig = Bitmap.Config.ARGB_8888; bitmap = MediaStore.Video.Thumbnails.getThumbnail(mContentResolver, id, MediaStore.Images.Thumbnails.MICRO_KIND, options); return bitmap; }
上面获取视频列表的方法中,Video对象中有一个属性是id,通过传入这个id可以获取到视频缩略图的Bitmap对象。
获取本机所有图片文件夹
/** * 得到图片文件夹集合 */ private static List<ImgFolderBean> getImageFolders() { List<ImgFolderBean> folders = new ArrayList<ImgFolderBean>(); // 扫描图片 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 + "= ?", new String[]{"image/jpeg", "image/png"}, MediaStore.Images.Media.DATE_MODIFIED); List<String> mDirs = new ArrayList<String>();//用于保存已经添加过的文件夹目录 while (c.moveToNext()) { String path = c.getString(c.getColumnIndex(MediaStore.Images.Media.DATA));// 路径 File parentFile = new File(path).getParentFile(); if (parentFile == null) continue; String dir = parentFile.getAbsolutePath(); if (mDirs.contains(dir))//如果已经添加过 continue; mDirs.add(dir);//添加到保存目录的集合中 ImgFolderBean folderBean = new ImgFolderBean(); folderBean.setDir(dir); folderBean.setFistImgPath(path); if (parentFile.list() == null) continue; int count = parentFile.list(new FilenameFilter() { @Override public boolean accept(File dir, String filename) { if (filename.endsWith(".jpeg") || filename.endsWith(".jpg") || filename.endsWith(".png")) { return true; } return false; } }).length; folderBean.setCount(count); folders.add(folderBean); } } catch (Exception e) { e.printStackTrace(); } finally { if (c != null) { c.close(); } } return folders; }
其中,图片文件夹的bean类ImgFolderBean代码为:
public class ImgFolderBean { /**当前文件夹的路径*/ private String dir; /**第一张图片的路径,用于做文件夹的封面图片*/ private String fistImgPath; /**文件夹名*/ private String name; /**文件夹中图片的数量*/ private int count; public ImgFolderBean(String dir, String fistImgPath, String name, int count) { this.dir = dir; this.fistImgPath = fistImgPath; this.name = name; this.count = count; } ... //此处省略setter和getter方法 }
获取图片文件夹下的图片路径的集合
/** * 通过图片文件夹的路径获取该目录下的图片 */ private static List<String> getImgListByDir(String dir) { ArrayList<String> imgPaths = new ArrayList<>(); File directory = new File(dir); if (directory == null || !directory.exists()) { return imgPaths; } File[] files = directory.listFiles(); for (File file : files) { String path = file.getAbsolutePath(); if (FileUtils.isPicFile(path)) { imgPaths.add(path); } } return imgPaths; }
获取本机已安装应用列表
/** * 获取已安装apk的列表 */ private static List<AppInfo> getAppInfos() { ArrayList<AppInfo> appInfos = new ArrayList<AppInfo>(); //获取到包的管理者 PackageManager packageManager = mContext.getPackageManager(); //获得所有的安装包 List<PackageInfo> installedPackages = packageManager.getInstalledPackages(0); //遍历每个安装包,获取对应的信息 for (PackageInfo packageInfo : installedPackages) { AppInfo appInfo = new AppInfo(); 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 = new File(sourceDir); //得到apk的大小 long size = file.length(); appInfo.setApkSize(size); System.out.println("---------------------------"); System.out.println("程序的名字:" + apkName); System.out.println("程序的包名:" + packageName); System.out.println("程序的大小:" + size); //获取到安装应用程序的标记 int flags = 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); } return appInfos; }
其中,安装包信息的bean类AppInfo代码为:
public class AppInfo { private ApplicationInfo applicationInfo; private int versionCode = 0; /** * 图片的icon */ private Drawable icon; /** * 程序的名字 */ private String apkName; /** * 程序大小 */ private long apkSize; /** * 表示到底是用户app还是系统app * 如果表示为true 就是用户app * 如果是false表示系统app */ private boolean isUserApp; /** * 放置的位置 */ private boolean isRom; /** * 包名 */ private String apkPackageName; ... //此处省略setter和getter方法 }
获取文档、压缩包、apk安装包等
/** * 通过文件类型得到相应文件的集合 **/ private static List<FileBean> getFilesByType(int fileType) { List<FileBean> files = new ArrayList<FileBean>(); // 扫描files文件库 Cursor c = null; try { c = mContentResolver.query(MediaStore.Files.getContentUri("external"), new String[]{"_id", "_data", "_size"}, null, null, null); int dataindex = c.getColumnIndex(MediaStore.Files.FileColumns.DATA); int sizeindex = c.getColumnIndex(MediaStore.Files.FileColumns.SIZE); while (c.moveToNext()) { String path = c.getString(dataindex); if (FileUtils.getFileType(path) == fileType) { if (!FileUtils.isExists(path)) { continue; } long size = c.getLong(sizeindex); FileBean fileBean = new FileBean(path, FileUtils.getFileIconByPath(path)); files.add(fileBean); } } } catch (Exception e) { e.printStackTrace(); } finally { if (c != null) { c.close(); } } return files; }
传入的fileType文件类型是在FileUtils定义的文件类型声明:
/**文档类型*/ public static final int TYPE_DOC = 0; /**apk类型*/ public static final int TYPE_APK = 1; /**压缩包类型*/ public static final int TYPE_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")) { return TYPE_DOC; }else if (path.endsWith(".apk")) { return TYPE_APK; }else if (path.endsWith(".zip") || path.endsWith(".rar") || path.endsWith(".tar") || path.endsWith(".gz")) { return TYPE_ZIP; }else{ return -1; } }
文件的bean类FileBean代码为:
public class FileBean { /** 文件的路径*/ public String path; /**文件图片资源的id,drawable或mipmap文件中已经存放doc、xml、xls等文件的图片*/ public int iconId; public FileBean(String path, int iconId) { 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; }else if(path.endsWith(".doc") || path.endsWith(".docx")){ iconId = R.mipmap.type_doc; }else if(path.endsWith(".xls") || path.endsWith(".xlsx")){ iconId = R.mipmap.type_xls; }else if(path.endsWith(".ppt") || path.endsWith(".pptx")){ iconId = R.mipmap.type_ppt; }else if(path.endsWith(".xml")){ iconId = R.mipmap.type_xml; }else if(path.endsWith(".htm") || path.endsWith(".html")){ iconId = R.mipmap.type_html; } return iconId; }
上述各种文件类型的图片放置在mipmap中,用于展示文件列表时展示。
FileManager以及其他类的源码,可以点击下面的网址跳转查看和下载:
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。