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 グループ
タグ: java
[…] MediaPlayerで通知音を鳴らす […]