カメラで撮影した画像ファイルにアクセスしたい。 フォルダは、大抵以下のフォルダになる。 2番目のフォルダのパスを取得するためにどうするか調べてみました。
/storage/emulated/0/DCIM /storage/XXXX-XXXX/DCIM
以下の記事を参考にしました。Android7から13対応のコード
Androidでストレージの物理パスを取得する #Android - Qiita
Android13でアプリから画像・音声・動画にアクセスする | CSL
Android13から権限が変更されたようで、READ_EXTERNAL_STORAGEからREAD_MEDIA_XXXXの権限になっています。 したがってバージョンを分けてAndroidManifest.xmlに以下のpermissionを入れます。
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" android:maxSdkVersion="32" />/> <uses-permission android:name="android.permission.READ_MEDIA_IMAGES" android:minSdkVersion="33" /> <!-- <uses-permission android:name="android.permission.READ_MEDIA_VIDEO" android:minSdkVersion="33" /> <uses-permission android:name="android.permission.READ_MEDIA_AUDIO" android:minSdkVersion="33" /> -->
サンプルコード
起動時にPermissionsのチェック、リクエストを行います。許可されていなかったら終了。 ストレージのパスは、getVolPaths()でまとめました。
package com.example.mytest1; import android.Manifest; import android.content.Context; import android.content.pm.PackageManager; import androidx.core.app.ActivityCompat; import androidx.core.content.ContextCompat; import android.os.Build; import android.os.storage.StorageManager; import android.os.storage.StorageVolume; import android.util.Log; import android.widget.Toast; import androidx.appcompat.app.AppCompatActivity; import android.os.Bundle; import java.util.ArrayList; import java.util.List; public class MainActivity extends AppCompatActivity { private static final int REQUEST_EXTERNAL_STORAGE = 101; private static String[] PERMISSIONS_STORAGE = { Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.READ_MEDIA_IMAGES, }; @Override public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) { super.onRequestPermissionsResult(requestCode, permissions, grantResults); boolean start = false; if (requestCode == REQUEST_EXTERNAL_STORAGE) { if (grantResults.length > 0) { for (int i = 0; i < permissions.length; i++) { switch (permissions[i]) { case Manifest.permission.READ_EXTERNAL_STORAGE: case Manifest.permission.READ_MEDIA_IMAGES: if (grantResults[i] == PackageManager.PERMISSION_GRANTED) { start = true; } break; } } } } if (start = true) { Toast.makeText(MainActivity.this, "Permission Granted", Toast.LENGTH_SHORT).show(); } else { Toast.makeText(MainActivity.this, "Storage Permission Denied", Toast.LENGTH_SHORT).show(); finish(); } } private List<String> getVolPaths(Context context) { StorageManager sm = (StorageManager) context.getSystemService(STORAGE_SERVICE); List<String> volPaths = new ArrayList<String>(); List<StorageVolume> volList = sm.getStorageVolumes(); for (StorageVolume volume : volList) { String vpath = null; // Android 11 - 13 if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.R) { vpath = volume.getDirectory().toString(); volPaths.add(vpath); Log.d("DEBUG", "Android 11 vol Path = " + vpath); } else { // Android 7 - 10 if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.N) { try { //noinspection JavaReflectionMemberAccess vpath = (String) volume.getClass().getMethod("getPath").invoke(volume); } catch (Exception e) { vpath = null; } if (vpath == null || "".equals(vpath)) { continue; } volPaths.add(vpath); Log.d("DEBUG", "Android 7 vol Path = " + vpath); } } } return volPaths; } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); int permission; if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { permission = ContextCompat.checkSelfPermission(this, Manifest.permission.READ_MEDIA_IMAGES); }else { permission = ContextCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE); } if (permission != PackageManager.PERMISSION_GRANTED) { ActivityCompat.requestPermissions( this, PERMISSIONS_STORAGE, REQUEST_EXTERNAL_STORAGE ); } Context context = getApplicationContext(); List<String> volPaths = getVolPaths(context); int i = 0; for (String pathName : volPaths) { i += 1; Log.d("DEBUG", "vol No=" + i + " Path = " + pathName); } } }
実行結果(logcat)、Device Emulator, Android 9で実行
D Android 7 vol Path = /storage/emulated/0 D Android 7 vol Path = /storage/0A11-1F0B D vol No=1 Path = /storage/emulated/0 D vol No=2 Path = /storage/0A11-1F0B
実行結果(logcat)、Device Emulator, Android 13で実行
D Android 11 vol Path = /storage/emulated/0 D Android 11 vol Path = /storage/0C07-090B D vol No=1 Path = /storage/emulated/0 D vol No=2 Path = /storage/0C07-090B