19
16

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

MediaStore.Images.Media の BUCKET_ID はどこからやってくるのか

Last updated at Posted at 2014-04-09

ギャラリーアプリが、画像をアルバム(フォルダ)ごとにわけているのを見て、データベース上にアルバムを識別する ID があるのだなと思って調べてみた。

MediaStore が持つアルバムの識別子

アルバムの識別子は BUCKET_ID というのがデータベースのカラムに存在していて、そこに保存されている。

BUCKET_ID と BUCKET_DISPLAY_NAME だけを管理するような、リレーショナルな構造にはなっておらず、画像データに関するカラムとアルバムに関するカラムがくっついた状態になっている。

アルバムごとに GROUP BY する

ギャラリーのように、アルバムごとにリストをつくろうと思うと、SQL でアルバムごとに GROUP BY した結果が欲しくなる。しかし、ContentResolver で問い合わせる時に、GROUP BY をするようなインタフェースは存在しないので、無理やり SQL をねじ込むことになる。

コードはこのヘルパにあるとおりで、WHERE 句が内部的にWHERE (%s)と書かれていて、SELECTION がこの %s に入ることを利用して、SQL インジェクションもびっくりの 1) GROUP BY 1, (2 を入れることで、WHERE (1) GROUP BY 1,(2)なる SQL 文が完成する。SELECT 文では、BUCKET_ID が最初のカラムに指定されているので、これによってグルーピングされる。

ところで、画像を MediaStore に登録するときに BUCKET_ID なんか自分で指定したこと無いんだけど

公式の API にも、BUCKET_ID を自分で指定するようなものは無い。
無いということは、どこかで自動で計算しているはず、ということで探してみた。

MediaStore が見に行くのは、MediaProvider という ContentProvider。その中で、computeBucketValues なるメソッドがあって、ここで BUCKET_ID が計算されている。

コード上はこのあたりにある。

画像を保存したディレクトリのパス文字列を全て小文字にした上で、その hashCode() を BUCKET_ID にしています。

そういうわけで

GROUP BY の闇はアプリの中においておきたくないので、ライブラリにまとめてみました。

BucketId の闇も何とか出来る部分は何とかしたい。

19
16
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
19
16

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?