Flutter の file_picker (https://pub.dev/packages/file_picker) を使用した際に、選択したファイルと異なるファイルが選択された不具合が発生したので紹介します。
file_picker のキャッシュ処理の仕様と特定の端末の仕様の合わせ技による不具合で原因の特定に苦労しました。
不具合内容
端末
Xperia XZ2 SO-03K
不具合機能概要
file_picker でストレージ内の画像を一つ選択し保存する機能
不具合内容
以下操作をすると不具合が発生
- 端末のカメラで撮影
- 該当機能に遷移し、撮影した画像を選択し保存
- 端末の機能で選択した画像を削除
- 1,2を再度行う (カメラで別の画像を撮影しそれを選択)
この操作をしたとき 2 回目のデータを確認すると1回目の画像になっている。
3 と 4 の間でアプリを再起動しても発生
原因
以下 2 つの要因が重なった不具合であった。
- file_picker では初回に選んだファイルがファイル名でキャッシュされる。以降同一のファイル名のファイルを選択した際にはキャッシュした画像が使用される。
キャッシュやストレージを削除すればキャッシュされた画像も削除されるがアプリの再起動では消えない。 - Xperia の古い機種ではカメラで撮影した画像のファイル名が連番で付与される(DCS_[連番])。連番はライブラリ内の最大の連番+1となる。
Xperia 1 Ⅲ から変更されているようである。(参考:https://androidnext.info/?p=11564)
Xperia 以外でも同じような仕様があるものは発生すると考えられる。iPhone では再現しなかった。
対策
発生する端末が少し古いものでもあったため、切り捨てても良かったが念のため対策を入れた。
file_picker の pick 処理を呼び出す前に file_picker で用意されているキャシュのクリア処理を実行。
clearTemporaryFiles method - FilePicker class - file_picker library - Dart API
API docs for the clearTemporaryFiles method from the FilePicker class, for the Dart programming language.
// キャッシュクリア
if (Platform.isAndroid || Platform.isIOS) {
FilePicker.platform.clearTemporaryFiles();
}
FilePickerResult? result = await FilePicker.platform.pickFiles(
type: FileType.image,
);
(参考) 該当端末以外での再現方法
以下手順を行うことで該当端末以外でも再現可能。
- file_picker で画像を選択
- 端末の機能から「1」で選んだ画像を削除や名前を変更
- 別の画像を準備。端末の機能からその画像の名前を「1」と同じ名前に変更
- file_picker で「3」の画像を選択