Проверьте, подключена ли гарнитура на разных уровнях API.

У меня есть приложение, предназначенное для уровня API 19+. Мне нужно проверить, подключена ли гарнитура (проводная или Bluetooth).

Я вижу, что AudioManager.isWiredHeadsetOn() устарел, начиная с уровня API 16, а документация предлагает использовать AudioManager.getDevices(), который был введен только начиная с уровня API 23.

Вопрос. Как правильно проверить, подключена ли гарнитура для уровней API 16–22?

Примечание. Я знаю, что могу использовать устаревший метод, но не хочу. Если они устарели, они должны были ввести замену API (хотя я не могу найти).


person Sasha Shpota    schedule 01.09.2018    source источник
comment
Возможным обходным решением может быть использование NotificationListenerService.getActiveNotifications, поскольку при подключении гарнитуры выдается уведомление, но это доступно только в API 18.   -  person TDG    schedule 23.09.2018
comment
Для правильного прослушивания трансляций с подключенной/исключенной проводной гарнитурой см. stackoverflow.com/questions/14708636   -  person ozbek    schedule 26.09.2018


Ответы (2)


Вам нужно прослушивать ACTION_HEADSET_PLUG, который срабатывает при событиях гарнитуры, а также, по-видимому, срабатывает периодически, даже если ничего не меняется.

Из моего существующего кода у меня есть это в onCreate моей основной службы:

    // listen for headphone events so we can auto switch the audio output when headphones are plugged in
    myHeadphoneMonitor = new HeadphoneMonitor();
    android.content.IntentFilter headphone_filter = new 
    android.content.IntentFilter(Intent.ACTION_HEADSET_PLUG);
    registerReceiver(myHeadphoneMonitor, headphone_filter);

А мой монитор выглядит так:

  package com.myname.foo;

  import android.content.BroadcastReceiver;
  import android.content.Context;
  import android.content.Intent;
  import android.util.Log;
  import android.os.Message;


  public class HeadphoneMonitor extends BroadcastReceiver
  {
    public boolean headphonesActive=false;

    @Override
    public void onReceive(final Context context, final Intent intent)
    {
        if (intent.getAction().equals(Intent.ACTION_HEADSET_PLUG))
        {
            int state = intent.getIntExtra("state", -1);
            switch (state) {
                    case 0:
                        Log.d("HeadphoneMonitor", "Headset is unplugged");
                        headphonesActive=false;
                        break;
                    case 1:
                        Log.d("HeadphoneMonitor", "Headset is plugged in");
                        headphonesActive=true;
                        break;
                    default:
                        Log.d("HeadphoneMonitor", "I have no idea what the headset state is");
                        break;
            }

            // push this event onto the queue to be processed by the Handler
            Message msg = MyApp.uiHandler.obtainMessage(MyApp.HEADPHONE_EVENT);
            MyApp.uiHandler.sendMessage(msg);
        }
    }
  }

В манифесте ничего не нужно для прослушивания этого широковещательного события.

person spartygw    schedule 26.09.2018
comment
Как я узнаю, подключен он или нет при запуске приложения? Приемник будет инициализирован с помощью headphonesActive = false, что может быть неверным, если подключена гарнитура. Я что-то упускаю? - person Sasha Shpota; 26.09.2018
comment
@OleksandrShpota это событие, отправленное системой с фиксированной трансляцией, так что это означает, что как только вы зарегистрируетесь для намерения, оно запустит событие, и вы получите текущее состояние. - person spartygw; 26.09.2018
comment
Это не будет обрабатывать подключения наушников Bluetooth. - person ozbek; 30.09.2018

Поскольку AndroidStudio предупреждает, что AudioManager.getDevices требует VersionCode M, лучший способ проверить версию следующим образом:

    // ... some code
    boolean isWiredHeadsetOn=false;
    AudioManager mAudioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
    Log.d(TAG, "onCreate:::: retrieved AudioManager instance");
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
        Log.d(TAG, "onCreate:::: BuildVersion>=M");
        AudioDeviceInfo[] mAudioDeviceInfos = mAudioManager.getDevices(AudioManager.GET_DEVICES_OUTPUTS);
        Log.d(TAG, "onCreate:::: got AudioDeviceInfo[]");
        for (int i = 0; i < mAudioDeviceInfos.length; i++) {
            if (mAudioDeviceInfos[i].getType() == AudioDeviceInfo.TYPE_WIRED_HEADSET) {
                Log.d(TAG, "onCreate:::: \n\nfind wiredHeadset!!!\n\n");
                isWiredHeadsetOn=true;
            } else {
                Log.d(TAG, "onCreate:::: find device type: " + mAudioDeviceInfos[i].getType() + ", id: " + mAudioDeviceInfos[i].getProductName());
            }
        }
    } else {
        Log.d(TAG, "onCreate:::: BuildVersion<M");
        isWiredHeadsetOn=mAudioManager.isWiredHeadsetOn();
    }
    // ... continue code

Надеюсь, я смог помочь. С уважением, Cs

person Csongi77    schedule 01.09.2018
comment
Пожалуйста, прочитайте вопрос внимательнее. Вы написали почти то же самое, что я на самом деле делаю прямо сейчас. Но, как я уже говорил, AudioManager.isWiredHeadsetOn() устарел, и я не хочу его использовать. И поскольку он устарел, начиная с API 16, а новые вещи были представлены только в API 23, должно быть что-то промежуточное, и это то, что я ищу. - person Sasha Shpota; 01.09.2018
comment
Проверены журналы различий на уровне API по адресу developer.android.com/guide/. темы/манифест/. Как вы сказали, AudioManager.isWiredHeadsetOn() устарел на уровне API 14 без каких-либо предложений о новом методе. Я не нашел лучшего метода... :( - person Csongi77; 01.09.2018