MediaPlayerで通知音を鳴らす

AndroidのMediaPlayerで通知音を鳴らすときに、音量設定を反映させます。

MediaPlayer.createメソッドでインスタンスを作成した状態だと、「メディア音量」というものが反映されるので、setAudioStreamTypeメソッドで再生するオーディオのタイプを指定してやります。これでシステムの設定画面で指定した音量が反映されます。

が、setAudioStreamTypeメソッドをMediaPlayer.createで作成したインスタンスに対して実行すると、
error (-38, 0)
とか
prepareAsync called in state 8
とか
setAudioStream called in state 8
とかエラーが起こります。

これはMediaPlayer.createメソッドが、内部的にすでにprepare(準備)メソッドを呼んでいるためで、ストリームタイプの変更は、準備の前に実行しておく必要があります。

コードはこんな感じになりました。

    public static void playSound(Context context, String url) {

        if (url != null) {
            Uri uri = Uri.parse(url);
            // MediaPlayer.createはprepareを実行してしまうのでnew MediaPlayer()を使う
            // MediaPlayer mp = MediaPlayer.create(context, uri);
            MediaPlayer mp = new MediaPlayer(); 
            try {
                mp.setDataSource(context, uri);
                // setAudioStreamTypeはprepare前に実行する必要がある
                mp.setAudioStreamType(AudioManager.STREAM_NOTIFICATION); 
                mp.setLooping(false); 
                // prepareの前後で使えるメソッドが異なる
                mp.prepare(); 
                mp.seekTo(0);
                mp.start(); 
            } catch (IllegalStateException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

    }

ちなみにマナーモードのときは、何も状態をチェックしなくてもストリームタイプを通知音にしておけば、音は鳴りません。MediaPlayer.createで作ると、メディアになってしまうので、マナーモードが反映されません。

それと、一部機種(音が長いと?)ではsetDataSourceが失敗する場合があるそうです。詳しくは以下。

Ringtoneを再生する時にFileDescriptorを使いたい – 日本Androidの会 | Google グループ


タグ:

新しく会社作りました!

コメント / トラックバック 1 件

コメントをどうぞ