読者です 読者をやめる 読者になる 読者になる

心魅 - cocoromi -

半角スペース時々全角

MediaStoreからある音楽ファイルの情報を取得する

コード上である音楽ファイルのタイトルやアーティストなどを取得したい時がある。


え?ない?


いやまぁあったんですよ。


はじめに

AndroidではMediaScannerというのが定期的にSDカード内のメディア情報(画像や、音楽、動画)を収集しています。


この収集されたデータにはAPIからコンテンツプロバイダとしてアクセスすることができます。


コンテンツプロバイダに関しては正直まだよくわかってない部分もあるので、他のサイトも参考にしてください。
ContentResolverで画像を読み込む | Android Techfirm Lab
anddev.org • View topic - How to extract ID3 tag from an mp3 file with android

音楽情報のコンテンツプロバイダへのアクセス方法


まずアクセするために以下の情報が必要です。

  • コンテンツプロバイダへのUri
  • 提供している情報の項目名


これらはわかりにくいのですが、android.provider.MediaStoreのあたりを見ていくとわかってきます。
MediaStoreはさらに以下のクラスを内包しています。
それぞれ、音楽、画像と動画情報にアクセするための色々をもっています。

  • MediaStore.Audio
  • MediaStore.Images
  • MediaStore.Video


今回は音楽情報を扱うのでMediaStore.Audioをみていきます。


MediaStore.Audio

このクラスもさらに内部にクラスを持っていますが、それぞれ取り扱っている情報が違います。
クラス名でなんとなくわかると思います。


今回は曲のタイトルにアクセスしたいので(消去法で)MediaStore.Audio.Mediaを使います。

データを取得してみる

まずはMediaStore.Audio.Mediaが持っている情報を全部取得してみます。

        ContentResolver resolver = c.getContentResolver();
        Cursor cursor = resolver.query(
        		MediaStore.Audio.Media.EXTERNAL_CONTENT_URI ,  //データの種類
        		null ,                                                                          //取得する
項目 nullは全部
        		null , //フィルター条件 nullはフィルタリング無し 
        		null , //フィルター用のパラメータ
        		null   //並べ替え
        );
        Log.d( "TEST" , Arrays.toString( cursor.getColumnNames() ) );  //項目名の一覧を出力
        Log.d( "TEST" , cursor.getCount() + "" ); //取得できた件数を表示

次に取得した情報をもっと詳細に表示してみます。
詳細に表示するためには項目名を知る必要がありますが、それはMediaStore.Audio.Media | Android Developersのinherited Constantsを見てください。


android.provider.MediaStore.Audio.AudioColumnsの下にARTISTやALBUM、android.provider.MediaStore.MediaColumnsの下にTITLEがあるのでこれを取得してみましょう。


        ContentResolver resolver = c.getContentResolver();
        Cursor cursor = resolver.query(
        		MediaStore.Audio.Media.EXTERNAL_CONTENT_URI , 
        		new String[]{
        				MediaStore.Audio.Media.ALBUM ,
        				MediaStore.Audio.Media.ARTIST ,
        				MediaStore.Audio.Media.TITLE
        		},    // keys for select. null means all
        		null,
        		null,
        		null
        );
        

        while( cursor.moveToNext() ){
        	Log.d("TEST" , "====================================");
        	Log.d("TEST" , cursor.getString( cursor.getColumnIndex( MediaStore.Audio.Media.ALBUM ) ) ); //アルバム名の取得
        	Log.d("TEST" , cursor.getString( cursor.getColumnIndex( MediaStore.Audio.Media.ARTIST ) ) ); //アーティスト名の取得
        	Log.d("TEST" , cursor.getString( cursor.getColumnIndex( MediaStore.Audio.Media.TITLE ) ) ); //タイトルの取得
        }


cursorの説明は省きますが、項目の指定にMediaStore.Audio.Mediaの定数を使いました。
こんな感じでAndroidのコンテンツプロバイダへのアクセスに必要なデータは種類に応じたクラスが持っているのでそれを使えばコーディングすることが出来ます。




最後に、ファイルに対応した、曲情報を取得します。さっきのinherited Constantsを眺めていくとDISPLAY_NAMEが使えそうですね。

DISPLAY_NAME
The display name of the file
Type: TEXT


検索条件はSQLのwhere句のように(っていうかまるっきりwhere句ですが)指定します。
その際"?"を埋め込んでおくと次の文字配列で置き換えてくれます。

        //f is instance of File
        ContentResolver resolver = c.getContentResolver();
        Cursor cursor = resolver.query(
        		MediaStore.Audio.Media.EXTERNAL_CONTENT_URI , 
        		new String[]{
        				MediaStore.Audio.Media.ALBUM ,
        				MediaStore.Audio.Media.ARTIST ,
        				MediaStore.Audio.Media.TITLE
        		},    // keys for select. null means all
        		MediaStore.Audio.Media.DISPLAY_NAME + "=?",
        		new String[]{
        			
        			f.getName()
        		},
        		null
        );
        

        while( cursor.moveToNext() ){
        	Log.d("TEST" , "====================================");
        	Log.d("TEST" , cursor.getString( cursor.getColumnIndex( MediaStore.Audio.Media.ALBUM ) ) ); //アルバム名の取得
        	Log.d("TEST" , cursor.getString( cursor.getColumnIndex( MediaStore.Audio.Media.ARTIST ) ) ); //アーティスト名の取得
        	Log.d("TEST" , cursor.getString( cursor.getColumnIndex( MediaStore.Audio.Media.TITLE ) ) ); //タイトルの取得
        }

まとめ

Android内の画像、音楽や動画のメタ情報などにアクセスしたくなったら、MediaStore以下のクラスをながめつつContentResolverのqueryメソッドの引数を決める。

ぶっちゃけめんどくさい。