言いたいことはそれだけか

KotlinとかAndroidとかが好きです。調べたことをメモします。٩( 'ω' )و

MediaStoreのThumbnailsの罠

先日参加したCA.apk #2 で前川さんが発表されていた「やさしい画像ギャラリー改善tips」がいい感じだったので、試してみた結果と気になった部分のメモ書きです。

発表の概要

画像ギャラリーを作る時に、MediaStore.Images.Media.EXTERNAL_CONTENT_URI だと画像の元サイズで読み込んでメモリが逼迫されるので、MediaStore.Images.Thumbnails.EXTERNAL_CONTENT_URIを使って小さいサイズで読み込むと動作がサクサクになるよ!という話だと理解しました。

気になったこと

基本的にいい感じなのですが、thumbnailのテーブルだとコンテンツが登録されない契機があるように見えます。具体的にいうと、ギャラリーを表示した直後にカメラアプリを起動し、ギャラリーに戻って来た際にthumbnailのテーブルには先ほど撮った写真はまだ登録されていません。(MediaStore.Images.Media.EXTERNAL_CONTENT_URIには登録されていました。)手元のNexus 6Pでしか試せていないのですが、/storage/emulated/0/DCIM/.thumbnails/配下のキャッシュされたファイルしか探しに行けてないような?thunbmail生成のタイミングに気をつけたほうがよさそうです。

で、どうする?

確実な方法としては、MediaStore.Images.Media.EXTERNAL_CONTENT_URIでちゃんと最新のデータが登録されているので、このテーブルからID一覧を取得するのが楽そうです。こっちのテーブルにはthumbnailのテーブルのようにKIND列が用意されていないので、サイズを指定してデータを参照することはできません。というわけで、Thumbnails.getThumbnail() を使って元データのIDからthumbnail画像のbitmapを取得するのが正攻法なのかなぁという気がしています。パフォーマンスはちょっと下がる気がしているので、他にいい方法があれば教えてください。

おまけ:thumbnail テーブルが更新されるタイミングを知りたくてframeworkを読んで見た

MediaProviderupdate()が呼ばれたタイミングでthumbnailが生成されているけど、insert()のタイミングではthumbnailは生成されていないような気がする…1
ということはMediaScannerでscanすればいいのでは?と思ってMediaScanner#scanDirectories() とか使いたかったけどそもそもクラスが @hide だし、publicなMediaScannerConnection#scanFile()ディレクト単位でscanできるのかわからないので諦めました :p