How to detect ear piece (speaker) availability on iOS devices?

穿精又带淫゛_ 提交于 2019-12-04 19:15:22

1) If you want to check if Ear piece (Receiver speaker) is available on device

You can identify this by simply identifying if Device is iPhone.

UIDevice.current.userInterfaceIdiom == .phone

in iOS prottype AVAudioSessionPortBuiltInReceiver is there for builtInreceriver speaker. and according to apple's documentation, This is available only on iPhone device. So there is no need to check for anything else, If its iPhone, You have Ear piece and if its not iPhone (on ipad) it don't have ear piece.

2) If you want to check if head phone is connected or not:

You can use currentroute of share audio session to check if headset is connected or not: here is sample function in swift 3.0

   func IsHeadSetConnected() -> Bool{
        let route  = AVAudioSession.sharedInstance().currentRoute;
        for desc   in route.outputs
        {
            let portType = desc.portType;
            if (portType == AVAudioSessionPortHeadphones)
            {
                return true;
            }

        }

        return false;
    } 

You should also monitor its status by listening for route change:

NotificationCenter.default.addObserver(self, selector: #selector(handleRouteChange(_:)), name: NSNotification.Name.AVAudioSessionRouteChange, object: nil)

here is sample code for handler of notification setup above:

func handleRouteChange(_ notification: Notification) {
    guard
    let userInfo = notification.userInfo,
    let reasonRaw = userInfo[AVAudioSessionRouteChangeReasonKey] as? NSNumber,
    let reason = AVAudioSessionRouteChangeReason(rawValue: reasonRaw.uintValue)
    else { fatalError("Strange... could not get routeChange") }
    switch reason {
    case .oldDeviceUnavailable:
        print("oldDeviceUnavailable")
    case .newDeviceAvailable:
        print("headset/line plugged in")
    case .routeConfigurationChange:
        print("headset pulled out")
    case .categoryChange:
        print("Just category change")
    default:
        print("not handling reason")
    }
}

Swift 3:

    import AVFoundation    

    let currentRoute = AVAudioSession.sharedInstance().currentRoute

    for description in currentRoute.outputs {
        if description.portType == AVAudioSessionPortLineOut {

        }else if description.portType == AVAudioSessionPortHeadphones {

        }else if description.portType == AVAudioSessionPortBluetoothA2DP{

        }else if description.portType == AVAudioSessionPortBuiltInReceiver{

        }else if description.portType == AVAudioSessionPortBuiltInSpeaker{

        }else if description.portType == AVAudioSessionPortHDMI{

        }else if description.portType == AVAudioSessionPortAirPlay{

        }else if description.portType == AVAudioSessionPortBluetoothLE{

        }
    }

Reference:

Apple document: https://developer.apple.com/reference/avfoundation/avaudiosessionportdescription/1669281-output_port_types

The short and simplest way is to check via contains.

func isHeadphonesConnected() -> Bool{
    let routes = AVAudioSession.sharedInstance().currentRoute
    return routes.outputs.contains(where: { (port) -> Bool in
        port.portType == AVAudioSessionPortHeadphones
    })
}

Check for

if let availableInputs = AVAudioSession.sharedInstance().availableInputs {
        for route in availableInputs {
            if ( route.portType == AVAudioSessionPortBuiltInMic ) {
                //built-in-mic available
                break;
            }
        }
    }
Raju Panwar

You can check if built-in-mic is available.

var isMicAvailable = false
if let availableInputs = AVAudioSession.sharedInstance().availableInputs {
    for route in availableInputs {
        if ( route.portType == AVAudioSessionPortBuiltInMic ) {
            //built-in-mic available
            isMicAvailable = true
            break;
        }
    }
}
print("current device has mic - \(isMicAvailable)")

Another way to to check if current device is iPhone.

NSString *deviceType = [UIDevice currentDevice].model;
if([deviceType isEqualToString:@"iPhone"]) {
    //current device is iPhone.
}

One liner Swift 4+ solution to:

Detect if built-in-mic is available

let isMicAvailable: Bool = AVAudioSession.sharedInstance().availableInputs?.first(where: { $0.portType == AVAudioSessionPortBuiltInMic }) != nil

Detect if the Ear piece (Receiver speaker) is available

let isEarPieceAvailable: Bool = AVAudioSession.sharedInstance().currentRoute.outputs.first(where: { $0.portType == AVAudioSessionPortBuiltInReceiver }) != nil
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!