アプリ内で保存した画像をギャラリーに反映させる方法を説明します。
カメラアプリや画像加工アプリを作成してSDカードなどのストレージに画像ファイルを保存した場合、そのままではギャラリーアプリからその画像を確認することができません。
今回の記事の方法でその画像ファイルをギャラリーの反映させることができます。
カメラアプリを作成したい場合や、SDカードに保存する場合は以下の記事が参考になります。
それでは続きでサンプルソースと共に説明します。
MediaScannerConnection
MediaScannerConnectionクラスはMediaScannerServiceと接続する役割を持ち、メディアファイルをMediaContent Providerに登録することができます。
このMediaScannerConnectionクラスのメソッドであるMediaScannerConnection#scanFileを使うことで任意の画像ファイルをMediaContent Providerに登録し、ギャラリーに反映させることができます。
scanFileメソッドはAPIレベル1から存在します。APIレベル8から同じscanFileという名前ですが、引き数が異なるものが追加されました。
APIレベル8で追加されたメソッドの方が呼び出しが簡単&複数のファイを指定することができて便利です。
最近の端末はAndroid2.2以上が多いのでまずはAPIレベル8で追加された方のscanFileメソッドを説明します。
scanFileメソッド(APIレベル8)
- static void scanFile(Context context, String[] paths, String[] mimeTypes, MediaScannerConnection.OnScanCompletedListener callback)
定義を見てもらえば分かりますが、クラスメソッドなのでMediaScannerConnectionクラスのインスタンスを生成する必要がありません(後述するAPIレベル1からのscanFileメソッドはインスタンスメソッド)。
第2引数にギャラリーに反映させたいファイルのパスを、第3引数に対象とするメディアの種類のMineTypeを指定します。共に配列ですので複数指定することができます。
※第3引数のMimeTypeはnullを指定することも可能で、その場合は拡張子からタイプを推測してくれます。
MediaScannerConnection.OnScanCompletedListenerは1つのメソッドだけを持ったインタフェースです。スキャンが終わった際に呼ばれます。
- abstract void onScanCompleted(String path, Uri uri)
以下のサンプルではSDカード直下のrotate.jpgをスキャンしてギャラリーに反映させています。
String[] paths = {Environment.getExternalStorageDirectory().toString()+ "/rotate.jpg"}; String[] mimeTypes = {"image/jpeg"}; MediaScannerConnection.scanFile(getApplicationContext(), paths, mimeTypes, mScanCompletedListener);
OnScanCompletedListener mScanCompletedListener = new OnScanCompletedListener() { @Override public void onScanCompleted(String path, Uri uri) { Log.d("MediaScannerConnection", "Scanned " + path + ":"); Log.d("MediaScannerConnection", "-> uri=" + uri); } };
上記のサンプルを実行してスキャンした際のログです。
onScanCompletedのpathにはスキャンしたファイルのパス、uriにはContentProviderのURIが入ります。URIがnullの場合はスキャンに失敗したということを表します。
scanFileメソッド(APIレベル1)
- void scanFile(String path, String mimeType)
次にAPIレベル1から使えるscanFileメソッドです。こちらはインスタンスメソッドなのでまずはMediaScannerConnectionクラスのインスタンスを生成する必要があります。
コンストラクタの第2引数にはMediaScannerConnectionClientクラスを指定します。
このMediaScannerConnectionClientクラスには
- onScanCompleted
- onMediaScannerConnected
が定義されており、それぞれスキャンが完了した時、MediaScannerServiceへの接続が完了した時に呼び出されます。
ギャラリーへの反映の手順は手順は以下の通りです。
- MediaScannerConnectionクラスのインスタンスの生成
- MediaScannerServiceへ接続
- MediaScannerServiceへ接続が完了したらscanFileメソッドでスキャンを指示
- スキャンが完了したらMediaScannerServiceへ接続への接続を解除する
MediaScannerConnectionクラスのインスタンスの生成とMediaScannerConnection#connectでMediaScannerServiceへ接続を実施
mMediaScannerConnection = new MediaScannerConnection(getApplicationContext(), mScannerConnectionCluent); mMediaScannerConnection.connect();
接続完了時に呼ばれるMediaScannerConnectionClient#onMediaScannerConnectedでMediaScannerConnection#scanFileを実行する。APIレベル8で追加されたscanFileと異なりは入れるではなく、1つのファイルしか指定することができません。
※第3引数のMimeTypeはnullを指定することも可能で、その場合は拡張子からタイプを推測してくれます。
MediaScannerConnectionClient mScannerConnectionCluent = new MediaScannerConnectionClient() { @Override public void onScanCompleted(String path, Uri uri) { Log.d("MediaScannerConnection", "Scanned " + path + ":"); Log.d("MediaScannerConnection", "-> uri=" + uri); mMediaScannerConnection.disconnect(); } @Override public void onMediaScannerConnected() { Log.d("MediaScannerConnection", "onMediaScannerConnected "); String path = Environment.getExternalStorageDirectory().toString()+ "/rotate.jpg"; String mimeType = "image/jpeg"; mMediaScannerConnection.scanFile(path, mimeType); } };