AndroidのデフォルトのContentProviderにMediaStoreがありますが、MediaScannerが自動で登録してくれます。
ただ、自分でカメラアプリや録音アプリなどを作ってファイルを生成した時にMediaStoreに能動的に登録したいことがあります。
通常は画像ならMediaStore.Images.Media.insertImage、それ以外もContentResolverを使ってMediaStoreにinsertすることで登録できます。
ただ、exifの取得やmp3のタグの読み取りなど、システムに任せたいこともあるかと思います。
登録を依頼する方法がいくつかあるのでまとめておきます。
Lollipop以降での新しいAPIなどは見つけられていないのですが、もしあったら教えてください。
MediaScannerConnection.scanFileを使う
MediaScannerConnection.scanFile
一般的によく使われる方法かと思います。
MediaScannerConnection.scanFile(getActivity(),
new String[] { file.getAbsolutePath() }, null,
new OnScanCompletedListener() {
@Override
public void onScanCompleted(String path, Uri uri) {
Log.v("MediaScanWork", "file " + path
+ " was scanned seccessfully: " + uri);
}
});
}
この方法は、登録完了のコールバックを受け取りたい時に有効です。
listenerはnullも許容されているのでcallbackが不要の時にも使えます。
また、複数ファイルも登録できるので便利です。
Intent.ACTION_MEDIA_SCANNER_SCAN_FILEを使う
Intent.ACTION_MEDIA_SCANNER_SCAN_FILE
紹介されている例が少し少なかったですが、特にスキャン完了などを把握しなくていい時には、とてもシンプルな方法なのでオススメです。
Uri contentUri = Uri.fromFile(newFile);
Intent mediaScanIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, contentUri);
context.sendBroadcast(mediaScanIntent);
注意点として、ファイルの絶対pathを渡した方がいいらしいです。
また、スキャンの結果がわからないので、使いどころを選びますね。
[昔可能だった方法]全ファイルの自動検索
かつてはIntent.ACTION_BOOT_COMPLETEDやIntent.ACTION_MEDIA_MOUNTEDを発行することで、MediaScannerに全ファイルの検索を依頼することができました。
この方法ではファイルのパスさえいらないので、自アプリだけなく他のアプリのスキャン漏れも再検索してもらえます。
しかし、kitkat以降では、これらのbroadcast intentの発行権限が発行時にチェックされるようになったため、使えなくなりました。
現状は全ファイルの再検索依頼は難しそうです。
まとめ
- MediaStoreに登録するのはMediaStore.Images.Media.insertImageなどを使ったりinsertするのがもっとも確実
- ファイルの情報を十分に登録できない時などはMediaScannerServiceに依頼する
- ストレージの再検索は現状難しそう。
参考
フレームワークの内部コードを交えた解説がされていて親切でした。