iOS 相机授权 - 错误状态

Posted

技术标签:

【中文标题】iOS 相机授权 - 错误状态【英文标题】:iOS camera authorization - wrong status 【发布时间】:2015-12-28 18:48:30 【问题描述】:

我使用以下代码检查并请求相机的授权。问题如下。以下场景导致授权状态错误:

    用户首次拒绝授权 终止应用程序 重启应用 离开应用程序,在设置应用程序中授予相机权限 返回应用程序

[AVCaptureDevice authorizationStatusForMediaType:AVMediaTypeVideo] 将返回AVAuthorizationStatusDeclined(如前所述授权)。

在终止并重新启动后会产生AVAuthorizationStatusAuthorized,因为它应该。在这种情况下,用户离开设置并拒绝相机访问,结果将保持AVAuthorizationStatusAuthorized,直到下次重新启动。

有什么我想念的想法吗?

- (void) popCamera 
    UIImagePickerController *picker = [[UIImagePickerController alloc] init];
    picker.delegate = self;
    //picker.allowsEditing = YES;
    #if !(TARGET_IPHONE_SIMULATOR)
    picker.sourceType = UIImagePickerControllerSourceTypeCamera;
    picker.cameraDevice = UIImagePickerControllerCameraDeviceFront;
    #endif
    self.view.translatesAutoresizingMaskIntoConstraints = YES;
    [self presentViewController:picker animated:YES completion:NULL];


- (void)camDenied

    NSLog(@"%@", @"Denied camera access");

    NSString *alertText;
    NSString *alertButton;

    BOOL canOpenSettings = (&UIApplicationOpenSettingsURLString != NULL);
    if (canOpenSettings)
    
        alertText = LSS(@"DeniedCamera1");

        SDCAlertView *alert = [[SDCAlertView alloc]
                              initWithTitle:LSS(@"DeniedCameraTitle")
                              message:alertText
                              delegate:self
                              cancelButtonTitle:LSS(@"Cancel")
                              otherButtonTitles:LSS(@"Goto"), nil];
        alert.tag = 3491832;
        [alert show];
    
    else
    
        alertText = LSS(@"DeniedCamera2");

        SDCAlertView *alert = [[SDCAlertView alloc]
                              initWithTitle:LSS(@"DeniedCameraTitle")
                              message:alertText
                              delegate:self
                              cancelButtonTitle:LSS(@"Cancel")
                              otherButtonTitles:nil];
        alert.tag = 3491832;
        [alert show];
    



- (IBAction) onTakePhoto:(id)sender 
    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)
             
                 [self popCamera];
             
             else
             
                 [self camDenied];
             
         ];
    
    else if (authStatus == AVAuthorizationStatusRestricted)
    
        SDCAlertView *alert = [[SDCAlertView alloc]
                              initWithTitle:LSS(@"RestrictCameraTitle")
                              message:LSS(@"RestrictCamera")
                              delegate:self
                              cancelButtonTitle:LSS(@"OK")
                              otherButtonTitles:nil];
    
    else
    
        [self camDenied];
    

    

原代码致谢:Is there a way to ask user for Camera access after they have already denied it on ios 8?

【问题讨论】:

我不太明白。 1) 用户拒绝访问。 2)应用程序被终止。 3) 用户在设置中授予访问权限。 4) App 再次启动时获得授权状态。到目前为止,一切都很好,这是正确的。但我不明白接下来会发生什么你认为是错误的。您的意思是用户然后转到设置并拒绝访问在应用程序运行时并且它不会影响当前会话? 是的,我是这个意思。用户拒绝=>终止应用程序=>重新启动应用程序=>将应用程序留在后台(多任务)=>转到设置应用程序并更改授权=>返回应用程序(即:左上角的后退按钮)=>状态保持“拒绝”由authorizationStatusForMediaType 报告(但相机正常工作)=> 终止应用程序=> 重新启动应用程序=> 接受状态。反之亦然。好像授权不会更新了。 【参考方案1】:

这似乎是预期的行为。如果 Apple 希望您在运行时对授权更改做出反应,则会有一条通知告诉您它已更改。

但是现在,there is no such notification(据我所知)。您只需调用+authorizationStatusForMediaType:,它要么返回确定状态(如拒绝或授权),要么返回AVAuthorizationStatusNotDetermined 告诉您需要通过requestAccessForMediaType:completionHandler: 请求授权。

很遗憾,这不是一个权威的答案;我只是在这里得出结论和猜测。您可能想在 Apple 的开发者论坛上提问,并希望得到 Apple 工程师的答复。

【讨论】:

我知道没有这样的通知。但是当我使用 +authorizationStatusForMediaType: 查询时,它应该返回正确的状态。为什么需要重启 App 才能正确检测到状态? 也许它正在缓存该值并且不知道实际授权已更改。由于无法获得有关此类授权更改的通知,恕我直言,该值在整个会话期间保持稳定是一件好事:否则您将需要一直查询状态。由于我还没有测试过:我猜如果该方法返回AVAuthorizationStatusAuthorized,即使用户更改了设置,您是否也可以访问相机? 是的,但这太不一致了。即:与位置服务进行比较。您授予授权,应用程序会识别它。让这非常令人不安的是,用户将看到黑屏,而不是收到正确的错误消息。 啊哈,所以即使你得到AVAuthorizationStatusAuthorized,你真的不能再访问相机了吗?那么就真的不协调了。我建议您为此向 Apple 提交错误报告。 问题已解决:当我不调试时,它将终止应用程序。当我调试它会引发异常,但我可以继续应用程序。很奇怪,但至少不会让用户感到困惑。

以上是关于iOS 相机授权 - 错误状态的主要内容,如果未能解决你的问题,请参考以下文章

Phonegap - iOS 文件传输不适用于授权标头

从画廊或相机上传图像到rest api(错误:状态:错误,消息:用户不存在!,数据:空)

Cordova 相机插件 IOS 11 无法从库中选择图像

iOS10以后相机相册等授权问题

如何优雅地使用iOS系统相机相册

如何优雅地使用iOS系统相机相册