メディアデータはデータベースによって管理されています。
Media Store APIを使ってメディアデータへアクセスしているのであれば、データベースの所在や構成などを意識する必要はありません。
ただ、「より複雑な制御をしたい場合」や「デバックを効率化したい場合」などに、データベースの知識が役立ちます。
今回は「メディアデータのデータベースによる管理」について、まとめます。
この記事は、Imagesデータ編です。
※環境:Android Studio Narwhal | 2025.1.1 Patch 1
データベースの所在
メディアデータのメディア情報を、データベースで管理しているのはMedia Providerモジュールです。
ですので、データベースは内部ストレージのMedia Providerモジュール固有の領域にあります。
# pwd /data/data/com.android.providers.media ← Media Storeアプリ固有の領域 # ls -l databases/* -rw-rw---- 1 u0_a60 u0_a60 155648 2025-06-11 13:12 databases/external.db -rw-rw---- 1 u0_a60 u0_a60 253952 2025-06-11 13:12 databases/internal.db ※「/data/data」は管理者ユーザー(ユーザーID:0)の内部ストレージと同じ場所
# pwd /data/data/com.google.android.providers.media.module ← Media Providerモジュール固有の領域 # ls -l databases/* -rw-rw---- 1 u0_a166 u0_a166 118784 2025-06-12 01:37 databases/external.db -rw------- 1 u0_a166 u0_a166 32768 2025-06-12 01:57 databases/external.db-shm -rw------- 1 u0_a166 u0_a166 453232 2025-06-12 01:56 databases/external.db-wal -rw-rw---- 1 u0_a166 u0_a166 233472 2025-06-12 01:38 databases/internal.db -rw------- 1 u0_a166 u0_a166 32768 2025-06-12 01:38 databases/internal.db-shm -rw------- 1 u0_a166 u0_a166 494432 2025-06-12 01:38 databases/internal.db-wal ※「/data/data」は管理者ユーザー(ユーザーID:0)の内部ストレージと同じ場所
テーブルの構成
データベースは複数のテーブルで構成されています。
# pwd /data/data/com.android.providers.media/databases # sqlite3 ./external.db sqlite> .tables album_art audio_genres images album_info audio_genres_map log albums audio_genres_map_noid search android_metadata audio_meta searchhelpertitle artist_info audio_playlists thumbnails artists audio_playlists_map video artists_albums_map downloads videothumbnails audio files
# pwd /data/data/com.google.android.providers.media.module/databases # sqlite3 ./external.db sqlite> .tables album_art audio_playlists log android_metadata audio_playlists_map search audio downloads searchhelpertitle audio_albums files thumbnails audio_artists images video audio_genres local_metadata videothumbnails
メディア情報の実態は、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,"
+ "owner_package_name TEXT DEFAULT NULL,"
+ "color_standard INTEGER, color_transfer INTEGER, color_range INTEGER,"
+ "_hash BLOB DEFAULT NULL, is_pending INTEGER DEFAULT 0,"
+ "is_download INTEGER DEFAULT 0, download_uri TEXT DEFAULT NULL,"
+ "referer_uri TEXT DEFAULT NULL, is_audiobook INTEGER DEFAULT 0,"
+ "date_expires INTEGER DEFAULT NULL,is_trashed INTEGER DEFAULT 0,"
+ "group_id INTEGER DEFAULT NULL,primary_directory TEXT DEFAULT NULL,"
+ "secondary_directory TEXT DEFAULT NULL,document_id TEXT DEFAULT NULL,"
+ "instance_id TEXT DEFAULT NULL,original_document_id TEXT DEFAULT NULL,"
+ "relative_path TEXT DEFAULT NULL,volume_name TEXT DEFAULT NULL)");
...
db.execSQL("CREATE VIEW images AS SELECT "
+ String.join(",", getProjectionMap(Images.Media.class).keySet())
+ " FROM files WHERE 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,"
+ "owner_package_name TEXT DEFAULT NULL,"
+ "color_standard INTEGER, color_transfer INTEGER, color_range INTEGER,"
+ "_hash BLOB DEFAULT NULL, is_pending INTEGER DEFAULT 0,"
+ "is_download INTEGER DEFAULT 0, download_uri TEXT DEFAULT NULL,"
+ "referer_uri TEXT DEFAULT NULL, is_audiobook INTEGER DEFAULT 0,"
+ "date_expires INTEGER DEFAULT NULL,is_trashed INTEGER DEFAULT 0,"
+ "group_id INTEGER DEFAULT NULL,primary_directory TEXT DEFAULT NULL,"
+ "secondary_directory TEXT DEFAULT NULL,document_id TEXT DEFAULT NULL,"
+ "instance_id TEXT DEFAULT NULL,original_document_id TEXT DEFAULT NULL,"
+ "relative_path TEXT DEFAULT NULL,volume_name TEXT DEFAULT NULL,"
+ "artist_key TEXT DEFAULT NULL,album_key TEXT DEFAULT NULL,"
+ "genre TEXT DEFAULT NULL,genre_key TEXT DEFAULT NULL,genre_id INTEGER,"
+ "author TEXT DEFAULT NULL, bitrate INTEGER DEFAULT NULL,"
+ "capture_framerate REAL DEFAULT NULL, cd_track_number TEXT DEFAULT NULL,"
+ "compilation INTEGER DEFAULT NULL, disc_number TEXT DEFAULT NULL,"
+ "is_favorite INTEGER DEFAULT 0, num_tracks INTEGER DEFAULT NULL,"
+ "writer TEXT DEFAULT NULL, exposure_time TEXT DEFAULT NULL,"
+ "f_number TEXT DEFAULT NULL, iso INTEGER DEFAULT NULL,"
+ "scene_capture_type INTEGER DEFAULT NULL, generation_added INTEGER DEFAULT 0,"
+ "generation_modified INTEGER DEFAULT 0, xmp BLOB DEFAULT NULL)");
...
db.execSQL("CREATE VIEW images AS SELECT "
+ String.join(",", getProjectionMap(Images.Media.class).keySet())
+ " 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 | ||
| _hash | B | _hash | ||
| _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 | |||
| color_range | I | |||
| color_standard | I | |||
| color_transfer | I | |||
| composer | T | |||
| date_added | I | date_added | ||
| date_expires | I | date_expires | ||
| date_modified | I | date_modified | ||
| datetaken | I | datetaken | ||
| description | T | description | ||
| document_id | T | document_id | ||
| download_uri | T | |||
| duration | I | duration | ||
| format | I | |||
| group_id | I | group_id | ||
| height | I | height | ||
| instance_id | T | instance_id | ||
| is_alarm | I | 0:false 1:true |
||
| is_audiobook | I | |||
| is_download | I | |||
| is_drm | I | is_drm | ||
| is_music | I | |||
| is_notification | I | |||
| is_pending | I | is_pending | ||
| is_podcast | I | |||
| is_ringtone | I | |||
| is_trashed | I | is_trashed | ||
| isprivate | I | isprivate | ||
| language | T | |||
| latitude | D | latitude | ||
| longitude | D | longitude | ||
| media_type | I | 1:Image 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 | ||
| original_document_id | T | original_document_id | ||
| owner_package_name | T | owner_package_name | ||
| parent | I | |||
| picasa_id | T | picasa_id | ||
| primary_directory | T | primary_directory | ||
| referer_uri | T | |||
| relative_path | T | relative_path | ||
| resolution | T | |||
| secondary_directory | T | secondary_directory | ||
| tags | T | |||
| title | T | title | ||
| title_key | T | |||
| title_resource_uri | T | |||
| track | I | |||
| volume_name | T | volume_name | ||
| width | I | width | ||
| year | I | |||
| ※カラム名はA-Z順にソート ※I:Integer、R:Real、D:Double、T:Text、B:BLOB(Binary) ※imageコレクション:Media Storeで操作可能なカラム(参照結果のCursorに含まれる) |
||||
| データベースの filesテーブル | データベースの imagesテーブル | MediaStoreの imagesコレクション | コメント | |
|---|---|---|---|---|
| _id | I | _id | 左に同じ | Primary Key Autoinc |
| _data | T | _data | Unigue | |
| _display_name | T | _display_name | ||
| _hash | B | |||
| _size | I | _size | ||
| album | T | album | ||
| album_artist | T | album_artist | ||
| album_id | I | |||
| album_key | T | |||
| artist | T | artist | ||
| artist_id | I | |||
| artist_key | T | |||
| author | T | author | ||
| bitrate | I | bitrate | ||
| bookmark | I | |||
| bucket_display_name | T | bucket_display_name | ||
| bucket_id | T | bucket_id | ||
| capture_framerate | R | capture_framerate | ||
| category | T | |||
| cd_track_number | T | cd_track_number | ||
| color_range | I | |||
| color_standard | I | |||
| color_transfer | I | |||
| compilation | I | compilation | ||
| composer | T | composer | ||
| date_added | I | date_added | ||
| date_expires | I | date_expires | ||
| date_modified | I | date_modified | ||
| datetaken | I | datetaken | ||
| description | T | description | ||
| disc_number | T | disc_number | ||
| document_id | T | document_id | ||
| download_uri | T | |||
| duration | I | duration | ||
| exposure_time | T | exposure_time | ||
| f_number | T | f_number | ||
| format | I | |||
| generation_added | I | generation_added | ||
| generation_modified | I | generation_modified | ||
| genre | T | genre | ||
| genre_id | I | |||
| genre_key | T | |||
| group_id | I | group_id | ||
| height | I | height | ||
| instance_id | T | instance_id | ||
| is_alarm | I | 0:false 1:true |
||
| is_audiobook | I | |||
| is_download | I | is_download | ||
| is_drm | I | is_drm | ||
| is_favorite | I | is_favorite | ||
| is_music | I | |||
| is_notification | I | |||
| is_pending | I | is_pending | ||
| is_podcast | I | |||
| is_ringtone | I | |||
| is_trashed | I | is_trashed | ||
| iso | I | iso | ||
| 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 | |||
| num_tracks | I | num_tracks | ||
| old_id | I | |||
| orientation | I | orientation | ||
| original_document_id | T | original_document_id | ||
| owner_package_name | T | owner_package_name | ||
| parent | I | |||
| picasa_id | T | picasa_id | ||
| primary_directory | T | |||
| referer_uri | T | |||
| relative_path | T | relative_path | ||
| resolution | T | resolution | ||
| scene_capture_type | I | scene_capture_type | ||
| secondary_directory | T | |||
| tags | T | |||
| title | T | title | ||
| title_key | T | |||
| title_resource_uri | T | |||
| track | I | |||
| volume_name | T | volume_name | ||
| width | I | width | ||
| writer | T | writer | ||
| xmp | B | xmp | ||
| year | I | year | ||
| ※カラム名は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)メディア情報のrelative_path,_display_nameを指定すると_dataが生成される
- (4)作成された_dataにより、メディアファイルが一意に定まる
(3,4)のrelative_path, _display_nameおよび_dataとファイルの物理的な関係は「固定」です。
関係が崩れると、Media Storeは破綻します。つまり、データを読み出したり、更新したり、といった正常なアクセスが出来なくなります。
関係が崩れないように、relative_path, _display_nameの変更はファイルへ直ちに反映されます。また、この両者から生成される_dataは、変更が禁止されています。
例えば、表示名を連番から具体的な名前(_display_name:「IMG0011.jpg」→「100万ドルの夜景.jpg」)に変更すると、ファイル名も自動的に変更されます。

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