博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
iOS 打开扬声器以及插入耳机的操作
阅读量:6632 次
发布时间:2019-06-25

本文共 8341 字,大约阅读时间需要 27 分钟。

废话不多说说一下现状

网上好多关于扬声器的操作,可是问题多多。SDK7.X 和SDK7.X以上版本号有点诧异

#import <Foundation/Foundation.h>

#import <AudioToolbox/AudioToolbox.h>

#import <AVFoundation/AVFoundation.h>

@interface AudioManager : NSObject

{

    AVAudioPlayer *m_audioPlayer;

}

@property (atomic, readonly)BOOL _isSpeakerOn;

@property (atomic, readonly)BOOL _isHeadsetOn;

+(AudioManager*)shared;

// 打开扬声器

- (void)setSpeakerOn;

// 关闭扬声器

- (void)setSpeakerOff;

@end

//

//  AudioManager.m

//  AvconNetAndCallDemo

//

//  Created by zjq on 14-7-21.

//  Copyright (c) 2014 zjq. All rights reserved.

//

#import "AudioManager.h"

#import <UIKit/UIKit.h>

#define IOSVersion [[UIDevice currentDevice].systemVersion floatValue]

@implementation AudioManager

@synthesize _isSpeakerOn;

@synthesize _isHeadsetOn;

- (id)init

{

    self = [super init];

    if (self) {

        _isSpeakerOn = NO;

        

        AVAudioSession *audioSession = [AVAudioSession sharedInstance];

        //默认情况下扬声器播放

        [audioSession setCategory:AVAudioSessionCategoryPlayback withOptions:AVAudioSessionCategoryOptionMixWithOthers  error:nil];

        [audioSession setActive:YES error:nil];

        

        UInt32 sessionCategory = kAudioSessionCategory_MediaPlayback;

        AudioSessionSetProperty(kAudioSessionProperty_AudioCategory,

                                sizeof(sessionCategory),

                                &sessionCategory);

        

        

        UInt32 audioRouteOverride = kAudioSessionOverrideAudioRoute_Speaker;

        AudioSessionSetProperty (kAudioSessionProperty_OverrideAudioRoute,

                                 sizeof (audioRouteOverride),

                                 &audioRouteOverride);

        

        AudioSessionAddPropertyListener (kAudioSessionProperty_AudioRouteChange,

                                         audioRouteChangeListenerCallback, (__bridge void *)(self));

        

    }

    return self;

}

static AudioManager *_audioManager = NULL;

+(AudioManager*)shared

{

    static dispatch_once_t onceToken;

    dispatch_once(&onceToken, ^{

        _audioManager = [[AudioManager alloc] init];

    });

    return _audioManager;

}

- (void)setSpeakerOn

{

    NSLog(@"setSpeakerOn:%d",[NSThread isMainThread]);

        UInt32 doChangeDefaultRoute = kAudioSessionOverrideAudioRoute_Speaker;

        

        AudioSessionSetProperty (kAudioSessionProperty_OverrideCategoryDefaultToSpeaker,

                                 sizeof (doChangeDefaultRoute),

                                 &doChangeDefaultRoute

                                 );

        

        _isSpeakerOn = [self checkSpeakerOn];

        _isHeadsetOn = NO;

    

     //[self resetOutputTarget];

   

}

- (void)setSpeakerOff

{

    

    UInt32 doChangeDefaultRoute = kAudioSessionOverrideAudioRoute_None;

    

    AudioSessionSetProperty (kAudioSessionProperty_OverrideCategoryDefaultToSpeaker,

                             sizeof (doChangeDefaultRoute),

                             &doChangeDefaultRoute

                             );

    

    _isSpeakerOn = [self checkSpeakerOn];

}

- (BOOL)checkSpeakerOn

{

    CFStringRef route;

    UInt32 propertySize = sizeof(CFStringRef);

    AudioSessionGetProperty(kAudioSessionProperty_AudioRoute, &propertySize, &route);

    

    if((route == NULL) || (CFStringGetLength(route) == 0))

    {

        // Silent Mode

        NSLog(@"AudioRoute: SILENT, do nothing!");

    }

    else

    {

        NSString* routeStr = (__bridge NSString*)route;

        NSRange speakerRange = [routeStr rangeOfString : @"Speaker"];

        if (speakerRange.location != NSNotFound)

            return YES;

    }

    

    return NO;

}

