在 iOS8中显示相机许可对话框

当我的应用程序在 iOS8上第一次尝试访问摄像头时,用户会看到一个摄像头权限对话框,很像 iOS7中用于访问摄像头的麦克风对话框。

在 iOS7中,可以预先调用麦克风权限对话框,并查看是否授予了该权限(例如,参见 这个问题)。在 iOS8中是否有类似的方法来调用相机许可对话框?对话框可以组合为麦克风和相机访问权限吗?

77151 次浏览

我遇到了一个类似的问题,如果用户拒绝相机访问时,他们第一次提示,按下按钮采取快照结果在黑色屏幕上的相机模式。

但是我想检测用户已经拒绝访问,并提示他们它必须打开,但我无法找到任何功能来检查当前用户相机访问,是否有这样的功能?

编辑: 下面的检查将让你在 IOS 8中了解摄像头访问:

#import <AVFoundation/AVFoundation.h>


AVAuthorizationStatus status = [AVCaptureDevice authorizationStatusForMediaType:AVMediaTypeVideo];
    

if(status == AVAuthorizationStatusAuthorized) { // authorized
        

}
else if(status == AVAuthorizationStatusDenied){ // denied
        

}
else if(status == AVAuthorizationStatusRestricted){ // restricted
        

        

}
else if(status == AVAuthorizationStatusNotDetermined){ // not determined
        

[AVCaptureDevice requestAccessForMediaType:AVMediaTypeVideo completionHandler:^(BOOL granted) {
if(granted){ // Access has been granted ..do something
               

} else { // Access denied ..do something
               

}
}];
}

这些资料见于下列问题(在 iOS8中如何知道应用程序是否有摄像头访问权限) :

以下是我们最终使用的方法:

if ([AVCaptureDevice respondsToSelector:@selector(requestAccessForMediaType: completionHandler:)]) {
[AVCaptureDevice requestAccessForMediaType:AVMediaTypeVideo completionHandler:^(BOOL granted) {
// Will get here on both iOS 7 & 8 even though camera permissions weren't required
// until iOS 8. So for iOS 7 permission will always be granted.
if (granted) {
// Permission has been granted. Use dispatch_async for any UI updating
// code because this block may be executed in a thread.
dispatch_async(dispatch_get_main_queue(), ^{
[self doStuff];
});
} else {
// Permission has been denied.
}
}];
} else {
// We are on iOS <= 6. Just do what we need to do.
[self doStuff];
}

对我来说,在 iOS7和 iOS8上的工作:

    ALAuthorizationStatus status = [ALAssetsLibrary authorizationStatus];


switch (status) {
case ALAuthorizationStatusAuthorized:
break;


case ALAuthorizationStatusRestricted:
case ALAuthorizationStatusDenied:
break;


case ALAuthorizationStatusNotDetermined:
break;
}

这是我的快速解决方案(iOS8) ,我需要相机的 QR 扫描,所以真的必须提示它的使用。

这提供了

  1. 鼓励用户选择允许如果之前默认允许相机访问问题

  2. 如果用户拒绝了第一个请求,访问设置的简单方法。

在 ViewDidAppear 或 ViewdidLoad 等地方使用呼叫检查摄像头。我需要使用 viewDidAppear 来设置自定义的相机视图约束。

func checkCamera() {
let authStatus = AVCaptureDevice.authorizationStatus(forMediaType: AVMediaTypeVideo)
switch authStatus {
case .authorized: break // Do your stuff here i.e. allowScanning()
case .denied: alertToEncourageCameraAccessInitially()
case .notDetermined: alertPromptToAllowCameraAccessViaSetting()
default: alertToEncourageCameraAccessInitially()
}
}


func alertToEncourageCameraAccessInitially() {
let alert = UIAlertController(
title: "IMPORTANT",
message: "Camera access required for QR Scanning",
preferredStyle: UIAlertControllerStyle.alert
)
alert.addAction(UIAlertAction(title: "Cancel", style: .default, handler: nil))
alert.addAction(UIAlertAction(title: "Allow Camera", style: .cancel, handler: { (alert) -> Void in
UIApplication.shared.openURL(URL(string: UIApplicationOpenSettingsURLString)!)
}))
present(alert, animated: true, completion: nil)
}


