You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android 11设备出现java.lang.IllegalArgumentException存储设备查找异常求助

Android 11下存储设备检测崩溃的解决方法

问题概述

在Android 11设备上启动应用时,SplashActivity触发崩溃,错误堆栈显示java.lang.IllegalArgumentException: Failed to find storage device at null,该错误由Environment.isExternalStorageRemovable(file)方法抛出,且网上相关排查信息极少。

错误原因分析

  1. getExternalCacheDirs()返回null元素:部分Android 11设备的系统实现中,Context.getExternalCacheDirs()返回的数组可能包含null项,代表无效的存储路径。
  2. 未做null校验直接传参:原代码未检查循环中的file是否为null,直接传入Environment.isExternalStorageRemovable(),该方法在参数为null时会抛出IllegalArgumentException。
  3. 异常捕获范围不足:原代码仅捕获NullPointerException,未覆盖IllegalArgumentException,导致崩溃无法被拦截。

解决方案

核心修改点

  • 遍历存储路径时先过滤null项
  • 扩展异常捕获范围,覆盖IllegalArgumentException
  • 对getExternalCacheDir()的返回值做null校验,避免后续StatFs初始化崩溃

修改后的代码

void initSaveDataFolder() {
    if (SecurityPreferences.getAutoChosseFolder()) {
        File[] externalCacheDirs = App.get().getExternalCacheDirs();
        // 先判断数组是否为空
        if (externalCacheDirs != null) {
            for (File file : externalCacheDirs) {
                // 跳过null的存储路径
                if (file == null) {
                    continue;
                }
                try {
                    if (Environment.isExternalStorageRemovable(file)) {
                        StatFs stat = new StatFs(file.getAbsolutePath());
                        long bytesAvailableInSdCard = (long) stat.getBlockSize() * (long) stat.getAvailableBlocks();
                        
                        // 检查内部缓存目录是否有效
                        File internalCacheDir = App.get().getExternalCacheDir();
                        if (internalCacheDir == null) {
                            SecurityPreferences.setIsSaveDataOnUsb(false);
                            break;
                        }
                        
                        StatFs stat2 = new StatFs(internalCacheDir.getAbsolutePath());
                        long bytesAvailableInInternalMemory = (long) stat2.getBlockSize() * (long) stat2.getAvailableBlocks();
                        
                        SecurityPreferences.setIsSaveDataOnUsb(bytesAvailableInSdCard > bytesAvailableInInternalMemory);
                        System.out.println("memoryes is " + bytesAvailableInSdCard + " " + bytesAvailableInInternalMemory);
                        SecurityPreferences.saveAutoChosseFolder(true);
                        break;
                    }
                } catch (NullPointerException | IllegalArgumentException e) {
                    // 同时捕获空指针和非法参数异常
                    SecurityPreferences.setIsSaveDataOnUsb(false);
                    break;
                }
            }
        } else {
            // 当存储路径数组为空时,默认保存到内部存储
            SecurityPreferences.setIsSaveDataOnUsb(false);
        }
    }
}

权限优化建议

原权限声明中的READ_INTERNAL_STORAGE是多余的,Android应用默认拥有内部存储的读写权限,可移除该权限:

<uses-permission
    android:name="android.permission.WRITE_EXTERNAL_STORAGE"
    tools:ignore="ScopedStorage" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

内容的提问来源于stack exchange,提问作者pavkabrika

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.14 14:56:28