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

Android 調用錄音機返回 file:// Uri 處理:Scheme 替換獲取絕對路徑與 ContentProvider 查詢差異

     編輯:程式設計綜合問答

現象

`Intent(MediaStore.Audio.Media.RECORD_SOUND_ACTION)` 返回 `data.getData()` 為 `file:///storage/emulated/0/Recording.mp3`,而非 `content://` Uri,導致 `ContentResolver.query()` 無結果。

原因

  • 舊版錄音應用/系統版本直接返回 **文件 Scheme Uri** (`file://`),不經過 `MediaStore` ContentProvider。
  • > Android 10+ (Q) 分區存儲強制要求 `content://`,但廠商定制 ROM 可能仍返回 `file://`。

處理策略

方案一:Scheme 判斷兼容 (推薦)


Uri uri = data.getData();
String path;
if ("file".equals(uri.getScheme())) {
    path = uri.getPath(); // 直接獲取絕對路徑
} else if ("content".equals(uri.getScheme())) {
    // 通過 ContentResolver 查詢 _DATA 列 (已棄用但仍可用) 或 openInputStream 讀取
    try (Cursor cursor = getContentResolver().query(uri, new String[]{MediaStore.MediaColumns.DATA}, null, null, null)) {
        if (cursor != null && cursor.moveToFirst()) {
            path = cursor.getString(0);
        }
    }
}
// 統一使用 path 或 uri 進行後續操作

方案二:FileProvider 統一輸出 (最佳實踐)

自行啟動錄音 Intent 時指定輸出 Uri:


File audioFile = new File(getExternalFilesDir(Environment.DIRECTORY_MUSIC), "recording_" + System.currentTimeMillis() + ".mp3");
Uri outputUri = FileProvider.getUriForFile(this, "com.example.fileprovider", audioFile);
Intent intent = new Intent(MediaStore.Audio.Media.RECORD_SOUND_ACTION);
intent.putExtra(MediaStore.EXTRA_OUTPUT, outputUri);
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
startActivityForResult(intent, REQUEST_RECORD);

需在 `AndroidManifest.xml` 配置 `` 並定義 `res/xml/file_paths.xml`。此方式返回固定 `content://` Uri,兼容性最強。

相機 `data` Extra 由來

`Intent(MediaStore.ACTION_IMAGE_CAPTURE)` **未指定 `EXTRA_OUTPUT`** 時,系統相機返回縮略圖 Bitmap 放在 `data.getExtras().get("data")`。此鍵名 `"data"` 定義於 `MediaStore.EXTRA_OUTPUT` 文檔及 AOSP 源碼 `Camera.java`,非公開 API 但行為穩定。生產環境必須指定 `EXTRA_OUTPUT` 獲取全尺寸圖片,依賴 `data` 會得到低質量縮略圖且部分相機不返回。

總結

  • `file://` Uri 直接 `.getPath()` 獲取路徑。
  • 優先使用 `FileProvider` + `EXTRA_OUTPUT` 主動控制輸出位置與 Uri 類型。
  • 相機拍照**務必指定輸出文件**,勿依賴 `data` 縮略圖。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved