在iOS中检测摄像头的权限
我正在开发一个非常简单的视频应用程序。我使用官方控件:UIImagePickerController 问题就在这里。当首次演示UIImagePickerController时,iOS将请求许可。用户可以单击“是”或“否”。如果用户单击“否”,则控件不会被解除。相反,如果用户一直单击“开始”按钮,计时器将在屏幕始终为黑色时继续运行,用户无法停止计时器或返回。用户唯一能做的就是关闭应用程序。下次显示UIImagePickerController时,它仍然是一个黑屏,如果单击“开始”,用户将无法返回在iOS中检测摄像头的权限,ios,permissions,camera,uiimagepickercontroller,ios-permissions,Ios,Permissions,Camera,Uiimagepickercontroller,Ios Permissions,我正在开发一个非常简单的视频应用程序。我使用官方控件:UIImagePickerController 问题就在这里。当首次演示UIImagePickerController时,iOS将请求许可。用户可以单击“是”或“否”。如果用户单击“否”,则控件不会被解除。相反,如果用户一直单击“开始”按钮,计时器将在屏幕始终为黑色时继续运行,用户无法停止计时器或返回。用户唯一能做的就是关闭应用程序。下次显示UIImagePickerController时,它仍然是一个黑屏,如果单击“开始”,用户将无法返回
我想知道是不是虫子。是否有任何方法可以检测摄像头的权限,以便决定是否显示UIImagePickerController?检查
授权状态
并正确处理案例
NSString *mediaType = AVMediaTypeVideo;
AVAuthorizationStatus authStatus = [AVCaptureDevice authorizationStatusForMediaType:mediaType];
if(authStatus == AVAuthorizationStatusAuthorized) {
// do your logic
} else if(authStatus == AVAuthorizationStatusDenied){
// denied
} else if(authStatus == AVAuthorizationStatusRestricted){
// restricted, normally won't happen
} else if(authStatus == AVAuthorizationStatusNotDetermined){
// not determined?!
[AVCaptureDevice requestAccessForMediaType:mediaType completionHandler:^(BOOL granted) {
if(granted){
NSLog(@"Granted access to %@", mediaType);
} else {
NSLog(@"Not granted access to %@", mediaType);
}
}];
} else {
// impossible, unknown authorization status
}
Swift 4及更新版本
确保:
import AVFoundation
下面的代码检查所有可能的权限状态:
let cameraMediaType = AVMediaType.video
let cameraAuthorizationStatus = AVCaptureDevice.authorizationStatus(for: cameraMediaType)
switch cameraAuthorizationStatus {
case .denied: break
case .authorized: break
case .restricted: break
case .notDetermined:
// Prompting user for the permission to use the camera.
AVCaptureDevice.requestAccess(for: cameraMediaType) { granted in
if granted {
print("Granted access to \(cameraMediaType)")
} else {
print("Denied access to \(cameraMediaType)")
}
}
}
由于iOS 10,您需要指定
NSCameraUsageDescription
输入您的Info.plist以请求摄像头访问,否则您的应用程序将在运行时崩溃。看
有趣的是,你知道iOS会在你在“设置”中更改其相机权限时关闭正在运行的应用程序吗 来自苹果开发者论坛: 如果用户切换你的应用程序的 在“设置”中访问摄影机。这同样适用于任何受保护的 设置中的数据类→隐私部分
Swift:使用AVFoundation
除了@Raptor的回答之外,还应提及以下内容。从iOS 10开始,您可能会收到以下错误:
在从主线程访问引擎后,此应用程序正在从后台线程修改自动布局引擎。这可能会导致引擎损坏和奇怪的崩溃。
要解决此问题,请确保按如下方式处理来自主线程的结果(Swift 3):
快速解决方案
然后为了使用它,你必须
AVCaptureDevice.authorizeVideo(completion: { (status) in
//Your work here
})
首先在Info.plist中指定NSCameraUsageDescription key。
然后检查授权状态(如果已授权),然后出示UIImagePickerController。它会工作。还需要:
\import
或类似的有用提示-如果您正在测试使用此功能的代码,您不能仅从测试设备中删除应用程序,然后重新安装。这样做不会导致iOS重新发出请求对用户来说!对我来说最有效的是每次我想测试时都要更改应用程序的捆绑ID
。这是一件痛苦的事情,但至少是这样。只需记住在完成后将ID设置回原来的位置;-)@Benjohn:不需要更改捆绑ID。你可以转到“设置”>“常规”>“重置”并找到一个可以重置所有内容的设置设备上的权限提示。当然,这也很烦人,因为它会影响你设备上的所有其他应用。如果苹果能在“设置”的“开发”部分添加特定于应用的控件,那就好了。应用…@KennyDeriemaeker:-)苹果可能会回答说我们应该使用专用设备进行测试!对我来说重置我的普通手机会非常糟糕。更改捆绑包Id是一个相当轻松的选择。我记得在提交之前也要将其更改回:-)只需确保不进行完全重置!只需重置隐私和位置设置(iOS 8)就足够了。Info.plist条目是怎么回事?来源?如果被拒绝,requestAccess方法将不起作用。您必须手动显示警报,要求用户转到设置并授予权限。授权相机和照片库如何?授权相机和照片库如何?回复:这是一个错误吗?我想是的,是吧原因似乎是VC显示了来自硬件的数据,但操作系统基本上是空穴来风。iOS的出现可能是产品系列演变的副作用。UIImageViewController
被认为是在iOS 2.0中添加的,文档从未注释以反映AVAuthorizationStatus应该被使用,但它存在于另一个框架中。苹果似乎在这里有一个官方教程:
private func showCameraPermissionPopup() {
let cameraMediaType = AVMediaTypeVideo
let cameraAuthorizationStatus = AVCaptureDevice.authorizationStatus(forMediaType: cameraMediaType)
switch cameraAuthorizationStatus {
case .denied:
NSLog("cameraAuthorizationStatus=denied")
break
case .authorized:
NSLog("cameraAuthorizationStatus=authorized")
break
case .restricted:
NSLog("cameraAuthorizationStatus=restricted")
break
case .notDetermined:
NSLog("cameraAuthorizationStatus=notDetermined")
// Prompting user for the permission to use the camera.
AVCaptureDevice.requestAccess(forMediaType: cameraMediaType) { granted in
DispatchQueue.main.sync {
if granted {
// do something
} else {
// do something else
}
}
}
}
}
extension AVCaptureDevice {
enum AuthorizationStatus {
case justDenied
case alreadyDenied
case restricted
case justAuthorized
case alreadyAuthorized
case unknown
}
class func authorizeVideo(completion: ((AuthorizationStatus) -> Void)?) {
AVCaptureDevice.authorize(mediaType: AVMediaType.video, completion: completion)
}
class func authorizeAudio(completion: ((AuthorizationStatus) -> Void)?) {
AVCaptureDevice.authorize(mediaType: AVMediaType.audio, completion: completion)
}
private class func authorize(mediaType: AVMediaType, completion: ((AuthorizationStatus) -> Void)?) {
let status = AVCaptureDevice.authorizationStatus(for: mediaType)
switch status {
case .authorized:
completion?(.alreadyAuthorized)
case .denied:
completion?(.alreadyDenied)
case .restricted:
completion?(.restricted)
case .notDetermined:
AVCaptureDevice.requestAccess(for: mediaType, completionHandler: { (granted) in
DispatchQueue.main.async {
if granted {
completion?(.justAuthorized)
} else {
completion?(.justDenied)
}
}
})
@unknown default:
completion?(.unknown)
}
}
}
AVCaptureDevice.authorizeVideo(completion: { (status) in
//Your work here
})