Preface
The usual way to monitor headphone plug in iOS is to use the headset provided by the iOS system to notify event avaudiosessionroutechangenotification. The code structure is the following system notification method
Add observation message
[[Nsnotificationcenter Defaultcenter] addobserver:self selector: @selector (audioroutechangelistenercallback:) Name:avaudiosessionroutechangenotification Object:nil];
Implement the Listening method
-(void) Audioroutechangelistenercallback: (nsnotification*) Notification {Nsdictionary *
Interuptiondict = Notification.userinfo;
Nsinteger Routechangereason = [[Interuptiondict Valueforkey:avaudiosessionroutechangereasonkey] integerValue]; Switch (Routechangereason) {case avaudiosessionroutechangereasonnewdeviceavailable: {//headphone insert [UIView a
Nimatewithduration:1 animations:^{self.warningLabel.alpha = 0;
}];
} break;
Case avaudiosessionroutechangereasonolddeviceunavailable: {//Headphone unplugged [UIView animatewithduration:1 animations:^{
Self.warningLabel.alpha = 1;
}];
} break;
Case Avaudiosessionroutechangereasoncategorychange://called at Start-also while other audio wants to play
NSLog (@ "Avaudiosessionroutechangereasoncategorychange");
Break }
}
The advantage of this approach is that the structure is clear and the amount of code is low. The disadvantage is that the notice is sometimes slow, not fast enough, and can not control themselves. In fact, the nature of the monitoring is to initiate a dead loop, non-stop testing the status of the headphone hole. So you can start a thread in your own program, and then generate a runloop, constantly to detect the status of the headphone hole. This is also done in the afnetworking framework. In order to constantly detect the state of the network, Afnetworking is to launch a own runloop thread to listen to the network state. Custom Way
First, define a function to determine whether headphones are plugged into the headphone hole. In the future, in a custom thread, this function is called non-stop.
Determine if headphone hole is plugged in
-(BOOL) Isheadsetpluggedin {
avaudiosessionroutedescription* route = [[Avaudiosession Sharedinstance] Currentroute];
for (avaudiosessionportdescription* desc in [route outputs]) {
if ([[Desc portType] Isequaltostring: Avaudiosessionportheadphones]) return
YES;
return NO;
}
Defines a static variable that is used to save the Runloop object. Defined as a static variable, do not consider the life cycle of this variable.
Static Nsrunloop *_headsetrunloop;
Define the thread that detects headphones
-(Nsthread *) startheadsetthread {
static nsthread *_headsetthread = nil;
Static dispatch_once_t oncepredicate;
Dispatch_once (&oncepredicate, ^{
_headsetthread =
[[Nsthread alloc] initwithtarget:self
Selector: @selector (headsetthreadentrypoint:)
Object:nil];
[_headsetthread start];
return _headsetthread;
}
Generates a runloop that runs all the time
-(void) Headsetthreadentrypoint: (ID) __unused Object {
@autoreleasepool {
[[Nsthread CurrentThread] SetName : @ "Com.olami.infraredTV"];
_headsetrunloop = [Nsrunloop currentrunloop];
[_headsetrunloop Addport:[nsmachport Port] formode:nsdefaultrunloopmode];
[_headsetrunloop run];
}
Here use Nsmachport as input source for Runloop, but this input source does nothing, the function is to let Runloop have been alive, will not perform once to exit. This function is the core code for the entire method implementation.
Using a custom thread to detect headphones
Use a custom thread to detect headphones
-(void) Startdetectheadset {
if (_headsetrunloop) {
[self.timer invalidate];
_timer = [Nstimer timerwithtimeinterval:0.5 target:self selector: @selector (detectheadset) Userinfo:nil Repeats:yes];
[_headsetrunloop Addtimer:_timer formode:nsrunloopcommonmodes];
} else{
Dispatch_after (Dispatch_time (Dispatch_time_now, int64_t) (0.5 * nsec_per_sec)), Dispatch_get_main_queue ( ), ^{
if (_headsetrunloop) {
[self.timer invalidate];
_timer = [Nstimer timerwithtimeinterval:0.5 target:self selector: @selector (detectheadset) Userinfo:nil repeats:yes];< C10/>[_headsetrunloop Addtimer:_timer formode:nsrunloopcommonmodes];}}
Here, a timer is used to monitor the plug-and-pull status of the headphone hole. If you want to be more rapid, you can use Cadisplaylink to implement it.
Just set the timer's runloop to a custom line.
Headphone Detection callback function
-(void) Detectheadset {
if ([self Isheadsetpluggedin]) {
NSLog (@ "headset is plugged in");
} else{
NSLog (@ "Headset has been unplugged");
}
Of course, the realization of this is to build the wheel side. But at least it gives the idea that when your app needs to listen for some device or variable status. This method can be used to implement.