iOS中检测硬件和传感器

首先要知道,你需要查看所需的硬件或传感器是否存在,而不是假设设备有哪些功能。举个例子,你不能假设只有iPhone才有麦克风,而应该使用API来查看麦克风是否存在。下面这段代码的第一个优势在于,它能自动兼容将来推出的新设备和外接麦克风。

第二个优势呢?这段代码只有一行。

检查麦克风可用性的正确方法

1
2
3
4

- (BOOL) microphoneAvailable  {
AVAudioSession *session = [AVAudioSession sharedInstance];
return session.inputIsAvailable;
}

对于麦克风,你还需要检测输入设备变化的提醒。也就是当用户插入麦克风时,除了在viewDidAppear中做相应的修改外,还要激活UI上的Record按钮。听起来挺酷,不是吗?下面就是具体的实现方法。

检查是否插入麦克风

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12

void audioInputPropertyListener(void* inClientData,
AudioSessionPropertyID inID, UInt32 inDataSize, const void *inData)  {
    UInt32 isAvailable = *(UInt32*)inData;
    BOOL micAvailable = (isAvailable > 0);
    //加入更新UI的代码
}
- (void)viewDidLoad  {
    [super viewDidLoad];
AudioSessionAddPropertyListener(
kAudioSessionProperty_AudioInputAvailable,
audioInputPropertyListener, nil);
}

这里,你要做的就是为kAudioSessionProperty_AudioInputAvailable增加一个属性监听器,然后在回调中检查它的值。

只要增加很少几行代码,就能够写出正确的设备检测代码了。下一步,你需要扩展这段代码,从而支持其他的硬件和传感器。



使用AudioSessionPropertyListeners与观察NSNotification事件很像。当你向一个类中增加一个属性监听器时,需要负责在适当的时候移除它。在前面这个例子中,由于在viewDidLoad中增加了属性监听器,所以需要在didReceiveMemoryWarning方法中移除它。


1. 检测摄像头类型

iPhone最初只有一个摄像头,后来在iPhone 4中增加了一个前置摄像头。iPod touch直到第四代才有摄像头。iPhone 4有前置摄像头,iPad 1(比iPhone 4大)却没有摄像头,而后来的iPad 2同时有了前置和后置摄像头。所有这些都意味着你不应该在假设设备功能的前提下编写代码。实际上使用API更方便。

UIImagePickerController类含有检测源类型可用性的类方法。

检测是否存在摄像头

1
2
3
4

- (BOOL) cameraAvailable  {
  return [UIImagePickerController isSourceTypeAvailable:
UIImagePickerControllerSourceTypeCamera];
}

检测是否存在前置摄像头

1
2
3
4
5
6
7
8
9

- (BOOL) frontCameraAvailable
{
#ifdef __IPHONE_4_0
  return [UIImagePickerController isCameraDeviceAvailable:
UIImagePickerControllerCameraDeviceFront];
#else
  return NO;
#endif
}

检测前置摄像头,需要运行在iOS 4或更高版本中。枚举类型UIImagePickerControllerCameraDeviceFront只在iOS 4及更高版本中可用,因为所有带有前置摄像头的设备(iPhone 4和iPad 2)使用的都是iOS 4及更高版本。所以你用到了宏,如果设备使用的是iOS 3或更低版本就返回NO

类似地,可以检查设备上的摄像头是否具备视频录制功能。iPhone 3GS及更新设备的摄像头支持录制视频。你可以使用以下代码来检查。

检测摄像头是否支持视频录制

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13

- (BOOL) videoCameraAvailable  {
  UIImagePickerController *picker =
[[UIImagePickerController alloc] init];
// 首次调用前面的方法,检查是否存在摄像头
if(![self cameraAvailable])  return NO;
NSArray *sourceTypes = [UIImagePickerController availableMediaTypesForSourceType:
UIImagePickerControllerSourceTypeCamera];

  if (![sourceTypes containsObject:(NSString *)kUTTypeMovie]){
    return NO;
  }
  return YES;
}

