メディアデータはデータベースによって管理されています。
Media Store APIを使ってメディアデータへアクセスしているのであれば、データベースの所在や構成などを意識する必要はありません。
ただ、「より複雑な制御をしたい場合」や「デバックを効率化したい場合」などに、データベースの知識が役立ちます。
今回は「メディアデータのデータベースによる管理」について、まとめます。
この記事は、Imagesデータ編です。
※環境:Android Studio Narwhal | 2025.1.1 Patch 1
データベースの所在
メディアデータのメディア情報を、データベースで管理しているのはMedia Storeアプリです。
ですので、データベースは内部ストレージのMedia Storeアプリ固有の領域にあります。
# pwd /data/data/com.android.providers.media ← Media Storeアプリ固有の領域 # ls -l databases/* -rw-rw---- 1 u0_a5 u0_a5 151552 2025-06-05 01:52 databases/external.db -rw-rw---- 1 u0_a5 u0_a5 229376 2025-06-05 00:01 databases/internal.db ※「/data/data」は管理者ユーザー(ユーザーID:0)の内部ストレージと同じ場所
テーブルの構成
データベースは複数のテーブルで構成されています。
# pwd /data/data/com.android.providers.media/databases # sqlite3 ./external.db sqlite> .tables album_art audio_genres log album_info audio_genres_map search albums audio_genres_map_noid searchhelpertitle android_metadata audio_meta thumbnails artist_info audio_playlists video artists audio_playlists_map videothumbnails artists_albums_map files audio images
メディア情報の実態は、filesテーブルが持ちます。
imagesテーブルはfilesテーブルからimageメディア情報を切り出したview(仮想テーブル)です。

viewテーブルの条件に、media_typeカラム(media_type=1)が用いられています。
...
db.execSQL("CREATE TABLE files (_id INTEGER PRIMARY KEY AUTOINCREMENT,"
+ "_data TEXT UNIQUE COLLATE NOCASE,_size INTEGER,format INTEGER,parent INTEGER,"
+ "date_added INTEGER,date_modified INTEGER,mime_type TEXT,title TEXT,"
+ "description TEXT,_display_name TEXT,picasa_id TEXT,orientation INTEGER,"
+ "latitude DOUBLE,longitude DOUBLE,datetaken INTEGER,mini_thumb_magic INTEGER,"
+ "bucket_id TEXT,bucket_display_name TEXT,isprivate INTEGER,title_key TEXT,"
+ "artist_id INTEGER,album_id INTEGER,composer TEXT,track INTEGER,"
+ "year INTEGER CHECK(year!=0),is_ringtone INTEGER,is_music INTEGER,"
+ "is_alarm INTEGER,is_notification INTEGER,is_podcast INTEGER,album_artist TEXT,"
+ "duration INTEGER,bookmark INTEGER,artist TEXT,album TEXT,resolution TEXT,"
+ "tags TEXT,category TEXT,language TEXT,mini_thumb_data TEXT,name TEXT,"
+ "media_type INTEGER,old_id INTEGER,is_drm INTEGER,"
+ "width INTEGER, height INTEGER, title_resource_uri TEXT)");
db.execSQL("CREATE VIEW images AS SELECT _id,_data,_size,_display_name,mime_type,title,"
+ "date_added,date_modified,description,picasa_id,isprivate,latitude,longitude,"
+ "datetaken,orientation,mini_thumb_magic,bucket_id,bucket_display_name,width,"
+ "height FROM files WHERE media_type=1");
...
カラムの構成
テーブルおよびコレクションは次のカラムを持ちます。
| データベースの filesテーブル | データベースの imagesテーブル | MediaStoreの imagesコレクション | コメント | |
|---|---|---|---|---|
| _id | I | _id | 左に同じ | Primary Key Autoinc |
| _data | T | _data | Unigue | |
| _display_name | T | _display_name | ||
| _size | I | _size | ||
| album | T | |||
| album_artist | T | |||
| album_id | I | |||
| artist | T | |||
| artist_id | I | |||
| bookmark | I | |||
| bucket_display_name | T | bucket_display_name | ||
| bucket_id | T | bucket_id | ||
| category | T | |||
| composer | T | |||
| date_added | I | date_added | ||
| date_modified | I | date_modified | ||
| datetaken | I | datetaken | ||
| description | T | description | ||
| duration | I | |||
| format | I | |||
| height | I | height | ||
| is_alarm | I | 0:false 1:true |
||
| is_drm | I | |||
| is_music | I | |||
| is_notification | I | |||
| is_podcast | I | |||
| is_ringtone | I | |||
| isprivate | I | isprivate | ||
| language | T | |||
| latitude | D | latitude | ||
| longitude | D | longitude | ||
| media_type | I | 1:Images 2:Audio 3:Video |
||
| mime_type | T | mime_type | ||
| mini_thumb_data | T | |||
| mini_thumb_magic | I | mini_thumb_magic | ||
| name | T | |||
| old_id | I | |||
| orientation | I | orientation | ||
| parent | I | |||
| picasa_id | T | picasa_id | ||
| resolution | T | |||
| tags | T | |||
| title | T | title | ||
| title_key | T | |||
| title_resource_uri | T | |||
| track | I | |||
| width | I | width | ||
| year | I | |||
| ※カラム名はA-Z順にソート ※I:Integer、R:Real、D:Double、T:Text、B:BLOB(Binary) ※imageコレクション:Media Storeで操作可能なカラム(参照結果のCursorに含まれる) |
||||
Media Store APIはカラム名をパラメータで定義しています。プログラムは、このパラメータを使います。※詳細は「MediaStore.Images.Media.*」を参照
レコードの構成
レコード(メディア情報)内のフィールドは、次のような関係があります。
- (1)URIを指定すると、_idが定まる
- (2)_idを指定すると、メディア情報が一意に定まる
- (3)メディア情報の_dataを指定すると、メディアファイルが一意に定まる
(3)の_dataとファイルの物理的な関係は「固定」です。
関係が崩れると、Media Storeは破綻します。つまり、データを読み出したり、更新したり、といった正常なアクセスが出来なくなります。

これに対し、_data以外とファイルの物理的な関係は「なし」です。
これらのフィールドはメディアファイルのメタ情報であって、関係が崩れたとしても、Media Storeは破綻しません。ただし、論理的な関係は維持しないと、メタ情報の意味がありません。
例えば、ファイル名を連番(_data:/…/IMG0011.jpg)、表示名を具体的な名前(_display_name:「100万ドルの夜景」)などにすることが出来ます。
また、MIMEタイプを”image/jpeg”⇒”image/png”にすると、読み出しは問題ありませんが、PNGフォーマットと信じたアプリは表示に失敗します。
関連記事:
