去年当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程序为例:将手机从耳边移开并不表示搜索结束,一段时间的沉默才指示状态的改变。

 

原文见:New In iPhone 3.0 Tutorial Series, Part 4: Proximity Monitoring 作者:Dan Grigsby