タイトル

執筆:2023.10.26
編集:2023.10.26


Android11
アプリから外部MicorSDカード領域に保存した画像がMediaStoreに登録できません!

getContentResolver().insert
EXTERNAL_CONTENT_URI

Requested path doesn't apper under [/storage/emulated/0]

なぜ emulated/0 にパスを勝手に変更しているの?

内部のユーザー領域なら正常に実行できる。
外部MicorSDカード領域のパスの場合上記のエラーになる。

フラグは、2種類しかないし INTERNAL_CONTENT_URI は、違うし。
ほかにフラグが増えたとか?

EXTERNAL_CONTENT_URI: The content:// style URI for the "primary" external storage volume.

ほかのアプリ(ファイラーだと)で名称変更でするとMediaStoreに上がってくるので APIレベル指定の違いかな?

古いアンドロイドならOKなのかな?
なにか互換性の設定がいるとか?

よくわからないので別の古い端末で動作確認してみよう。


追記
解決しました
Androidサイトのヘルプにも記述がないから苦労した。
ネットにも情報ないし、みんな迷走してSDCardへの保存が使えないと思い込んでいる模様。

getContentUri([定義済み定数|'ボリューム名']) です。
SDカードは、ボリューム名を入れます。ボリューム名は、getExternalVolumeNames関数から取得できます.

getExternalVolumeNames関数の結果
external_primary : 本体に保存する場合
4桁数値-4桁数値  : SDカードに保存する場合

LContentUri := TJImages_Media.JavaClass.getContentUri(StringToJString([定義済み定数|ボリューム名]));
// 'external_primary' or '4桁数値-4桁数値' : Android11
// 'external' : 古いAndroid
LJNewURI := TAndroidHelper.ContentResolver.insert(LContentUri, LJContentValues);



if (TJBuild_VERSION.JavaClass.SDK_INT >= 29) then // (Android10 API 29)
// MediaStore.VOLUME_EXTERNAL_PRIMARY : Constant Value: "external_primary"
LVolume := 'external_primary'
else
LVolume := 'external';
// LVolume := 'xxxx-xxxx'; // SDカードの場合は数値を書いて有効にする

LContentUri := TJImages_Media.JavaClass.getContentUri(StringToJString(LVolume));
//LContentUri := TJMyAndroidUtils.JavaClass.getContentUriFromFilename(
// TAndroidHelper.Context, StringToJString(LContentFilename));

ShowDebugMessage('ContentResolver:Uri:' + #10 + JStringToString(LContentUri.toString()));

» 続きを読む