某些设备的设置中未出现iOS相机权限

12
我是一名有用的助手,可以为您进行翻译。以下是需要翻译的内容:

我在尝试使用相机时遇到了一些问题。问题在于某些设备在设置下显示相机条目,而另一些则没有。在那些相机开关未出现的设备上,我无法使用相机,因为它没有权限,并且也不会在设置中出现以启用它们。

这是在正常工作的设备上的样子:

enter image description here

这是在不工作的设备上的显示效果。

enter image description here

当我拍摄这些截图时,应用程序应该已经请求了权限,但它没有这样做。我还验证了这些设备没有启用限制。有什么想法吗?
更新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];

1
摄像头只有在您的应用程序请求权限后才会出现。您能展示一下您用来请求权限的代码吗? - Aaron Brager
添加了。那段代码不是在我启动捕获会话时自动请求权限吗?在应用程序中还有其他地方我正在使用UIImagePickerController来拍照。也许我没有正确处理权限,但如果我之前打开了UIImagePickerController,那么权限就已经被启用了吗? - lucaslt89
我也遇到了同样的问题,非常渴望找到解决方案。如果你已经找到了解决方法,请告诉我...! - durazno
Aaron的答案对我有用。 - lucaslt89
请尝试此解决方案https://dev59.com/DJLea4cB1Zd3GeqPwwWn#34526211 对我有效。 - user3236605
我也遇到了类似的问题(https://stackoverflow.com/questions/59998987/iphone-11-pro-max-with-ios-13-camera-permission-issue?noredirect=1#comment106109682_59998987),与iOS13.3上的多摄像头iPhone有关,其中引入了新的类来处理多摄像头。 https://developer.apple.com/videos/play/wwdc19/225/ - Chathura Palihakkara
5个回答

8

在打开会话之前,您需要请求权限。请使用

[AVCaptureDevice requestAccessForMediaType:completionHandler:]

1
不,这不是真的。“请注意,在创建AVCaptureDeviceInput时,如果状态为AVAuthorizationStatusNotDetermined,则授权对话框将自动显示。”如果您不手动请求权限,它确实会执行此操作,并且在手动执行时也会询问您。但是我遇到了与lucaslt89相同的问题。即使重置了位置和隐私设置,应用程序也不会请求权限,并且手动调用[AVCaptureDevice requestAccessForMediaType:completionHandler:]时会出现相同的结果。这在某些设备上发生,但在其他一些设备上则没有此类问题。为什么?!! - durazno
我也遇到了同样的问题。应用程序没有请求权限。你已经修复了吗? - abhimuralidharan
你们能否帮忙确认一下这个问题是否发生在装有iOS 13的多摄像头iPhone上? - Chathura Palihakkara

3

步骤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
        }
    })

1
我需要相机来使用ARKit。每次显示带有sceneView的VC时,我都会在viewWillAppear中运行checkCameraPermission()。如果用户不允许访问,则会显示一个带有settingsButton的警报。一旦他们按下该按钮,他们将被带到“设置”,相机图标和切换开关将始终存在。
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
}

0
如果上述解决方案无效,您可以考虑在iOS设备上检查此设置。

enter image description here


0

我之前也遇到了同样的问题,直到我将相机类型改为宽屏:

   let deviceDiscoverySession = AVCaptureDevice.DiscoverySession(deviceTypes: [.builtInWideAngleCamera], mediaType: AVMediaType.video, position: .back)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接