Android 获取内外SD卡路径几种方法总结

今天做项目的时候发现获取存储的方式不一样,搞了一个上午,计算sd卡的容量.总结一下.以免后面走弯路

Android 获取SD卡路径:

外置sd卡路径,也许很多同学在平时的工作中并不会用到,因为现在很多机型都不支持外置sd卡(这也是Google目标),所以并不用考虑外置sd卡的路径问题。除了开发文件管理类的应用之外,其他应用使用 Enviroment

方法一:

//内置sd卡路径
String sdcardPath = System.getenv("EXTERNAL_STORAGE"); 
//内置sd卡路径
String sdcardPath = Environment.getExternalStorageDirectory().getAbsolutePath();
//外置置sd卡路径
String extSdcardPath = System.getenv("SECONDARY_STORAGE");

不过在编写过程中发现在API 23版本中 SECONDARY_STORAGE 被移除。
所以我们只能通过发射拿到外置和内置sd卡的路径
反射的方式使用在sdk中被 隐藏 的类 StroageVolume 中的方法getVolumeList(),获取所有的存储空间(Stroage Volume),然后通过参数is_removable控制,来获取内部存储和外部存储(内外sd卡)的路径,参数 is_removable为false时得到的是内置sd卡路径,为true则为外置sd卡路径。
代码如下:

/**
     * 通过反射调用获取内置存储和外置sd卡根路径(通用)
     *
     * @param mContext    上下文
     * @param is_removale 是否可移除,false返回内部存储路径,true返回外置SD卡路径
     * @return
     */
    public static String getStoragePath(Context mContext, boolean is_removale) {
        String path = "";
        //使用getSystemService(String)检索一个StorageManager用于访问系统存储功能。
        StorageManager mStorageManager = (StorageManager) mContext.getSystemService(Context.STORAGE_SERVICE);
        Class<?> storageVolumeClazz = null;
        try {
            storageVolumeClazz = Class.forName("android.os.storage.StorageVolume");
            Method getVolumeList = mStorageManager.getClass().getMethod("getVolumeList");
            Method getPath = storageVolumeClazz.getMethod("getPath");
            Method isRemovable = storageVolumeClazz.getMethod("isRemovable");
            Object result = getVolumeList.invoke(mStorageManager);

            for (int i = 0; i < Array.getLength(result); i++) {
                Object storageVolumeElement = Array.get(result, i);
                path = (String) getPath.invoke(storageVolumeElement);
                boolean removable = (Boolean) isRemovable.invoke(storageVolumeElement);
                if (is_removale == removable) {
                    return path;
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return path;
    }

方法二
我也总结了一下一种方式,判断是否存在外置sd卡

//判断是否存在外置tf卡
    public static boolean isStorageTf(Context context) {
        try {
            StorageManager sm = (StorageManager) context.getSystemService(Context.STORAGE_SERVICE);
            Method getVolumeStateMethod = StorageManager.class.getMethod("getVolumeState", new Class[]{String.class});
            String state = (String) getVolumeStateMethod.invoke(sm, getTfStoragePath(context));
            if (state.equals(Environment.MEDIA_MOUNTED)) {
                return true;
            }
        } catch (Exception e) {
            Log.e("TF error", "not find tf", e);
        }
        return false;
    }

    //获取外置tf卡路径
    public static String getTfStoragePath(Context context) {

        try {
            @SuppressLint("WrongConstant")
            StorageManager sm = (StorageManager) context.getSystemService("storage");
            Method getVolumePathsMethod = StorageManager.class.getMethod("getVolumePaths", new Class[0]);
            String[] paths = (String[]) getVolumePathsMethod.invoke(sm, new Object[]{});
            // second element in paths[] is secondary storage path
            return paths[1];
        } catch (Exception e) {
            Log.e("TF error", "get Tf failed", e);
        }
        return null;
    }

拿到了外部sd卡,我们就可以计算容量了

以下是我个人用到的

/**
     * 获取Sd卡的状态
     *
     * @return
     */
    public static String getSDAllSize(Context context) {

        long GB = 1024 * 1024 * 1024;//定义GB的计算常量
        long MB = 1024 * 1024;//定义MB的计算常量
        long KB = 1024;//定义KB的计算常量
        DecimalFormat df = new DecimalFormat("0.00");//格式化小数
        if (!isStorageTf(context)) {
            return "0GB";
        }
        // File path = Environment.getExternalStorageDirectory();
        // Log.e(TAG, "getSDAllSize:path: " + path);
        String path1 = getTfStoragePath(context);
        StatFs sf = new StatFs(path1);
        long blockSize = sf.getBlockSize();
        long allBlocks = sf.getBlockCount();
        long freeBlocks = sf.getAvailableBlocks();
        // 总空间
        String totalMemory = df.format((allBlocks * blockSize) / (float) GB) + "GB";
        // 可用空间
        String availableMemory = df.format((freeBlocks * blockSize) / (float) GB) + "GB";

        return availableMemory + "/" + totalMemory;
        //return (allBlocks * blockSize) / 1024 / 1024 + "GB"; //单位G

    }
  • 1
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值