去年当Google发布了一款iPhone应用程序时引起了一段辩论:他们的程序使用了未公开的API来检测是否电话靠近说话者的耳朵。
而在iPhone 3.0 SDK中,此API可以被任何程序使用了。本文展示怎样使用此API:
临近监测
Apple提供了一个UIDevice类,此单例对象展示了有关运行你程序代码的设备的物理特性。通过设定单例对象的proximityMonitoringEnabled属性可以启动/禁止临近监测:
1 2 | UIDevice *device = [UIDevice currentDevice]; device.proximityMonitoringEnabled = YES; |
设备支持
Apple的文档中提到“并不是所有iPhone OS设备都具有一个接近传感器”。要确定你的设备是否支持临近监测,你应将 proximityMonitoringEnabled属性设为YES,然后检查其值:
1 2 3 4 | UIDevice *device = [UIDevice currentDevice]; device.proximityMonitoringEnabled = YES; if (device.proximityMonitoringEnabled == YES) // do something |
在iPhone 3G上运行上述代码显示其确实支持临近监测;而在模拟器上运行同样的代码则显示它并不支持临近监测。(注意:Apple的文档中有一个错误:它提示要检查proximityStatus属性而不是 proximityMonitoringEnabled属性)。
在大部分情况下,你可能需要提供一套逻辑当电话靠近耳朵旁边时触发某种功能。对于Google程序而言,你需要按下按钮进行声音搜索。
获取接近通知
临近监测事件没有使用大家熟悉的代理(delegate)方式。相反,接近改变会触发notifications(通知)。与delegate相反,notification用于当不止一方对某种改变有兴趣时传播事件。
对事件有兴趣的各方添加一个observer(观察者)到它们希望接收通知的对象。observer构成了一个 notification center当特定事件发生时触发回调。补充我们先前的代码,下面代码注册了一个当临近事件发生时被触发的回调:
1 2 3 4 5 6 | UIDevice *device = [UIDevice currentDevice]; device.proximityMonitoringEnabled = YES; if (device.proximityMonitoringEnabled == YES) [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(proximityChanged:) name:@"UIDeviceProximityStateDidChangeNotification" object:device]; |
下面在代码中加入回调功能。这里,我们只是将临近事件记录在控制台中:
1 2 3 4 | - (void) proximityChanged:(NSNotification *)notification { UIDevice *device = [notification object]; NSLog(@"In proximity: %i", device.proximityState); } |
不管是否设备持续靠近你的耳朵,proximityState属性并不总会保持其值为YES。它会被设为YES,然后很快被复位成NO。你需要自己处理它的状态。以Google程序为例:将手机从耳边移开并不表示搜索结束,一段时间的沉默才指示状态的改变。



