How to detect ear piece (speaker) availability on

2020-07-30 02:37发布

I want to detect specially on iPad's if there is ear piece available or not.

For example - I can detect if the iOS device hasTourch or not using AVFoundation so is there any way to detect ear piece availability.

6条回答
冷血范
2楼-- · 2020-07-30 02:43

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")
    }
}
查看更多
SAY GOODBYE
3楼-- · 2020-07-30 02:49

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.
}
查看更多
家丑人穷心不美
4楼-- · 2020-07-30 02:59

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

查看更多
老娘就宠你
5楼-- · 2020-07-30 02:59

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
    })
}
查看更多
Animai°情兽
6楼-- · 2020-07-30 03:04

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
查看更多
ゆ 、 Hurt°
7楼-- · 2020-07-30 03:05

Check for

if let availableInputs = AVAudioSession.sharedInstance().availableInputs {
        for route in availableInputs {
            if ( route.portType == AVAudioSessionPortBuiltInMic ) {
                //built-in-mic available
                break;
            }
        }
    }
查看更多
登录 后发表回答