func alertPromptToAllowCameraAccessViaSetting() {


let alert = UIAlertController(
title: "IMPORTANT",
message: "Please allow camera access for QR Scanning",
preferredStyle: UIAlertControllerStyle.alert
)
alert.addAction(UIAlertAction(title: "Dismiss", style: .cancel) { alert in
if AVCaptureDevice.devices(withMediaType: AVMediaTypeVideo).count > 0 {
AVCaptureDevice.requestAccess(forMediaType: AVMediaTypeVideo) { granted in
DispatchQueue.main.async() {
self.checkCamera() } }
}
}
)
present(alert, animated: true, completion: nil)
}

感谢 jamix 上面提供的关于如何使用摄像机调度异步的技巧-它使得响应能够更快地显示新设置的摄像机功能。

对不起,混合了尾随闭合. . 想试试它们。

所有的答案似乎都没有检查麦克风和相机的权限。我们的代码将检查授予相机权限但拒绝麦克风访问的场景。

由于我们是 Swift 的新用户,所以粗糙嵌套的闭包和 if语句不太可能是最优的。请分享改进代码的建议!但至少到目前为止,它在测试中是有效的。

    AVCaptureDevice.requestAccessForMediaType(AVMediaTypeVideo, completionHandler: { (videoGranted: Bool) -> Void in
if (videoGranted) {
AVCaptureDevice.requestAccessForMediaType(AVMediaTypeAudio, completionHandler: { (audioGranted: Bool) -> Void in
if (audioGranted) {
dispatch_async(dispatch_get_main_queue()) {
// Both video & audio granted
}
} else {
// Rejected audio
}
})
} else {
// Rejected video
}
})

我对应用程序委托进行访问检查。

import UIKit
import AVFoundation
import Photos


func applicationDidBecomeActive(application: UIApplication) {
cameraAllowsAccessToApplicationCheck()
internetAvailabilityOnApplicationCheck()
photoLibraryAvailabilityCheck()
}


//MARK:- CAMERA ACCESS CHECK
func cameraAllowsAccessToApplicationCheck()
{
let authorizationStatus = AVCaptureDevice.authorizationStatusForMediaType(AVMediaTypeVideo)
switch authorizationStatus {
case .NotDetermined:
// permission dialog not yet presented, request authorization
AVCaptureDevice.requestAccessForMediaType(AVMediaTypeVideo,
completionHandler: { (granted:Bool) -> Void in
if granted {
print("access granted")
}
else {
print("access denied")
}
})
case .Authorized:
print("Access authorized")
case .Denied, .Restricted:
alertToEncourageCameraAccessWhenApplicationStarts()
default:
print("DO NOTHING")
}
}
//MARK:- PHOTO LIBRARY ACCESS CHECK
func photoLibraryAvailabilityCheck()
{
if PHPhotoLibrary.authorizationStatus() == PHAuthorizationStatus.Authorized
{


}
else
{
var cameraUnavailableAlertController = UIAlertController (title: "Photo Library Unavailable", message: "Please check to see if device settings doesn't allow photo library access", preferredStyle: .Alert)


var settingsAction = UIAlertAction(title: "Settings", style: .Destructive) { (_) -> Void in
let settingsUrl = NSURL(string:UIApplicationOpenSettingsURLString)
if let url = settingsUrl {
UIApplication.sharedApplication().openURL(url)
}
}
var cancelAction = UIAlertAction(title: "Okay", style: .Default, handler: nil)
cameraUnavailableAlertController .addAction(settingsAction)
cameraUnavailableAlertController .addAction(cancelAction)
self.window?.rootViewController!.presentViewController(cameraUnavailableAlertController , animated: true, completion: nil)
}
}
func internetAvailabilityOnApplicationCheck()
{
//MARK:- INTERNET AVAILABLITY
if InternetReachability.isConnectedToNetwork() {


}
else
{
dispatch_async(dispatch_get_main_queue(), {


//INTERNET NOT AVAILABLE ALERT
var internetUnavailableAlertController = UIAlertController (title: "Network Unavailable", message: "Please check your internet connection settings and turn on Network Connection", preferredStyle: .Alert)


var settingsAction = UIAlertAction(title: "Settings", style: .Destructive) { (_) -> Void in
let settingsUrl = NSURL(string:UIApplicationOpenSettingsURLString)
if let url = settingsUrl {
UIApplication.sharedApplication().openURL(url)
}
}
var cancelAction = UIAlertAction(title: "Okay", style: .Default, handler: nil)
internetUnavailableAlertController .addAction(settingsAction)
internetUnavailableAlertController .addAction(cancelAction)
self.window?.rootViewController!.presentViewController(internetUnavailableAlertController , animated: true, completion: nil)
})
}
}

