不幸的是,我用的不是这个代码.

在用户拒绝摄像头访问后,我想请求他们在下次try 加载摄像头时再次使用摄像头(在本例中,是使用摄像头视图的条形码 scanner ).我总是得到AVAuthorizationStatusDenied,然后granted总是自动返回NO,即使我在代码中再次请求它.

我的许多用户都在给我发邮箱,说"当我try 条形码扫描时,我的屏幕是黑色的",这是因为他们出于某种原因拒绝了摄像头的访问.我希望能够再次提醒他们,因为很可能否认是错误的.

有没有可能做到这一点?

    AVAuthorizationStatus authStatus = [AVCaptureDevice authorizationStatusForMediaType:AVMediaTypeVideo];
    if(authStatus == AVAuthorizationStatusAuthorized)
    {
        NSLog(@"%@", @"You have camera access");
    }
    else if(authStatus == AVAuthorizationStatusDenied)
    {
        NSLog(@"%@", @"Denied camera access");

        [AVCaptureDevice requestAccessForMediaType:AVMediaTypeVideo completionHandler:^(BOOL granted) {
            if(granted){
                NSLog(@"Granted access to %@", AVMediaTypeVideo);
            } else {
                NSLog(@"Not granted access to %@", AVMediaTypeVideo);
            }
        }];
    }
    else if(authStatus == AVAuthorizationStatusRestricted)
    {
        NSLog(@"%@", @"Restricted, normally won't happen");
    }
    else if(authStatus == AVAuthorizationStatusNotDetermined)
    {
        NSLog(@"%@", @"Camera access not determined. Ask for permission.");

        [AVCaptureDevice requestAccessForMediaType:AVMediaTypeVideo completionHandler:^(BOOL granted) {
            if(granted){
                NSLog(@"Granted access to %@", AVMediaTypeVideo);
            } else {
                NSLog(@"Not granted access to %@", AVMediaTypeVideo);
            }
        }];
    }
    else
    {
        NSLog(@"%@", @"Camera access unknown error.");
    }

推荐答案

经过一些研究,你似乎不能做我想做的事.下面是我编写的另一个选项,如果在iOS 8+上,我会弹出一个对话框并自动打开设置应用程序.

注意:

  • 由于iOS 10,您需要在信息中指定NSCameraUsageDescription个密钥.plist必须能够请求摄像头访问,否则你的应用程序将在运行时崩溃.
  • 一旦用户更改了你的应用程序的任何权限,就会终止你的应用程序.在用户点击"Go"按钮之前,相应地处理并保存任何需要的数据.
  • 在iOS 8和iOS 11之间的某个时刻,苹果不再要求用户touch 设置应用程序中的隐私单元,以便访问和更改摄像头设置.您可能需要根据用户使用的iOS版本更改用户在设置应用程序中应该执行的操作说明.如果有人想在下面留下 comments ,告诉我们到底是什么版本的iOS,那就太棒了.
  • 截至本答案的最后一次编辑,以下代码正在iOS 14.2上运行.

Swift 5.2:

在视图控制器的顶部:

import AVFoundation

在打开相机视图之前:

@IBAction func goToCamera()
{
    let status = AVCaptureDevice.authorizationStatus(for: .video)
    switch (status)
    {
    case .authorized:
        self.popCamera()

    case .notDetermined:
        AVCaptureDevice.requestAccess(for: .video) { (granted) in
            if (granted)
            {
                self.popCamera()
            }
            else
            {
                self.camDenied()
            }
        }

    case .denied:
        self.camDenied()

    case .restricted:
        let alert = UIAlertController(title: "Restricted",
                                      message: "You've been restricted from using the camera on this device. Without camera access this feature won't work. Please contact the device owner so they can give you access.",
                                      preferredStyle: .alert)

        let okAction = UIAlertAction(title: "OK", style: .default, handler: nil)
        alert.addAction(okAction)
        self.present(alert, animated: true, completion: nil)
    @unknown default:
        fatalError()
    }
}

带有完成块的拒绝alert :

func camDenied()
{
    DispatchQueue.main.async
    {
        var alertText = "It looks like your privacy settings are preventing us from accessing your camera to do barcode scanning. You can fix this by doing the following:\n\n1. Close this app.\n\n2. Open the Settings app.\n\n3. Scroll to the bottom and select this app in the list.\n\n4. Turn the Camera on.\n\n5. Open this app and try again."

        var alertButton = "OK"
        var goAction = UIAlertAction(title: alertButton, style: .default, handler: nil)

        if UIApplication.shared.canOpenURL(URL(string: UIApplication.openSettingsURLString)!)
        {
            alertText = "It looks like your privacy settings are preventing us from accessing your camera to do barcode scanning. You can fix this by doing the following:\n\n1. Touch the Go button below to open the Settings app.\n\n2. Turn the Camera on.\n\n3. Open this app and try again."

            alertButton = "Go"

            goAction = UIAlertAction(title: alertButton, style: .default, handler: {(alert: UIAlertAction!) -> Void in
                UIApplication.shared.open(URL(string: UIApplication.openSettingsURLString)!, options: [:], completionHandler: nil)
            })
        }

        let alert = UIAlertController(title: "Error", message: alertText, preferredStyle: .alert)
        alert.addAction(goAction)
        self.present(alert, animated: true, completion: nil)
    }
}