这段代码会枚举给定摄像头的可用媒体类型,然后判断它是否包含kUTTypeMovie

2. 检测照片库是否为空

如果你在使用摄像头,几乎总会用到照片库。在调用UIImagePicker显示用户相册前,需要确保它里面有照片。可以用检查摄像头是否存在的方法来查看相册是否为空,只要将UIImagePickerControllerSourceTypePhotoLibraryUIImagePickerControllerSourceTypeSavedPhotosAlbum作为源类型传过去就行了。

3. 检测摄像头闪光灯是否存在

到目前为止,带有摄像头闪光灯的唯一设备是iPhone 4^〔1〕^。在未来几年里,将会有越来越多的设备带有摄像头闪光灯。使用UIImagePickerController的类方法来检查摄像头闪光灯是否存在很容易。

^〔1〕^ 翻译本书时,iPhone 4S和iPhone 5均已发布,它们也带有摄像头闪光灯。——译者注

检测摄像头闪光灯是否存在

1
2
3
4
5
6
7
8

- (BOOL) cameraFlashAvailable  {
#ifdef __IPHONE_4_0
  return [UIImagePickerController isFlashAvailableForCameraDevice:
UIImagePickerControllerCameraDeviceRear];
#else
  return NO;
#endif
}

4. 检测陀螺仪是否存在

陀螺仪是iPhone 4上新增的一个有意思的传感器。iPhone 4之后发布的设备,包括new iPad和iPhone 5,都有陀螺仪。陀螺仪用于测量设备物理位置的相对变化。相比之下,加速计只能测量力的大小,而不能测量扭动。有了陀螺仪,游戏开发者甚至可能实现六轴控制,类似于索尼PlayStation 3控制器或任天堂的Wii控制器提供的功能。你可以使用CoreMotion.framework提供的API来检测陀螺仪是否存在。

检测陀螺仪是否存在

1
2
3
4
5
6
7
8
9

- (BOOL) gyroscopeAvailable  {
#ifdef __IPHONE_4_0
  CMMotionManager *motionManager = [[CMMotionManager alloc] init];
  BOOL gyroAvailable = motionManager.gyroAvailable;
  return gyroAvailable;
#else
  return NO;
#endif
}



如果陀螺仪是你的应用中一个重要功能,而你的目标设备上没有陀螺仪,那么必须用其他输入方法来设计应用。或者也可以在应用的info.plist中的UIRequiredDeviceCapablities键中指定它们,防止没有陀螺仪的设备安装该应用。本章稍后会进一步介绍这个键。


5. 检测指南针或磁力计

指南针可用性可以使用CoreLocation.framework中的CLLocationManager类来检查。调用CLLocationManager中的headingAvailable方法,如果返回值为真,你就可以在应用中使用指南针。指南针在与位置有关的应用和用到了增强现实技术的应用中用处比较大。

6. 检测视网膜屏幕

作为iOS开发人员,你已经知道只要为应用中用到的每个资源增加一个@2x的图片文件,就可以满足视网膜屏幕(Retina Display)的需要。但如果要从远程服务器下载图片,采用视网膜屏幕的设备需要下载的图片分辨率为普通屏幕图片分辨率的两倍。

照片浏览器应用就是一个很好的例子,它类似于Flickr查看器或Instagram。当用户在iPhone 4、new iPad或iPhone 5上启动该应用时,下载的图片分辨率应该为非视网膜屏幕设备上图片分辨率的两倍。一些开发者选择忽略它,直接为所有设备下载高分辨率图片,但这有点浪费带宽,甚至通过EDGE下载时可能要慢得多。相反,你应该在判断出设备使用的是视网膜屏幕之后再下载高分辨率图片。这项检查很容易。

检查设备使用的是否是视网膜屏幕

1
2
3
4
5
6
7
8

- (BOOL) retinaDisplayCapable  {
int scale = 1.0;
UIScreen *screen = [UIScreen mainScreen];
if([screen respondsToSelector:@selector(scale)])
  scale = screen.scale;
if(scale == 2.0f) return YES;
else return NO;
}

在这段代码中,你会找到设备的mainScreen,然后检查该设备是否可以显示适用于视网膜屏幕的高分辨率图片。这样,如果苹果推出了外接视网膜屏幕(可能是更新的苹果影院显示器),支持目前这一代iPad直接以视网膜模式输出,那么你的应用无需任何修改依然能工作。

7. 检测振动提醒功能

在写本书时,只有各个版本的iPhone具备振动提醒功能。很遗憾,没有公开的API用于检测设备是否支持振动功能。不过,AudioToolbox.framework有两个方法用来选择性地振动不同版本的iPhone:

1
2

AudioServicesPlayAlertSound(kSystemSoundID_Vibrate);
AudioServicesPlaySystemSound(kSystemSoundID_Vibrate);

第一个方法会振动iPhone,而在iPod touch/iPad上则会发出“哔哔”的响声。第二个方法只会振动iPhone。在不支持振动的设备上,它什么都不做。如果你正在开发的一款游戏通过振动设备来提示危险,或是开发一款迷宫游戏,当玩家撞到墙时发出振动,那么应该用第二个方法。第一个方法用来提醒用户,包括振动和发出哔哔声,而第二个方法只能用来发出振动。

8. 检测远程控制功能

iOS应用可以处理按下外接耳机上的按钮触发的远程控制事件。处理这类事件,使用如下方法接收通知:

1

[[UIApplication sharedApplication] beginReceivingRemoteControlEvents];

firstResponder中实现如下方法:

1

remoteControlReceivedWithEvent:

调用如下方法,确保在不需要这些事件时关闭该功能:

1

[[UIApplication sharedApplication] endReceivingRemoteControlEvents];

9. 检测拨打电话功能

可以检查设备是否支持拨打电话,方法是查看它是否能打开tel:类型的URL。UIApplication类的canOpenURL:方法可以很方便地检查设备上是否有能够处理特定类型URL的应用。在iPhone上,tel:这类URL由iPhone上的电话应用来处理。该方法还可以用来检查能够处理给定URL的具体应用是否已安装到设备上。

检测拨打电话功能

1
2
3
4

- (BOOL) canMakePhoneCalls  {
  return [[UIApplication sharedApplication]
canOpenURL:[NSURL URLWithString:@"tel://"]];
}



可用性小提示 在iPod touch上,开发者应该完全隐藏面向电话的功能。举个例子,如果你开发一个显示因特网上电话号码列表的黄页应用,应该只在能够拨打电话的设备上显示拨打电话的那个按钮。不要只是简单地禁用它(因为用户做什么都无法启用它)或是显示一个错误提醒。有先例说明,在iPod touch上显示一个“Not an iPhone”错误提醒会导致该应用无法通过苹果应用审核部门的审查。

时间: 2024-08-29 10:33:08

iOS中检测硬件和传感器的相关文章

每次插入U盘等设备都找不到,设备管理器中卸载 ,再扫描检测硬件改动才可以正常问题解决方法

每次插入U盘等设备都找不到,设备管理器查看通用串行总线控制器 点黄色叹号设备 右键 卸载 ,再扫描检测硬件改动 就可以正常问题 解决方法:进入注册表,开始运行中 输入regedit  回车 点击HKEY_LOCAL_MACHINE----------SYSTEM-----------CurrentControlSet-------------Control-----------Class Class项底下找到'通用串行总线控制器'这项,看右面窗口里发现有'upperfilter'或'lowerf

iOS中使用 Reachability 检测网络

iOS中使用 Reachability 检测网络 内容提示:下提供离线模式(Evernote).那么你会使用到Reachability来实现网络检测.   写本文的目的 了解Reachability都能做什么 检测3中网络环境 2G/3G wifi 无网络 如何使用通知 单个controller 多个controller 简单的功能: 仅在wifi下使用 Reachability简介 Reachablity 是一个iOS下... 如果你想在iOS程序中提供一仅在wifi网络下使用(Reeder)

iOS中使用 Reachability 检测网络区分手机网络类型 WiFi 和2 3 4 G

如果你想在iOS程序中提供一仅在wifi网络下使用(Reeder),或者在没有网络状态下提供离线模式(Evernote).那么你会使用到Reachability来实现网络检测. 写本文的目的 了解Reachability都能做什么 检测3中网络环境 2G/3G wifi 无网络 如何使用通知 单个controller 多个controller 简单的功能: 仅在wifi下使用 Reachability简介 Reachablity 是一个iOS下检测,iOS设备网络环境用的库. 监视目标网络是否可

【开发记录】iOS中使用 Reachability 检测网络

如果你想在iOS程序中提供一仅在wifi网络下使用(Reeder),或者在没有网络状态下提供离线模式(Evernote).那么你会使用到Reachability来实现网络检测. 写本文的目的 了解Reachability都能做什么 检测3中网络环境 2G/3G wifi 无网络 如何使用通知 单个controller 多个controller 简单的功能: 仅在wifi下使用 Reachability简介 Reachablity 是一个iOS下检测,iOS设备网络环境用的库. 监视目标网络是否可

软件测试、ios中的测试概念以及步骤

软件测试: 软件测试的目标是应该服务于软件项目的目标,可以通过建议反馈使用更加高效的方法和工具,提升软件开发效率以及软件开发质量.同时还可以通过过一些手段,更早.更快.更多地发现缺陷,从容降低了这些缺陷带来的风险. 软件测试是为了消除更加多的bug,虽然没有能够消除彻底. 但是软件的质量不是通过软件测试,而是软件开发工程师决定的. 软件测试的好处: 1.测试可以对软件预防,然后反应给软件开发工程师,所以及时快速的找到错误. 2.对软件缺陷的检测. 软件测试的类型: 单元测试(Unit Tests

Android中的11种传感器

在Android2.3 gingerbread系统中,google提供了11种传感器供应用层使用. ? 1 2 3 4 5 6 7 8 9 10 11 #define SENSOR_TYPE_ACCELEROMETER       1 //加速度 #define SENSOR_TYPE_MAGNETIC_FIELD      2 //磁力 #define SENSOR_TYPE_ORIENTATION         3 //方向 #define SENSOR_TYPE_GYROSCOPE   

iOS 中 UIView 和 CALayer 的关系

UIView 有一个名叫 layer ,类型为 CALayer 的对象属性,它们的行为很相似,主要区别在于:CALayer 继承自 NSObject ,不能够响应事件. 这是因为 UIView 除了负责响应事件 ( 继承自 UIReponder ) 外,它还是一个对 CALayer 的底层封装.可以说,它们的相似行为都依赖于 CALayer 的实现,UIView 只不过是封装了它的高级接口而已. 那 CALayer 是什么呢? CALayer(图层) 文档对它定义是:管理基于图像内容的对象,允许

iOS开发笔记--iOS中的多线程

摘要 本文主要介绍iOS开发中的三种多线程技术:NSThread, NSOperation/NSOperationQueue, GCD.以及在多线程编程中的注意点和小技巧. 多线程 NSThread NSOperation/NSOperationQueue GCD 目录[-] iOS中的多线程 iOS的三种多线程技术特点: GCD基本思想 队列: 操作: 不同队列中嵌套同步操作dispatch_sync的结果: 同步操作dispatch_sync的应用场景: GCD优点: GCD队列: NSOp

Linux系统中的硬件问题如何排查?(3)

Linux系统中的硬件问题如何排查?(3) 2013-03-27 10:32 核子可乐译 51CTO.com 字号:T | T 在Linux系统中,对于硬件故障问题的排查可能是计算机管理领域最棘手的工作,即使是经验相当丰富的用户有时也会遇上自己搞不定的状况,本文分享一些实用的技巧与处理方法,希望有助于读者朋友理解.查明并最终搞定硬件难题. AD:2014WOT全球软件技术峰会北京站 课程视频发布 Dmesg命令 另外一些颇具价值的信息被保存在内核缓冲区日志当中,我们通常可以利用dmesg命令来调