*

对我来说,问题是由于最近的一些构建配置更改,我的 Info.plist 中没有设置 Bundle nameBundle Display Name。这案子不太可能,但我花了几个小时才搞定。希望能帮到别人。

对于 Swift 3,您可以在第一个视图控制器的 viewWillAppear方法中添加以下内容:

首先导入 AVFoundation框架

import AVFoundation

然后:

override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)


let authorizationStatus = AVCaptureDevice.authorizationStatus(forMediaType: AVMediaTypeVideo)


switch authorizationStatus {
case .notDetermined:
AVCaptureDevice.requestAccess(forMediaType: AVMediaTypeVideo) { granted in
if granted {
print("access granted")
}
else {
print("access denied")
}
}
case .authorized:
print("Access authorized")
case .denied, .restricted:
print("restricted")


}
}

不要忘记在你的 Info.plist上添加 Privacy - Camera Usage Description

  • Swift 3.0解决方案

    进口 AVFoundation

注意: 在 Info.plist 中添加隐私-相机使用描述键

//马克: 相机处理

        func callCamera(){
let myPickerController = UIImagePickerController()
myPickerController.delegate = self;
myPickerController.sourceType = UIImagePickerControllerSourceType.camera


self.present(myPickerController, animated: true, completion: nil)
NSLog("Camera");
}
func checkCamera() {
let authStatus = AVCaptureDevice.authorizationStatus(forMediaType: AVMediaTypeVideo)
switch authStatus {
case .authorized: callCamera() // Do your stuff here i.e. callCameraMethod()
case .denied: alertToEncourageCameraAccessInitially()
case .notDetermined: alertPromptToAllowCameraAccessViaSetting()
default: alertToEncourageCameraAccessInitially()
}
}


func alertToEncourageCameraAccessInitially() {
let alert = UIAlertController(
title: "IMPORTANT",
message: "Camera access required for capturing photos!",
preferredStyle: UIAlertControllerStyle.alert
)
alert.addAction(UIAlertAction(title: "Cancel", style: .default, handler: nil))
alert.addAction(UIAlertAction(title: "Allow Camera", style: .cancel, handler: { (alert) -> Void in
UIApplication.shared.openURL(URL(string: UIApplicationOpenSettingsURLString)!)
}))
present(alert, animated: true, completion: nil)
}


func alertPromptToAllowCameraAccessViaSetting() {


let alert = UIAlertController(
title: "IMPORTANT",
message: "Camera access required for capturing photos!",
preferredStyle: UIAlertControllerStyle.alert
)
alert.addAction(UIAlertAction(title: "Dismiss", style: .cancel) { alert in
if AVCaptureDevice.devices(withMediaType: AVMediaTypeVideo).count > 0 {
AVCaptureDevice.requestAccess(forMediaType: AVMediaTypeVideo) { granted in
DispatchQueue.main.async() {
self.checkCamera() } }
}
}
)
present(alert, animated: true, completion: nil)
}