酢ろぐ!

カレーが嫌いなスマートフォンアプリプログラマのブログ。

Androidでヘッドセット(イヤホン)の接続状態の変化を検出する

Androidでヘッドセット(イヤホン)の接続状態が変わったイベントを取得する必要がでてきました。

Androidでヘッドセット(イヤホン)の接続状態の変化を検出する

ヘッドセットの状態変更を検出するIntentが用途別に2つ存在しています。Intent.ACTION_HEADSET_PLUGAudioManager.ACTION_AUDIO_BECOMING_NOISYです。

Intent 説明
ACTION_HEADSET_PLUG イヤホンの装着
ACTION_AUDIO_BECOMING_NOISY 音声経路の変更(スピーカーから音が鳴ってしまうよ)

それぞれのイベントの通知を受け取るためには、Activityの中でBroadcastReceiverで変化を受け取るレシーバーを実装します。

private BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
    @Override
    public void onReceive(Context context, Intent intent) {
        final String action = intent.getAction();
        if (action == null) {
            return;
        }

        switch (action) {
            case Intent.ACTION_HEADSET_PLUG:
                Log.e(TAG, "Intent.ACTION_HEADSET_PLUG");
                int state = intent.getIntExtra("state", -1);
                if (state == 0) {
                    // ヘッドセットが装着されていない・外された
                } else if (state > 0) {
                    // イヤホン・ヘッドセット(マイク付き)が装着された
                }
                break;
            case AudioManager.ACTION_AUDIO_BECOMING_NOISY:
                Log.e(TAG, "AudioManager.ACTION_AUDIO_BECOMING_NOISY");
                // 音声経路の変更!大きな音が鳴りますよ!!
                break;
         default:
                break;
        }
    }
};

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    registerReceiver(broadcastReceiver, new IntentFilter(Intent.ACTION_HEADSET_PLUG));
    registerReceiver(broadcastReceiver, new IntentFilter(AudioManager.ACTION_AUDIO_BECOMING_NOISY));
}

@Override
protected void onDestroy() {
    super.onDestroy();
    
    unregisterReceiver(broadcastReceiver);
}

Intent.ACTION_HEADSET_PLUGの場合は、stateの数値によって状態を判定することができます。0であればヘッドセットはついていない、1以上であればヘッドセット・またはイヤホンが装着された状態です。

AudioManager.ACTION_AUDIO_BECOMING_NOISYの場合は、イヤホンを外してスピーカーから音が鳴る前の音声経路の変更で通知されます。

ヘッドセットの着脱を検出したい場合はIntent.ACTION_HEADSET_PLUGを使用することになります。

ACTION_AUDIO_BECOMING_NOISYとACTION_HEADSET_PLUGの違い

では、ヘッドセットが外れる場合の通知であれば両方とも使えるのではないか?と考えてしまいます。

意味の違いはあるのですが、一番の違いとしてはIntent.ACTION_HEADSET_PLUGよりもAudioManager.ACTION_AUDIO_BECOMING_NOISYの方が1秒くらい通知が早いです

09-30 19:03:34.842 AudioManager.ACTION_AUDIO_BECOMING_NOISY
09-30 19:03:35.873 Intent.ACTION_HEADSET_PLUG

用途によって使い分けてみてください。