- (BOOL)hasHeadset

{

    CFStringRef route;

    UInt32 propertySize = sizeof(CFStringRef);

    AudioSessionGetProperty(kAudioSessionProperty_AudioRoute, &propertySize, &route);

    

    if((route == NULL) || (CFStringGetLength(route) == 0))

    {

        // Silent Mode

        NSLog(@"AudioRoute: SILENT, do nothing!");

    }

    else

    {

        NSString* routeStr = (__bridge NSString*)route;

        NSLog(@"AudioRoute: %@", routeStr);

        if ([routeStr isEqualToString:@"ReceiverAndMicrophone"]) {

//            static dispatch_once_t onceToken;

//            dispatch_once(&onceToken, ^{

//                [self setSpeakerOn];

//            });

            [self setSpeakerOn];

        }

        

        NSRange headphoneRange = [routeStr rangeOfString : @"Headphone"];

        NSRange headsetRange = [routeStr rangeOfString : @"Headset"];

        if (headphoneRange.location != NSNotFound)

        {

            return YES;

        } else if(headsetRange.location != NSNotFound)

        {

            return YES;

        }

    }

    return NO;

}

// 推断麦克风是否实用

- (BOOL)hasMicphone

{

    return [[AVAudioSession sharedInstance] isInputAvailable];

}

- (void)erjiOutPutTarget

{

    BOOL hasHeadset = [self hasHeadset];

    

    if (hasHeadset) {

        _isHeadsetOn = YES;

    }

    NSLog (@"Will Set output target is_headset = %@ .", hasHeadset?@"YES":@"NO");

    UInt32 audioRouteOverride = kAudioSessionOverrideAudioRoute_None;

    AudioSessionSetProperty(kAudioSessionProperty_OverrideAudioRoute, sizeof(audioRouteOverride), &audioRouteOverride);

}

- (void)resetOutputTarget

{

    BOOL hasHeadset = [self hasHeadset];

    NSLog (@"Will Set output target is_headset = %@ .", hasHeadset?@"YES":@"NO");

    UInt32 audioRouteOverride =  kAudioSessionOverrideAudioRoute_Speaker;

    AudioSessionSetProperty(kAudioSessionProperty_OverrideAudioRoute, sizeof(audioRouteOverride), &audioRouteOverride);

    _isHeadsetOn = NO;

}

void audioRouteChangeListenerCallback (void *inUserData, AudioSessionPropertyID inPropertyID, UInt32 inPropertyValueS, const void *inPropertyValue)

{

    if (inPropertyID != kAudioSessionProperty_AudioRouteChange)

        return;

    

    // Determines the reason for the route change, to ensure that it is not

    // because of a category change.

    CFDictionaryRef routeChangeDictionary = (CFDictionaryRef)inPropertyValue;

    

    CFNumberRef routeChangeReasonRef = (CFNumberRef)CFDictionaryGetValue (routeChangeDictionary, CFSTR (kAudioSession_AudioRouteChangeKey_Reason));

    

    SInt32 routeChangeReason;

    

    CFNumberGetValue (routeChangeReasonRef, kCFNumberSInt32Type, &routeChangeReason);

    NSLog(@"<<<RouteChangeReason: %d",(int)routeChangeReason);

    NSLog(@"[=======%@",inUserData);

    

    AudioManager *pMgr = (__bridge AudioManager *)inUserData;

    //没有耳机

    if (routeChangeReason == kAudioSessionRouteChangeReason_OldDeviceUnavailable)

    {

        [pMgr setSpeakerOn];

        [pMgr resetOutputTarget];

    }

    else if (routeChangeReason == kAudioSessionRouteChangeReason_NewDeviceAvailable)

    {

        [pMgr erjiOutPutTarget];

    }else if (routeChangeReason == kAudioSessionRouteChangeReason_Override){

        [pMgr setSpeakerOn];

        [pMgr resetOutputTarget];

    }

    NSLog(@"-------->%f",IOSVersion);

    //if (IOSVersion >= 8.0) {

        if (routeChangeReason==8) {

            [pMgr hasHeadset];

        }

    //}

}

//- (BOOL)isAirplayActived

//{

//    CFDictionaryRef currentRouteDescriptionDictionary = nil;

//    UInt32 dataSize = sizeof(currentRouteDescriptionDictionary);

