iOS 在某些设备的设置下不显示相机权限
iOS Camera permissions doesn't appear under settings in some devices
我在尝试使用相机时遇到了一些问题。问题是有些设备会在设置下向我显示相机条目,而有些则不会。在那些没有出现相机开关的设备上,我无法使用相机,因为它没有权限,而且它也没有出现在启用它们的设置下。
这是它在可用设备上的样子:
这就是它在不起作用的设备中的样子。
当我截取这些屏幕截图时,应用程序应该已经请求权限,但它没有。
我还验证了这些设备没有启用限制。
有什么想法吗?
更新 1:添加了代码
这是我用来显示相机的代码(它在自定义视图下,而不是本机相机视图控制器)
self.captureSession = [[AVCaptureSession alloc] init];
AVCaptureDevice *videoCaptureDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
NSError *error = nil;
AVCaptureDeviceInput *videoInput = [AVCaptureDeviceInput deviceInputWithDevice:videoCaptureDevice error:&error];
if(videoInput)
{
[self.captureSession addInput:videoInput];
}
else
{
NSLog(@"Error: %@", error);
}
AVCaptureMetadataOutput *metadataOutput = [[AVCaptureMetadataOutput alloc] init];
[self.captureSession addOutput:metadataOutput];
[metadataOutput setMetadataObjectsDelegate:self
queue:dispatch_get_main_queue()];
[metadataOutput setMetadataObjectTypes:@[AVMetadataObjectTypeCode39Code, AVMetadataObjectTypeQRCode]];
AVCaptureVideoPreviewLayer *previewLayer = [[AVCaptureVideoPreviewLayer alloc] initWithSession:self.captureSession];
previewLayer.frame = self.view.layer.bounds;
UIView * previewView = [[UIView alloc] initWithFrame:self.view.frame];
[previewView.layer addSublayer:previewLayer];
[self.view addSubview:previewView];
[self.view sendSubviewToBack:previewView];
[self.captureSession startRunning];
您需要在打开会话之前请求权限。使用
[AVCaptureDevice requestAccessForMediaType:completionHandler:]
第 1 步:使用以下密钥(不带引号)
在 info.plist 上提供正确的相机消息访问消息
"Privacy - Camera Usage Description"
第 2 步:objective-C/SWIFT 您需要申请相机访问权限
OBJECTIVE-C
[AVCaptureDevice requestAccessForMediaType:AVMediaTypeVideo completionHandler:^(BOOL granted)
{
if (granted == true)
{
//[self presentViewController : picker animated:YES completion:NULL];
//Do your stuff
}
else
{
UIAlertView *cameraAlert = [[UIAlertView alloc]initWithTitle:STR_APPLICATION_TITLE
message:STR_ALERT_CAMERA_DENIED_MESSAGE
delegate:self
cancelButtonTitle:@"OK"
otherButtonTitles:nil,nil];
[cameraAlert show];
NSLog(@"denied");
}
}];
SWIFT
AVCaptureDevice.requestAccessForMediaType(AVMediaTypeVideo, completionHandler: { (videoGranted: Bool) -> Void in
if (videoGranted) {
//Do Your stuff here
} else {
// Rejected Camera
}
})
我遇到了同样的问题,直到我将我的相机类型更改为广角:
let deviceDiscoverySession = AVCaptureDevice.DiscoverySession(deviceTypes: [.builtInWideAngleCamera], mediaType: AVMediaType.video, position: .back)
我需要相机给用户ARKit
。每次显示带有 sceneView 的 vc 时,我都会 运行 viewWillAppear
中的 checkCameraPermission()
。如果用户不允许访问,将显示带有 settingsButton 的警报。一旦他们按下该按钮,他们将被带到 Settings
,带有切换开关的相机图标将始终存在。
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
checkCameraPermission()
}
func checkCameraPermission() {
let authorizationStatus = AVCaptureDevice.authorizationStatus(for: AVMediaType.video)
switch authorizationStatus {
case .notDetermined:
AVCaptureDevice.requestAccess(for: AVMediaType.video) { [weak self](granted) in
if granted {
print("access granted")
DispatchQueue.main.async { [weak self] in
self?.startSceneViewSession()
}
} else {
print("access denied")
DispatchQueue.main.async { [weak self] in
self?.alertUserCameraPermissionMustBeEnabled()
}
}
}
case .authorized:
print("Access authorized")
startSceneViewSession()
case .denied, .restricted:
print("restricted")
alertUserCameraPermissionMustBeEnabled()
@unknown default:
fatalError()
}
}
func alertUserCameraPermissionMustBeEnabled() {
let message = "Camera access is necessary to use Augemented Reality for this app.\n\nPlease go to Settings to allow access to the Camera.\n Please switch the button to the green color."
let alert = UIAlertController (title: "Camera Access Required", message: message, preferredStyle: .alert)
let settingsAction = UIAlertAction(title: "Settings", style: .default, handler: { (action) in
guard let settingsUrl = URL(string: UIApplication.openSettingsURLString) else { return }
if UIApplication.shared.canOpenURL(settingsUrl) {
UIApplication.shared.open(settingsUrl, completionHandler: { (_) in
})
}
})
alert.addAction(settingsAction)
present(alert, animated: true, completion: nil)
}
// this is for ARKit
func startSceneViewSession() {
sceneView.session.run(configuration)
sceneView.isPlaying = true
}
如果上述解决方案不起作用,您可以考虑在 iOS 设备上检查此设置。
我在尝试使用相机时遇到了一些问题。问题是有些设备会在设置下向我显示相机条目,而有些则不会。在那些没有出现相机开关的设备上,我无法使用相机,因为它没有权限,而且它也没有出现在启用它们的设置下。
这是它在可用设备上的样子:
这就是它在不起作用的设备中的样子。
当我截取这些屏幕截图时,应用程序应该已经请求权限,但它没有。
我还验证了这些设备没有启用限制。
有什么想法吗?
更新 1:添加了代码
这是我用来显示相机的代码(它在自定义视图下,而不是本机相机视图控制器)
self.captureSession = [[AVCaptureSession alloc] init];
AVCaptureDevice *videoCaptureDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
NSError *error = nil;
AVCaptureDeviceInput *videoInput = [AVCaptureDeviceInput deviceInputWithDevice:videoCaptureDevice error:&error];
if(videoInput)
{
[self.captureSession addInput:videoInput];
}
else
{
NSLog(@"Error: %@", error);
}
AVCaptureMetadataOutput *metadataOutput = [[AVCaptureMetadataOutput alloc] init];
[self.captureSession addOutput:metadataOutput];
[metadataOutput setMetadataObjectsDelegate:self
queue:dispatch_get_main_queue()];
[metadataOutput setMetadataObjectTypes:@[AVMetadataObjectTypeCode39Code, AVMetadataObjectTypeQRCode]];
AVCaptureVideoPreviewLayer *previewLayer = [[AVCaptureVideoPreviewLayer alloc] initWithSession:self.captureSession];
previewLayer.frame = self.view.layer.bounds;
UIView * previewView = [[UIView alloc] initWithFrame:self.view.frame];
[previewView.layer addSublayer:previewLayer];
[self.view addSubview:previewView];
[self.view sendSubviewToBack:previewView];
[self.captureSession startRunning];
您需要在打开会话之前请求权限。使用
[AVCaptureDevice requestAccessForMediaType:completionHandler:]
第 1 步:使用以下密钥(不带引号)
在 info.plist 上提供正确的相机消息访问消息"Privacy - Camera Usage Description"
第 2 步:objective-C/SWIFT 您需要申请相机访问权限
OBJECTIVE-C
[AVCaptureDevice requestAccessForMediaType:AVMediaTypeVideo completionHandler:^(BOOL granted)
{
if (granted == true)
{
//[self presentViewController : picker animated:YES completion:NULL];
//Do your stuff
}
else
{
UIAlertView *cameraAlert = [[UIAlertView alloc]initWithTitle:STR_APPLICATION_TITLE
message:STR_ALERT_CAMERA_DENIED_MESSAGE
delegate:self
cancelButtonTitle:@"OK"
otherButtonTitles:nil,nil];
[cameraAlert show];
NSLog(@"denied");
}
}];
SWIFT
AVCaptureDevice.requestAccessForMediaType(AVMediaTypeVideo, completionHandler: { (videoGranted: Bool) -> Void in
if (videoGranted) {
//Do Your stuff here
} else {
// Rejected Camera
}
})
我遇到了同样的问题,直到我将我的相机类型更改为广角:
let deviceDiscoverySession = AVCaptureDevice.DiscoverySession(deviceTypes: [.builtInWideAngleCamera], mediaType: AVMediaType.video, position: .back)
我需要相机给用户ARKit
。每次显示带有 sceneView 的 vc 时,我都会 运行 viewWillAppear
中的 checkCameraPermission()
。如果用户不允许访问,将显示带有 settingsButton 的警报。一旦他们按下该按钮,他们将被带到 Settings
,带有切换开关的相机图标将始终存在。
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
checkCameraPermission()
}
func checkCameraPermission() {
let authorizationStatus = AVCaptureDevice.authorizationStatus(for: AVMediaType.video)
switch authorizationStatus {
case .notDetermined:
AVCaptureDevice.requestAccess(for: AVMediaType.video) { [weak self](granted) in
if granted {
print("access granted")
DispatchQueue.main.async { [weak self] in
self?.startSceneViewSession()
}
} else {
print("access denied")
DispatchQueue.main.async { [weak self] in
self?.alertUserCameraPermissionMustBeEnabled()
}
}
}
case .authorized:
print("Access authorized")
startSceneViewSession()
case .denied, .restricted:
print("restricted")
alertUserCameraPermissionMustBeEnabled()
@unknown default:
fatalError()
}
}
func alertUserCameraPermissionMustBeEnabled() {
let message = "Camera access is necessary to use Augemented Reality for this app.\n\nPlease go to Settings to allow access to the Camera.\n Please switch the button to the green color."
let alert = UIAlertController (title: "Camera Access Required", message: message, preferredStyle: .alert)
let settingsAction = UIAlertAction(title: "Settings", style: .default, handler: { (action) in
guard let settingsUrl = URL(string: UIApplication.openSettingsURLString) else { return }
if UIApplication.shared.canOpenURL(settingsUrl) {
UIApplication.shared.open(settingsUrl, completionHandler: { (_) in
})
}
})
alert.addAction(settingsAction)
present(alert, animated: true, completion: nil)
}
// this is for ARKit
func startSceneViewSession() {
sceneView.session.run(configuration)
sceneView.isPlaying = true
}
如果上述解决方案不起作用,您可以考虑在 iOS 设备上检查此设置。