Android版本6.0以上SD卡相关方法(反射)
1. 概述
- 主要是获取SD外置存储卡的相关方法;
- 获取内置存储卡视频或者图片大小;
- 千万注意: 首先要申请Android的读取权限;
2. 获取SD卡路径方法
1) 获取StorageManager的实例
StorageManager storageManager = (StorageManager) context.getSystemService(Context.STORAGE_SERVICE);
2) 通过反射获取存储卡的集合
// 反射获取存储卡的集合
Method getVolumeList = StorageManager.class.getDeclaredMethod("getVolumeList");
List<Object> getVolumeInfo = (List<Object>) getVolumes.invoke(storageManager);
// 反射获取SD卡的类型
// 1. TYPE_PRIVATE 内部存储
// 2. TYPE_PUBLIC 外部存储(这就是我们需要获取的SD卡)
Field getType = obj.getClass().getField("type");
3) 通过反射获取是否可读以及存储卡路径
// 1. 是否可读(可读可以获取SD卡的路径以及总内存和剩余内存)
Method isMountedReadable = obj.getClass().getDeclaredMethod("isMountedReadable");
boolean readable = (boolean) isMountedReadable.invoke(obj);
// 2. 获取SD卡路径
Method file = obj.getClass().getDeclaredMethod("getPath");
File f = (File) file.invoke(obj);
// 3. 根据路径获取总内存以及剩余内存
long total = f.getTotalSpace();
long used = f.getFreeSpace();
3. 格式化以及挂载的方法(一般都是搭配使用)
// 1. 反射格式化的方法
Method format = StorageManager.class.getDeclaredMethod("format", String.class);
format.invoke(storageManager, id);
// 2. 反射挂载的方法
Method mount = StorageManager.class.getDeclaredMethod("mount", new Class[]{String.class});
mount.invoke(storageManager, id);
PS: 遍历内置存储卡所有视频以及图片(以视频为例)
注意: 外置存储卡目前我没找到方法测试
// 1. 通过上下文获取ContentResolver
ContentResolver resolver = context.getContentResolver();
// 2. 创建想要查询的内容数组(拿视频为例)
// 名称 、 大小 、 路径
String[] querys = new String[]{MediaStore.Video.Media.DISPLAY_NAME,
MediaStore.Video.Media.SIZE, MediaStore.Video.Media.DATA};;
// 3. 创建Uri
Urli uri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
// 4. 开始查询(注意 cursor可能为空,需要注意判空)
Cursor cursor = resolver.query(uri, querys, null, null, null);
// 5 . 开始查询(注意是根据querys一一对应的)
String displayName = cursor.getString(0);
int siz = cursor.getInt(1);
String data = cursor.getString(2);
// 可以打印这些数据查看
最后: 附详细代码
public class StorageUtils {
private final static String TAG = "StorageUtils";
// 是否有外置存储卡
public static boolean hasSd = false;
public static StorageManager storageManager;
public static boolean initSd(Context context) {
storageManager = (StorageManager) context.getSystemService(Context.STORAGE_SERVICE);
// 1000单位,个人测过的大部分是以1000为单位的,部分是1024,实际使用可以自己测试下
float unit = 1000;
try {
Method getVolumes = StorageManager.class.getDeclaredMethod("getVolumes");
List<Object> getVolumeInfo = (List<Object>) getVolumes.invoke(storageManager);
if (null != getVolumeInfo && getVolumeInfo.size() > 0) {
for (int i = 0; i < getVolumeInfo.size(); i++) {
Object obj = getVolumeInfo.get(i);
Field getType = obj.getClass().getField("type");
int type = getType.getInt(obj);
if (type == 0) {//TYPE_PUBLIC
//外置存储
Method isMountedReadable = obj.getClass().getDeclaredMethod("isMountedReadable");
boolean readable = (boolean) isMountedReadable.invoke(obj);
if (readable) {
hasSd = true;
Method file = obj.getClass().getDeclaredMethod("getPath");
File f = (File) file.invoke(obj);
//外置存储
String path = getPath(obj);
long total = f.getTotalSpace();
long free = f.getFreeSpace();
Log.e(TAG, "外置:" + path + ",total:" + getUnit(total, unit) + ",free:" + getUnit(free, unit));
}
}
}
return true;
}
} catch (SecurityException e) {
Log.e(TAG, "请检查权限");
} catch (Exception e) {
e.printStackTrace();
}
return false;
}
private static String getPath(Object obj) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {
String sdPath = "";
Method isMountedReadable = obj.getClass().getDeclaredMethod("isMountedReadable");
boolean readable = (boolean) isMountedReadable.invoke(obj);
if (readable) {
Method file = obj.getClass().getDeclaredMethod("getPath");
File f = (File) file.invoke(obj);
sdPath = f.getPath();
}
return sdPath;
}
// 获取外置存储卡视频的大小
public static long getVideoSize(Context context) {
//获取ContentResolver实例
long total = 0;
ContentResolver resolver = context.getContentResolver();
// 视频为例: 需要查询的内容->名称,大小,路径
String[] querys= new String[]{MediaStore.Video.Media.DISPLAY_NAME,
MediaStore.Video.Media.SIZE, MediaStore.Video.Media.DATA};
Uri uri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
//开始查询,查询结果是一个cursor对象
Cursor cursor = resolver.query(uri, querys, null, null, null);
//若查询的Uri不存在,则cursor为空,所以要做非空判断
if (cursor != null) {
while (cursor.moveToNext()) {
// 判断路径
String displayName = cursor.getString(0);
int size = cursor.getInt(1);
String filePath = cursor.getString(2);
total += size;
Log.e(TAG,"name:"+displayName+",size:"+size+",path:"+filePath);
}
//记得关闭cursor
cursor.close();
Log.e(TAG,"video total size:"+total);
}
return total;
}
// 格式化SD卡以及挂载
private static void format(String id) {
try {
Method format = StorageManager.class.getDeclaredMethod("format", String.class);
Method mount = StorageManager.class.getDeclaredMethod("mount", new Class[]{String.class});
format.invoke(storageManager, id);
mount.invoke(storageManager, id);
} catch (Exception e) {
e.printStackTrace();
}
}
private static final String[] units = {"B", "KB", "MB", "GB", "TB"};
/**
* 进制转换
*/
public static String getUnit(float size, float base) {
int index = 0;
while (size > base && index < 4) {
size = size / base;
index++;
}
return String.format(Locale.getDefault(), " %.2f %s ", size, units[index]);
}
}
网友评论