Enable and insert headphones for iOS
Don't talk nonsense about the status quo
Many speaker operations on the Internet, but there are many problems. SDK7.X and SDK7.X versions are a bit strange.
# Import
# Import
# Import
@ Interface AudioManager: NSObject
{
AVAudioPlayer * m_audioPlayer;
}
@ Property (atomic, readonly) BOOL _ isspeakeon;
@ Property (atomic, readonly) BOOL _ isHeadsetOn;
+ (AudioManager *) shared;
// Open the speaker
-(Void) setspeakeon;
// Close the speaker
-(Void) setSpeakerOff;
@ End
//
// AudioManager. m
// AvconNetAndCallDemo
//
// Created by zjq on 14-7-21.
// Copyright (c) 2014 zjq. All rights reserved.
//
# Import AudioManager. h
# Import
# Define IOSVersion [[UIDevice currentDevice]. systemVersion floatValue]
@ Implementation AudioManager
@ Synthesize _ isspeakeon;
@ Synthesize _ isHeadsetOn;
-(Id) init
{
Self = [super init];
If (self ){
_ Isspeakeon = NO;
AVAudioSession * audioSession = [AVAudioSession sharedInstance];
// Speaker playing by default
[AudioSession setCategory: AVAudioSessionCategoryPlayback witexceptions: 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) setspeakeon
{
NSLog (@ setspeakeon: % d, [NSThread isMainThread]);
UInt32 doChangeDefaultRoute = kAudioSessionOverrideAudioRoute_Speaker;
AudioSessionSetProperty (kAudioSessionProperty_OverrideCategoryDefaultToSpeaker,
Sizeof (doChangeDefaultRoute ),
& DoChangeDefaultRoute
);
_ Isspeakeon = [self checkspeakeon];
_ IsHeadsetOn = NO;
// [Self resetOutputTarget];
}
-(Void) setSpeakerOff
{
UInt32 doChangeDefaultRoute = kAudioSessionOverrideAudioRoute_None;
AudioSessionSetProperty (kAudioSessionProperty_OverrideCategoryDefaultToSpeaker,
Sizeof (doChangeDefaultRoute ),
& DoChangeDefaultRoute
);
_ Isspeakeon = [self checkspeakeon];
}
-(BOOL) checkspeakeon
{
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;
Nsange 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 setspeakeon];
//});
[Self setspeakeon];
}
Nsange headphoneRange = [routeStr rangeOfString: @ Headphone];
Nsange headsetRange = [routeStr rangeOfString: @ Headset];
If (headphoneRange. location! = NSNotFound)
{
Return YES;
} Else if (headsetRange. location! = NSNotFound)
{
Return YES;
}
}
Return NO;
}
// Determine whether the microphone is useful
-(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 (@ <
NSLog (@ [========%@, inUserData );
AudioManager * pMgr = (_ bridge AudioManager *) inUserData;
// No earphones
If (routeChangeReason = kAudioSessionRouteChangeReason_OldDeviceUnavailable)
{
[PMgr setspeakeon];
[PMgr resetOutputTarget];
}
Else if (routeChangeReason = kAudioSessionRouteChangeReason_NewDeviceAvailable)
{
[PMgr erjiOutPutTarget];
} Else if (routeChangeReason = kAudioSessionRouteChangeReason_Override ){
[PMgr setspeakeon];
[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, extends tRouteDescriptionDictionary );
//
// 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 {
// Set the following when initializing the player:
UInt32 sessionCategory = kAudioSessionCategory_MediaPlayback;
AudioSessionSetProperty (kAudioSessionProperty_AudioCategory,
Sizeof (sessionCategory ),
& SessionCategory );
UInt32 audioRouteOverride = kAudioSessionOverrideAudioRoute_Speaker;
AudioSessionSetProperty (kAudioSessionProperty_OverrideAudioRoute,
Sizeof (audioRouteOverride ),
& AudioRouteOverride );
AVAudioSession * audioSession = [AVAudioSession sharedInstance];
// Speaker playing by default
[AudioSession setCategory: AVAudioSessionCategoryPlayback error: nil];
[AudioSession setActive: YES error: nil];
[Self handleNotification: YES];
}
# Pragma mark-Listen to the receiver or speaker
-(Void) handleNotification :( BOOL) state
{
[[UIDevice currentDevice] setProximityMonitoringEnabled: state]; // we recommend that you set yes before playing and NO after playing. This function enables infrared sensing.
If (state) // Add a listener
[[Nsicationcenter center defacenter center] addObserver: self
Selector: @ selector (sensorStateChange :) name: @ UIDeviceProximityStateDidChangeNotification
Object: nil];
Else // remove the listener
[[Nsicationcenter center defacenter center] removeObserver: self name: @ UIDeviceProximityStateDidChangeNotification object: nil];
}
// Process listener-triggered events
-(Void) sensorStateChange :( nsicationicationcenter *) notification;
{
// If your phone is near your face and placed near your ears, the audio will be output through the receiver and the screen will be dimmed (power-saving)
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