Objective-C:

在视图控制器的顶部:

#import <AVFoundation/AVFoundation.h>

在打开相机视图之前:

- (IBAction)goToCamera
{
    AVAuthorizationStatus authStatus = [AVCaptureDevice authorizationStatusForMediaType:AVMediaTypeVideo];
    if(authStatus == AVAuthorizationStatusAuthorized)
    {
        [self popCamera];
    }
    else if(authStatus == AVAuthorizationStatusNotDetermined)
    {
        NSLog(@"%@", @"Camera access not determined. Ask for permission.");
        
        [AVCaptureDevice requestAccessForMediaType:AVMediaTypeVideo completionHandler:^(BOOL granted)
        {
            if(granted)
            {
                NSLog(@"Granted access to %@", AVMediaTypeVideo);
                [self popCamera];
            }
            else
            {
                NSLog(@"Not granted access to %@", AVMediaTypeVideo);
                [self camDenied];
            }
        }];
    }
    else if (authStatus == AVAuthorizationStatusRestricted)
    {
        // My own Helper class is used here to pop a dialog in one simple line.
        [Helper popAlertMessageWithTitle:@"Error" alertText:@"You've been restricted from using the camera on this device. Without camera access this feature won't work. Please contact the device owner so they can give you access."];
    }
    else
    {
        [self camDenied];
    }
}

拒绝alert :

- (void)camDenied
{
    NSLog(@"%@", @"Denied camera access");
    
    NSString *alertText;
    NSString *alertButton;
    
    BOOL canOpenSettings = (&UIApplicationOpenSettingsURLString != NULL);
    if (canOpenSettings)
    {
        alertText = @"It looks like your privacy settings are preventing us from accessing your camera to do barcode scanning. You can fix this by doing the following:\n\n1. Touch the Go button below to open the Settings app.\n\n2. Turn the Camera on.\n\n3. Open this app and try again.";
        
        alertButton = @"Go";
    }
    else
    {
        alertText = @"It looks like your privacy settings are preventing us from accessing your camera to do barcode scanning. You can fix this by doing the following:\n\n1. Close this app.\n\n2. Open the Settings app.\n\n3. Scroll to the bottom and select this app in the list.\n\n4. Turn the Camera on.\n\n5. Open this app and try again.";
        
        alertButton = @"OK";
    }
    
    UIAlertView *alert = [[UIAlertView alloc]
                          initWithTitle:@"Error"
                          message:alertText
                          delegate:self
                          cancelButtonTitle:alertButton
                          otherButtonTitles:nil];
    alert.tag = 3491832;
    [alert show];
}

代表调用UIAlertView:

- (void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex
{
    if (alertView.tag == 3491832)
    {
        BOOL canOpenSettings = (&UIApplicationOpenSettingsURLString != NULL);
        if (canOpenSettings)
            [[UIApplication sharedApplication] openURL:[NSURL URLWithString:UIApplicationOpenSettingsURLString]];
    }
}

Objective-c相关问答推荐

[NSNull new]和[NSNull NULL]有什么不同?

单例实例与类方法

UICollectionView:一行或一列

NSTimeZone:localTimeZone 和 systemTimeZone 有什么区别?

iOS performSelectorOnMainThread 有多个参数

如何为代码自动格式化设置 Xcode 插件

在 Xcode 中为无法识别的 Select 器创建断点

如何将 UISlider 垂直放置?

如何删除应用程序指定目录中的所有文件?

无法加载从笔尖引用的图像

当服务器上的图像文件更改时,我的应用程序中的 SDWebImage 缓存图像会发生什么情况?

无法访问 dispatch_async 中的全局变量:变量不可赋值(缺少 _block 类型说明符)

从 UITabBarController 在当前上下文中呈现模态视图控制器后出现黑屏

MKAnnotation 图像偏移与自定义引脚图像

主队列上的 performSelectorOnMainThread: 和 dispatch_async() 有什么区别?

cellForRowAtIndexPath 是如何工作的?

获取临时目录中文件的文件路径和 URL

NSMutableArray addObject 不起作用

iOS:开源 VoIP/SIP Objective-C 代码

Objective-C:如何向 NSURL 添加查询参数?