码迷,mamicode.com
首页 > 移动开发 > 详细

iOS 打开扬声器以及插入耳机的操作

时间:2015-07-29 19:14:58      阅读:172      评论:0      收藏:0      [点我收藏+]

标签:

废话不多说说一下现状

网上好多关于扬声器的操作,但是问题多多,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



版权声明:本文为博主原创文章,未经博主允许不得转载。

iOS 打开扬声器以及插入耳机的操作

标签:

原文地址:http://blog.csdn.net/zzuzzl/article/details/47132177

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!