原因は実行時のパーミッション不足で、分かってみたら当然なんだけど、ググったときに事例が見つからずちょっとハマったので、メモとして残すことにしました。
ディレクトリ内のファイル一覧の取得
Directory pDir = Directory(_target);
var plist = pDir.listSync();
for( var p in plist ){
print( p.path );
}
ファイル一覧の取得にはDirectoryクラスのlistSync()とかlist()メソッドを使います。_targetには対象ディレクトリの名前が入ります。AndroidManifest.xmlには外部ストレージのアクセス許可のため、次の記述を入れてあります。
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
ここで _target="/storage/emulated/0/DCIM"; と外部ストレージの名前を入れて実行してみると、次のようになりました。
I/flutter ( 9998): /storage/emulated/0/DCIM/mei
I/flutter ( 9998): /storage/emulated/0/DCIM/Camera
I/flutter ( 9998): /storage/emulated/0/DCIM/.thumbnails
I/flutter ( 9998): /storage/emulated/0/DCIM/LINE
I/flutter ( 9998): /storage/emulated/0/DCIM/Facebook
Fileアプリで確認すると、このディレクトリにはもっといろいろ入ってるのですが、plistには格納されません。表示されているのは全部ディレクトリです。"/storage/emulated/0/DCIM"の代わりに"/"を指定すると、以下のように明らかにパーミッションの例外を起こしますが、これは中途半端でもアクセスできているのでパーミッションの問題ではないと思い込んでしまいました。
W/1.ui ( 9998): type=1400 audit(0.0:2766): avc: denied { read } for name="/" dev="dm-4" ino=2 scontext=u:r:untrusted_app:s0:c134,c257,c512,c768 tcontext=u:object_r:rootfs:s0 tclass=dir permissive=0 app=com.example.filer_permission
実行時にアプリに権限を与える
結論から言うと、実行時にユーザーに明示的に指定してもらわないとパーミッションが取得できないという、いまどき当たり前の話でした。昔はAndroidManifest.xmlに書くだけでよかったんだけどねぇ。
設定のアプリ情報でターゲットアプリの設定を開くと「権限が付与されていません」と表示されるので、そこをクリックして必要な権限を付与します。
「メディアへのアクセスのみを許可」を選択して戻ります。
再度実行すると、今度はファイル一覧にいろいろ入っています。
I/flutter (14631): /storage/emulated/0/DCIM/IMG_00000001.jpg
I/flutter (14631): /storage/emulated/0/DCIM/IMG_00000002.jpg
I/flutter (14631): /storage/emulated/0/DCIM/IMG_00000003.jpg
I/flutter (14631): /storage/emulated/0/DCIM/IMG_00000004.jpg
I/flutter (14631): /storage/emulated/0/DCIM/saturdaynight.mp3
I/flutter (14631): /storage/emulated/0/DCIM/Skrillex.mp3
I/flutter (14631): /storage/emulated/0/DCIM/PCM.wav
I/flutter (14631): /storage/emulated/0/DCIM/type3_14.25kbps.amr
I/flutter (14631): /storage/emulated/0/DCIM/type5_18.25kbps.amr
I/flutter (14631): /storage/emulated/0/DCIM/type6_19.85kbps.amr
I/flutter (14631): /storage/emulated/0/DCIM/type7_23.05kbps.amr
I/flutter (14631): /storage/emulated/0/DCIM/type8_23.85kbps.amr
I/flutter (14631): /storage/emulated/0/DCIM/mei
I/flutter (14631): /storage/emulated/0/DCIM/Camera
I/flutter (14631): /storage/emulated/0/DCIM/.thumbnails
I/flutter (14631): /storage/emulated/0/DCIM/LINE
I/flutter (14631): /storage/emulated/0/DCIM/Facebook
以下のように実行時に必要な権限がないときの処理をするライブラリもあるようですが、baseflow.comというライブラリに依存していて、セットアップがいろいろ面倒で、プログラム構造も変わってしまうので、しばらくは手動で対処。