首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

Android 開發:File.mkdirs() 創建目錄失效的常見原因與解決方案

     編輯:程式設計綜合問答

問題現象

調用 file.mkdirs() 創建目錄 /sdcard/AllAroundMe/Images,代碼邏輯判斷 !file.exists() 進入創建分支,但後續 file.exists() 仍為 false,目錄未實際創建成功。

核心原因排查

  1. 缺少存儲權限:Android 6.0+ 需動態申請 WRITE_EXTERNAL_STORAGE,清單文件聲明不足夠。
  2. 路徑拼接錯誤:Environment.getExternalStorageDirectory() + "/AllAroundMe/Images" 字符串拼接易出錯,推薦使用 File 構造函數。
  3. 外部存儲不可用:設備無 SD 卡、SD 卡掛載為只讀、被電腦掛載(MTP)、存儲空間滿。
  4. 應用專用目錄替代:Android 10+ (API 29) 限制訪問公共外部存儲,推薦使用 getExternalFilesDir()。

標準解決方案

1. 清單文件聲明權限


<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<!-- Android 10+ 適配 -->
<application android:requestLegacyExternalStorage="true" ... >

2. 動態申請權限 (API 23+)


if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) 
        != PackageManager.PERMISSION_GRANTED) {
    ActivityCompat.requestPermissions(this, 
        new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 
        REQUEST_CODE_STORAGE);
} else {
    createDirectory();
}

3. 正確路徑構建與創建


private void createDirectory() {
    // 推薦:使用應用專用外部存儲目錄(無需權限、自動清理、Android 10+ 兼容)
    File dir = new File(getExternalFilesDir(Environment.DIRECTORY_PICTURES), "AllAroundMe/Images");
    
    // 或兼容舊版:公共目錄(需權限)
    // File dir = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES), "AllAroundMe/Images");
    
    if (!dir.exists()) {
        boolean success = dir.mkdirs();
        Log.d("MyTag", "Create dir: " + dir.getAbsolutePath() + " success=" + success);
    }
    
    if (dir.exists()) {
        Log.d("MyTag", "Dir exists: " + dir.getAbsolutePath());
    }
}

路徑構建最佳實踐對比

方式代碼示例優點缺點
字符串拼接Environment.getExternalStorageDirectory() + "/xxx"直觀跨平台分隔符問題、易出錯
File 構造函數new File(baseDir, "subdir")自動處理分隔符、可讀性好需確保 baseDir 非 null
getExternalFilesDir()getExternalFilesDir(Environment.DIRECTORY_PICTURES)無需權限、應用專用、協卸載自動刪除用戶不可直接在相冊看到
getExternalCacheDir()getExternalCacheDir()臨時文件、系統可自動清理非持久化存儲

Android 10+ (API 29) 存儲適配重點

  • 分區存儲:應用默認只能訪問自有目錄(getExternalFilesDir()、MediaStore)。
  • MediaStore:保存圖片/視頻/音頻到公共媒體集合,用戶可在相冊看到,需使用 MediaStore.Images.Media.insertImage 或 ContentResolver.insert。
  • requestLegacyExternalStorage:AndroidManifest.xml 中 application 標籤添加 android:requestLegacyExternalStorage="true" 可暫時繼續使用舊模式(Android 10 有效,Android 11+ 無效)。
  • SAF (Storage Access Framework):用戶通過系統選擇器授權特定目錄訪問權限。

調試技巧


// 檢查存儲狀態
String state = Environment.getExternalStorageState();
Log.d("Storage", "State: " + state); // MEDIA_MOUNTED 表示可讀寫

// 檢查目錄對象
File dir = new File(...);
Log.d("Dir", "exists=" + dir.exists() + " isDir=" + dir.isDirectory() + " canWrite=" + dir.canWrite() + " absPath=" + dir.getAbsolutePath());
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved