检查耳机是不是连接到不同的 API 级别

Posted

技术标签:

【中文标题】检查耳机是不是连接到不同的 API 级别【英文标题】:Check if headset is connected on different API levels检查耳机是否连接到不同的 API 级别 【发布时间】:2019-02-07 04:59:51 【问题描述】:

我有一个针对 API 级别 19+ 的应用程序。我需要检查耳机是否已连接(有线或蓝牙)。

我看到AudioManager.isWiredHeadsetOn() 从 API 级别 16 开始已被弃用,并且文档提供使用仅从 API 级别 23 开始引入的AudioManager.getDevices()

问题:检查耳机是否连接到 API 级别 16 - 22 的正确方法是什么?

注意:我知道我仍然可以使用已弃用的方法,但我不想这样做。如果他们弃用它,他们应该引入一个替代 API(我虽然找不到)。

【问题讨论】:

一种可能的解决方法是使用NotificationListenerService.getActiveNotifications,因为连接耳机会产生通知,但这仅适用于 API 18。 要正确收听有线耳机插入/拔出广播,请参阅***.com/questions/14708636 【参考方案1】:

您需要侦听 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);
        
    
  

清单中不需要任何内容​​来侦听此广播事件。

【讨论】:

我如何知道它是否在应用程序启动时连接?接收器将使用headphonesActive = false 初始化,如果连接耳机,则可能不正确。我错过了什么吗? @OleksandrShpota 这是一个由系统发送的带有 sticky 广播的事件,这意味着一旦您注册了意图,它将触发该事件,因此您将获得当前状态。 这不会处理蓝牙耳机连接。【参考方案2】:

由于 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

【讨论】:

请更准确地阅读问题。您发布的内容与我现在实际所做的几乎相同。但正如我提到的AudioManager.isWiredHeadsetOn() 已被弃用,我不想使用它。而且由于它从 API 16 开始就被弃用了,而新的东西只在 API 23 中引入,所以必须有一些介于两者之间的东西,这就是我正在寻找的东西。 检查了developer.android.com/guide/topics/manifest/… 的 API 级别差异日志。正如您所说,AudioManager.isWiredHeadsetOn() 在 API 级别 14 已被弃用,没有任何新方法的建议。我没有找到更好的方法... :(

以上是关于检查耳机是不是连接到不同的 API 级别的主要内容,如果未能解决你的问题,请参考以下文章

如何检查 Java 程序的输入/输出流是不是连接到终端?

是否有任何API可以检查WiFi是否已连接到Internet?

无法连接到服务器,服务器:消息 18456,级别 16,状态 1

无法连接到 Heroku API,请检查互联网连接并重试

在 iOS 12 中检查设备是不是连接到 ***

检测蓝牙耳机是不是连接到 Apple Watch