首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Android 讀寫 SD 卡檔案完整指南:權限、路徑與實作範例

     編輯:Java 相關知識

前言

在 Android 開發中,存取 SD 卡(外部儲存裝置)是常見需求。雖然底層 Java IO API 與標準 Java 無異,但 Android 的權限機制與儲存路徑解析有其特殊規則。本文整理完整流程,並提供兩種路徑取得方式與可直接執行的寫入範例。

一、核心前置作業:聲明權限

Android 6.0 (API 23) 以上需動態申請,但清單檔仍必須宣告:

<!-- AndroidManifest.xml -->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<!-- Android 10+ 讀取媒體檔案另需 -->
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

注意:Android 10 (API 29) 引入分區儲存,建議改用 MediaStore 或 getExternalFilesDir() 以相容新版政策。

二、取得 SD 卡路徑的兩種方式

方式 1:硬編碼路徑(不推薦,僅供舊版參考)

// 早期裝置常見掛載點,新版裝置可能不存在或無權存取
final String FILE_NAME = "/mnt/sdcard/00000.H264";

缺點:裝置碎片化嚴重,路徑可能為 /storage/emulated/0、/sdcard 等,極易失效。

方式 2:透過系統 API 動態取得(標準作法)

// 取得主要外部儲存目錄(通常指 /storage/emulated/0)
File sdDir = Environment.getExternalStorageDirectory();
String filePath = sdDir.getCanonicalPath() + "/your_file_name.txt";

優點:跨裝置相容、自動處理多使用者/工作資料夾隔離。

三、檔案寫入完整範例(採方式 2 + 緩衝流)

public class FileTestActivity extends AppCompatActivity {
    private static final String FILE_NAME = "app_data.txt";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Button btnWrite = findViewById(R.id.btn_write);
        btnWrite.setOnClickListener(v -> writeToSdCard());
    }

    private void writeToSdCard() {
        // 1. 確認儲存狀態可寫
        if (!Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())) {
            Toast.makeText(this, "SD 卡不可用", Toast.LENGTH_SHORT).show();
            return;
        }

        // 2. 取得檔案物件(建議使用 getExternalFilesDir() 避免權限問題)
        File file = new File(getExternalFilesDir(null), FILE_NAME);
        // 若需對其他 App 可見,改用 Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOCUMENTS)

        // 3. 使用 try-with-resources 自動關閉資源 (Java 7+)
        try (FileOutputStream fos = new FileOutputStream(file, true); // true = 附加模式
             BufferedOutputStream bos = new BufferedOutputStream(fos)) {

            String content = "寫入時間:" + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.getDefault()).format(new Date()) + "\n";
            bos.write(content.getBytes(StandardCharsets.UTF_8));
            bos.flush();
            Toast.makeText(this, "寫入成功:" + file.getAbsolutePath(), Toast.LENGTH_LONG).show();

        } catch (IOException e) {
            e.printStackTrace();
            Toast.makeText(this, "寫入失敗:" + e.getMessage(), Toast.LENGTH_SHORT).show();
        }
    }
}

四、關鍵細節與避坑指南

  • 編碼指定:getBytes(StandardCharsets.UTF_8) 避免中文亂碼。
  • 緩衝流:BufferedOutputStream 大幅提升大量寫入效能。
  • 附加模式:new FileOutputStream(file, true) 實現追加寫入而非覆蓋。
  • 執行緒:耗時 IO 操作應放在背景執行緒(如 Coroutines、RxJava、ExecutorService),避免 ANR。
  • 範圍儲存適配:Android 10+ 建議使用 MediaStore 插入媒體檔案,或 getExternalFilesDir() 存放私有資料(免權限、隨 App 解除安裝自動刪除)。

五、總結

Android 讀寫 SD 卡核心在於:正確聲明權限 → 動態取得標準路徑 → 善用緩衝流與資源自動管理 → 適配分區儲存新政。掌握這套流程,即可穩健處理各類檔案存取需求。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved