【问题标题】:Detect existence of camera in iPhone app?检测 iPhone 应用程序中是否存在摄像头?
【发布时间】:2011-04-08 07:42:28
【问题描述】:

我正在编写一个 iOS 应用程序,我需要能够检测设备是否有摄像头。以前,我会检查设备是否是 iPhone,因为只有 iPhone 有摄像头——但随着 iPod Touch 4 的推出,这不再是一个可行的选择。该应用程序在没有相机的情况下运行,但相机的存在增加了功能。

那么,谁能给我提供返回是否有摄像头的代码?

【问题讨论】:

  • Swift 版本:Link

标签: ios objective-c ios-camera


【解决方案1】:

你可以在 UIImagePickerController 中使用+isSourceTypeAvailable: 方法:

if ([UIImagePickerController isSourceTypeAvailable: UIImagePickerControllerSourceTypeCamera])
   // Has camera

【讨论】:

  • 注意:如果摄像头是“受限”的,即使存在摄像头也会返回false。
  • 我现在正在开发一个应用程序,将相机访问权限设置为受限,但这会返回 true,所以 @pulse4life 的评论不正确(至少不再正确 - 使用 iOS 10)。对于访问授权,您应该使用AVAuthorizationStatus
  • 我刚刚在 iOS 10.3.2 上再次测试了这个。如果相机在您的设备上受到限制,它将返回 false。受限是指转到设置>常规>限制并关闭相机(这通常由系统管理员完成)。我相信这是苹果想要的预期行为,因为即使存在相机,它在技术上也不可用。
  • 但是,有时我的 iPhone 摄像头无法正常工作,这可能与软件或硬件有关。如何在 swift 或 Objective c 中以编程方式找出摄像头是否正常工作?
  • @vikramarkaios,您的意思是在相机由于某种原因发生故障的情况下?我怀疑是否有 API 可以检测到这一点。
【解决方案2】:

正如 Juan Boero 所写,请检查:

    if UIImagePickerController.isSourceTypeAvailable(.camera) {...}

但我会添加另一个检查以查看用户是否允许访问相机,正如苹果在他们的 PhotoPicker 示例 (PhotoPicker example Objective-C) 中所建议的那样:

*请注意您必须导入 AVFoundation

SWIFT 5

    let authStatus = AVCaptureDevice.authorizationStatus(for: AVMediaType.video)
    switch authStatus {
        /*
         Status Restricted -
         The client is not authorized to access the hardware for the media type. The user cannot change the client's status, possibly due to active restrictions such as parental controls being in place.
         */
    case .denied, .restricted:
        // Denied access to camera
        // Explain that we need camera access and how to change it.
        let dialog = UIAlertController(title: "Unable to access the Camera", message: "To enable access, go to Settings > Privacy > Camera and turn on Camera access for this app.", preferredStyle: UIAlertController.Style.alert)

        let okAction = UIAlertAction(title: "OK", style: UIAlertAction.Style.default, handler: nil)

        dialog.addAction(okAction)
        self.present(dialog, animated:true, completion:nil)
    case .notDetermined:
        // The user has not yet been presented with the option to grant access to the camera hardware.
        // Ask for it.
        AVCaptureDevice.requestAccess(for: AVMediaType.video, completionHandler: { (grantd) in
        // If access was denied, we do not set the setup error message since access was just denied.
           if grantd {
           // Allowed access to camera, go ahead and present the UIImagePickerController.
            self.showImagePickerForSourceType(sourceType: UIImagePickerController.SourceType.camera)
            }
        })
    case .authorized:
        // Allowed access to camera, go ahead and present the UIImagePickerController.
        self.showImagePickerForSourceType(sourceType: UIImagePickerController.SourceType.camera)
    @unknown default:
        break; //handle other status
    }

SWIFT 3

let authStatus = AVCaptureDevice.authorizationStatus(forMediaType: AVMediaTypeVideo)
    
if authStatus == AVAuthorizationStatus.denied {
    // Denied access to camera
    // Explain that we need camera access and how to change it.
    let dialog = UIAlertController(title: "Unable to access the Camera", message: "To enable access, go to Settings > Privacy > Camera and turn on Camera access for this app.", preferredStyle: UIAlertControllerStyle.alert)
        
    let okAction = UIAlertAction(title: "OK", style: UIAlertActionStyle.default, handler: nil)
        
    dialog.addAction(okAction)
    self.present(dialog, animated:true, completion:nil)
        
} else if authStatus == AVAuthorizationStatus.notDetermined {     // The user has not yet been presented with the option to grant access to the camera hardware.
    // Ask for it.
    AVCaptureDevice.requestAccess(forMediaType: AVMediaTypeVideo, completionHandler: { (grantd) in
    // If access was denied, we do not set the setup error message since access was just denied.
       if grantd {
       // Allowed access to camera, go ahead and present the UIImagePickerController.
            self.showImagePickerForSourceType(sourceType: UIImagePickerControllerSourceType.camera)
        }
    })
} else {
        
    // Allowed access to camera, go ahead and present the UIImagePickerController.
    self.showImagePickerForSourceType(sourceType: UIImagePickerControllerSourceType.camera)

}

func showImagePickerForSourceType(sourceType: UIImagePickerControllerSourceType) {
    
    let myPickerController = UIImagePickerController()
    myPickerController.delegate = self;
    myPickerController.sourceType = sourceType  
    self.present(myPickerController, animated: true, completion: nil)
}

【讨论】:

  • 截至 2018 年 5 月,授权状态可以是 {authorized,notDetermined,denied,restricted} 之一 - 受限状态(即管理员完全阻止用户使用相机)不是以上处理。如果这对您的用例很重要,您可能需要 switch 而不是 if {} else if {}
【解决方案3】:

如果您使用的是 AV Foundation 类而不是 UIImagePickerController,您可以这样做:

BOOL hasCamera = ([[AVCaptureDevice devices] count] > 0);

如果您使用的是 UIImagePickerController,它可能不值得,因为您必须将 AVFoundation.framework 添加到您的项目中。

【讨论】:

  • 这不一定有效。如果限制已关闭摄像头,则可以将麦克风作为设备输出,但没有摄像头可用。最好使用 [[AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo] count]
【解决方案4】:

是的,有一个 API 可以做到这一点:

BOOL isCamera = [UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera];

【讨论】:

    【解决方案5】:

    斯威夫特:

    if UIImagePickerController.isSourceTypeAvailable(.Camera){
    
        //Your code goes here
        //For example you can print available media types:
    
        print(UIImagePickerController.availableMediaTypesForSourceType(.Camera))
    
        }
    

    【讨论】:

      【解决方案6】:

      如果您需要知道设备是否专门有前置或后置摄像头,请使用:

      isCameraAvailable = [UIImagePickerController isCameraDeviceAvailable:UIImagePickerControllerCameraDeviceFront];
      

      【讨论】:

      • 这应该是一个很好的答案,因为这不依赖于“受限”状态
      【解决方案7】:

      检查相机是否可用 (Swift)

      if(!UIImagePickerController.isSourceTypeAvailable(UIImagePickerControllerSourceType.Camera))
      

      【讨论】:

        【解决方案8】:

        您可以使用发现会话 (Swift 5) 检查特定源类型的可用性:

        let discovery = AVCaptureDevice.DiscoverySession.init(deviceTypes: [.builtInWideAngleCamera], mediaType: AVMediaType.video, position: .back)
        let isWideAngleCameraSupported = !discovery.devices.isEmpty
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2015-06-19
          • 2018-04-07
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2020-08-12
          相关资源
          最近更新 更多