我想知道如何检测 iPhone 中是否存在 GPS 硬件
4 回答
CLLocation.verticalAccuracy
我发现最好的方法是利用仅针对配备 GPS 的设备设置的事实。当然,这意味着 GPS 可用性只能在第一次位置更新后确定。
来自 Apple 的文档:
确定垂直精度需要具有 GPS 功能的设备。因此,在一些早期的基于 iOS 的设备上,此属性始终包含负值。
更新: 有时,Core Location 也会在 iPhone 4 上发送带有 verticalAccuracy = -1 的 CLLocation 对象。当没有可用的 GPS 定位并且核心位置求助于蜂窝或 Wi-Fi 定位时,它可能会这样做。所以你得到 -1 的事实并不一定意味着你没有 GPS。只有当您获得肯定知道的正值时,您才拥有 GPS。
为了避免仅仅为了知道 GPS 是否存在而请求 GPS 权限,我使用了一个小技巧。由于所有具有真正 GPS 的设备也有 3G,我只检查设备是否有电话运营商。
//Use classLoaders to avoid crashes on iPhone OS 3.x
id netInfo = [[NSClassFromString(@"CTTelephonyNetworkInfo") alloc] init];
if (netInfo)
{
id carrier = [netInfo subscriberCellularProvider];
if ([[carrier carrierName] length] <=0)
{
//NO operator=>NO 3G and no real GPS
}
}
[netInfo release];
当然,这可能不是 100% 的未来证明,但在这一点上效果很好。我在我的 Battery HD 应用程序中使用它来隐藏 GPS 估计,所以我显然不想要求用户对此进行授权。
您无法检测到硬件,至少不能通过官方 SDK。但是,您可以从应用程序(通过 CoreLocation 框架)与它进行交互(即从中获取信息)。这适用于自 iPhone OS 2.0 发布以来发布的所有设备(即使是内部没有真正 GPS 的 iPod touch)。
即使您无法使用 SDK 确定这一点,您也可以利用您对当前模型的了解。如果您将自己限制在 iPhone 3G、iPhone 3GS 和 iPod Touch 第 2 代(我个人不支持较旧的 iPhone edge 或 iPod Touch 第 1 代),那么您已经知道 iPhone 型号配备了真正的 AGPS 单元,而 iPod Touch 2nd一代可以使用 - 如果可用的话 - 地理标记的 wifi 热点。然后,您可以使用以下方法来确定您正在运行的模型:
- (NSString *) deviceModel{
size_t size;
sysctlbyname("hw.machine", NULL, &size, NULL, 0);
char *answer = malloc(size);
sysctlbyname("hw.machine", answer, &size, NULL, 0);
NSString *results = [NSString stringWithCString:answer encoding: NSUTF8StringEncoding];
free(answer);
return results;
}
该方法返回@"iPhone2,1" 用于3GS,@"iPhone1,2" 用于3G,@"iPod2,1" 用于ipod touch 2nd generation;你这样称呼它
NSString *deviceModel = [[self deviceModel] retain];
并按如下方式使用它:
if([self.deviceModel isEqualToString:@"Pod2,1"]){
// no real GPS unit available
// no camera available
...
}