//    AudioSessionGetProperty(kAudioSessionProperty_AudioRouteDescription, &dataSize, &currentRouteDescriptionDictionary);

//

//    BOOL airplayActived = NO;

//    if (currentRouteDescriptionDictionary)

//    {

//        CFArrayRef outputs = CFDictionaryGetValue(currentRouteDescriptionDictionary, kAudioSession_AudioRouteKey_Outputs);

//        if(outputs != NULL && CFArrayGetCount(outputs) > 0)

//        {

//            CFDictionaryRef currentOutput = CFArrayGetValueAtIndex(outputs, 0);

//            //Get the output type (will show airplay / hdmi etc

//            CFStringRef outputType = CFDictionaryGetValue(currentOutput, kAudioSession_AudioRouteKey_Type);

//

//            airplayActived = (CFStringCompare(outputType, kAudioSessionOutputRoute_AirPlay, 0) == kCFCompareEqualTo);

//        }

//        CFRelease(currentRouteDescriptionDictionary);

//    }

//    return airplayActived;

//}

/*

 - (void)openloudspeaker{

 //初始化播放器的时候例如以下设置

 UInt32 sessionCategory = kAudioSessionCategory_MediaPlayback;

 AudioSessionSetProperty(kAudioSessionProperty_AudioCategory,

 sizeof(sessionCategory),

 &sessionCategory);

 

 UInt32 audioRouteOverride = kAudioSessionOverrideAudioRoute_Speaker;

 AudioSessionSetProperty (kAudioSessionProperty_OverrideAudioRoute,

 sizeof (audioRouteOverride),

 &audioRouteOverride);

 

 AVAudioSession *audioSession = [AVAudioSession sharedInstance];

 //默认情况下扬声器播放

 [audioSession setCategory:AVAudioSessionCategoryPlayback error:nil];

 [audioSession setActive:YES error:nil];

 [self handleNotification:YES];

 

 }

 #pragma mark - 监听听筒or扬声器

 - (void) handleNotification:(BOOL)state

 {

 [[UIDevice currentDevice] setProximityMonitoringEnabled:state]; //建议在播放之前设置yes。播放结束设置NO,这个功能是开启红外感应

 

 if(state)//加入监听

 [[NSNotificationCenter defaultCenter] addObserver:self

 selector:@selector(sensorStateChange:) name:@"UIDeviceProximityStateDidChangeNotification"

 object:nil];

 else//移除监听

 [[NSNotificationCenter defaultCenter] removeObserver:self name:@"UIDeviceProximityStateDidChangeNotification" object:nil];

 }

 

 //处理监听触发事件

 -(void)sensorStateChange:(NSNotificationCenter *)notification;

 {

 //假设此时手机靠近面部放在耳朵旁,那么声音将通过听筒输出,并将屏幕变暗(省电啊)

 if ([[UIDevice currentDevice] proximityState] == YES)

 {

 NSLog(@"Device is close to user");

 [[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayAndRecord error:nil];

 }

 else

 {

 NSLog(@"Device is not close to user");

 [[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback error:nil];

 }

 }

 */

@end

转载于:https://www.cnblogs.com/gavanwanggw/p/7140838.html

你可能感兴趣的文章
云服务器ECS出现速度变慢 以及突然断开怎么办?
查看>>
208亿背后的“秘密”
查看>>
全栈必备 敏捷估点
查看>>
作为一名合格的JAVA架构师需要点亮哪些技能树?
查看>>
Kubernetes 在知乎上的应用
查看>>
【死磕 Spring】----- IOC 之解析 bean 标签:BeanDefinition
查看>>
PHP浮点数的精确计算BCMath
查看>>
基于Token认证的WebSocket连接
查看>>
【Solidity】2.合约的结构体 - 深入理解Solidity
查看>>
【IOS-COCOS2D-X 游戏开发之二】【必看篇】总结阐述COCOS2D-X与COCOS2D-IPHONE区别;
查看>>
前端面试回忆录 - 滴滴篇 - 凉面
查看>>
jxl导入Excel 切割List 并使用MyBatis批量插入数据库
查看>>
小程序开发总结
查看>>
管理ORACLE实例
查看>>
JavaScript 闭包
查看>>
java获取当前时间前一周、前一月、前一年的时间
查看>>
话说WEB开发之页面重绘和回流
查看>>
using标识使用
查看>>
T264接口说明
查看>>
SELinux介绍
查看>>