美文网首页
Android版本6.0以上SD卡相关方法

Android版本6.0以上SD卡相关方法

作者: KevinGarnett21 | 来源:发表于2021-09-13 20:04 被阅读0次

Android版本6.0以上SD卡相关方法(反射)

1. 概述

  1. 主要是获取SD外置存储卡的相关方法;
  2. 获取内置存储卡视频或者图片大小;
  3. 千万注意: 首先要申请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]);
    }

}

相关文章

网友评论

      本文标题:Android版本6.0以上SD卡相关方法

      本文链接:https://www.haomeiwen.com/subject/funfgltx.html