Android 透過 Intent.ACTION_GET_CONTENT 或 ACTION_PICK 選取圖片後,需正確解析 Uri 取得真實路徑,再複製至 App 專屬或公共目錄。Android 10+ (API 29) 建議使用 MediaStore 或 DocumentFile 避免直接檔案路徑操作。
Intent(Intent.ACTION_OPEN_DOCUMENT).setType("image/*")onActivityResult 取得 Uri,授權持久權限:getContentResolver().takePersistableUriPermission(uri, FLAG_READ)ContentResolver.openInputStream(uri) 讀取串流,寫入目標檔案(getExternalFilesDir(Environment.DIRECTORY_PICTURES) 或 MediaStore 插入新記錄)。// 複製至 App 專屬目錄(無需權限,卸載自動清理)
File destDir = getExternalFilesDir(Environment.DIRECTORY_PICTURES);
File destFile = new File(destDir, "copy_" + System.currentTimeMillis() + ".jpg");
try (InputStream in = getContentResolver().openInputStream(uri);
FileOutputStream out = new FileOutputStream(destFile)) {
byte[] buffer = new byte[8192];
int len;
while ((len = in.read(buffer)) != -1) out.write(buffer, 0, len);
// 可選:掃描讓相簿顯示
MediaScannerConnection.scanFile(this, new String[]{destFile.getAbsolutePath()}, null, null);
}
若必須支援 Android 9 以下且需真實路徑,可用 MediaStore.Images.Media.DATA 查詢,但不保證所有 Uri 皆有此欄位,建議統一使用串流複製。
/mnt/sdcard/美好時光 為公共儲存,Android 10+ 需 MANAGE_EXTERNAL_STORAGE 權限且用戶難授權。getExternalFilesDir() 或 MediaStore 插入,符合分區儲存規範。<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<!-- Android 10+ 不需 WRITE_EXTERNAL_STORAGE 即可寫入專屬目錄 -->