首页 > 代码库 > iOS 打开扬声器以及插入耳机的操作

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

废话不多说说一下现状

网上好多关于扬声器的操作,可是问题多多。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 = [superinit];

   if (self) {

       _isSpeakerOn = NO;

        

       AVAudioSession *audioSession = [AVAudioSessionsharedInstance];

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

        [audioSession setCategory:AVAudioSessionCategoryPlaybackwithOptions:AVAudioSessionCategoryOptionMixWithOthers error:nil];

        [audioSessionsetActive:YESerror: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, (__bridgevoid *)(self));

        

    }

    return self;

}



staticAudioManager *_audioManager = NULL;

+(AudioManager*)shared

{

   static dispatch_once_t onceToken;

   dispatch_once(&onceToken, ^{

        _audioManager = [[AudioManageralloc] init];

    });

    return_audioManager;

}


- (void)setSpeakerOn

{

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

        UInt32 doChangeDefaultRoute =kAudioSessionOverrideAudioRoute_Speaker;

        

        AudioSessionSetProperty (kAudioSessionProperty_OverrideCategoryDefaultToSpeaker,

                                sizeof (doChangeDefaultRoute),

                                 &doChangeDefaultRoute

                                 );

        

       _isSpeakerOn = [selfcheckSpeakerOn];

       _isHeadsetOn = NO;

    

     //[self resetOutputTarget];

   

}


- (void)setSpeakerOff

{

    

    UInt32 doChangeDefaultRoute =kAudioSessionOverrideAudioRoute_None;

    

    AudioSessionSetProperty (kAudioSessionProperty_OverrideCategoryDefaultToSpeaker,

                            sizeof (doChangeDefaultRoute),

                             &doChangeDefaultRoute

                             );

    

    _isSpeakerOn = [selfcheckSpeakerOn];

}


- (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 = (__bridgeNSString*)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 = (__bridgeNSString*)route;

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

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

//            static dispatch_once_t onceToken;

//            dispatch_once(&onceToken, ^{

//                [self setSpeakerOn];

//            });

            [selfsetSpeakerOn];

        }

        

       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 [[AVAudioSessionsharedInstance] isInputAvailable];

}


- (void)erjiOutPutTarget

{

   BOOL hasHeadset = [selfhasHeadset];

    

   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 = [selfhasHeadset];

    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 = (__bridgeAudioManager *)inUserData;

    //没有耳机

    if (routeChangeReason ==kAudioSessionRouteChangeReason_OldDeviceUnavailable)

    {

        [pMgrsetSpeakerOn];

        [pMgr resetOutputTarget];

    }

    elseif (routeChangeReason ==kAudioSessionRouteChangeReason_NewDeviceAvailable)

    {

        [pMgrerjiOutPutTarget];

    }elseif (routeChangeReason ==kAudioSessionRouteChangeReason_Override){

        [pMgrsetSpeakerOn];

        [pMgr resetOutputTarget];

    }

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

    //if (IOSVersion >= 8.0) {

       if (routeChangeReason==8) {

            [pMgrhasHeadset];

        }

   //}

}


//- (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 打开扬声器以及插入耳机的操作