Est-il un moyen de demander à l'utilisateur d'accéder à la Caméra après qu'ils ont déjà refusé sur iOS?

j'utilise ce code, mais malheureusement il ne fonctionne pas.

après qu'un utilisateur a refusé l'accès à la caméra, je veux leur demander la permission d'utiliser à nouveau la caméra la prochaine fois qu'ils essaient de la charger (dans ce cas, c'est un scanner de code-barre en utilisant la vue de la caméra). Je reçois toujours AVAuthorizationStatusDenied et puis granted retourne toujours automatiquement NO même si je le demande à nouveau en code.

beaucoup de mes utilisateurs m'envoient un e-mail disant "Mon l'écran est noir quand j'essaie de codes à barres de numérisation" et c'est parce qu'ils ont refusé accéder à la caméra pour une raison quelconque. Je veux être capable de les inciter à nouveau parce que très probablement le déni était une erreur.

Est-il possible de faire cela?

    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.");
    }
49
demandé sur Ethan Allen 2014-09-27 05:23:48

4 réponses

Après quelques recherches, il semble que vous ne pouvez pas faire ce que je voudrais. Voici l'alternative que j'ai codé pour ouvrir une boîte de dialogue et ouvrir l'application de réglages automatiquement si sur iOS 8+.

quelques notes:

  • depuis iOS 10, vous devez spécifier la touche NSCameraUsageDescription dans vos informations.plist pour être en mesure de demander l'accès à la caméra, sinon votre application va se planter à l'exécution.
  • une fois que l'utilisateur change toutes les permissions pour votre application, il tuer votre application. Manipulez en conséquence et enregistrez toutes les données nécessaires avant que l'utilisateur n'appuie sur le bouton "Go".
  • entre iOS 8 et 11, Apple n'a plus besoin de l'utilisateur pour toucher la cellule de confidentialité dans les applications de configuration afin d'obtenir et de modifier les paramètres de la caméra. Vous pouvez modifier vos instructions sur ce que l'utilisateur est censé faire dans l'application Paramètres, basé sur ce que la version iOS qu'ils utilisent. Si quelqu'un veut laisser un commentaire ci-dessous nous dire à tous ce que exact version iOS qui a changé, ce serait génial.

Swift 4:

au sommet de votre contrôleur de vue:

import AVFoundation

avant d'ouvrir la vue de la caméra:

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

    case .notDetermined:
        AVCaptureDevice.requestAccess(for: AVMediaType.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)
    }
}

Déni d'alerte avec l'achèvement de bloc:

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: UIApplicationOpenSettingsURLString)!)
            {
                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: UIApplicationOpenSettingsURLString)!, options: [:], completionHandler: nil)
                })
            }

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

Objectif-C:

au sommet de votre contrôleur de vue:

#import <AVFoundation/AVFoundation.h>

avant d'ouvrir la vue de la caméra:

- (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];
    }
}

Déni d'alerte:

- (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];
}

appel de la déléguée pour L'UIAlertView:

- (void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex
{
    if (alertView.tag == 3491832)
    {
        BOOL canOpenSettings = (&UIApplicationOpenSettingsURLString != NULL);
        if (canOpenSettings)
            [[UIApplication sharedApplication] openURL:[NSURL URLWithString:UIApplicationOpenSettingsURLString]];
    }
}
77
répondu Ethan Allen 2018-05-01 21:41:21

une fois qu'ils ont refusé l'accès à la caméra, l'utilisateur peut autoriser l'utilisation de la caméra pour votre application dans les paramètres. Par conception, vous ne pouvez pas outrepasser cela dans votre propre code.

vous pouvez détecter ce cas avec le code échantillon suivant et ensuite expliquer à l'utilisateur comment le corriger: iOS 7 UIImagePickerController Caméra No Image

NSString *mediaType = AVMediaTypeVideo; // Or AVMediaTypeAudio

AVAuthorizationStatus authStatus = [AVCaptureDevice authorizationStatusForMediaType:mediaType];

// The user has explicitly denied permission for media capture.
else if(authStatus == AVAuthorizationStatusDenied){
    NSLog(@"Denied");
}
9
répondu StilesCrisis 2017-05-23 12:02:40

Pour Swift 3.0

cela guidera l'utilisateur vers les paramètres pour modifier la permission.

func checkCameraAuthorise() -> Bool {
    let status = AVCaptureDevice.authorizationStatus(forMediaType: AVMediaTypeVideo)
    if status == .restricted || status == .denied {
        let dialog = ZAlertView(title: "", message: "Please allow access to the camera in the device's Settings -> Privacy -> Camera", isOkButtonLeft: false, okButtonText: "OK", cancelButtonText: "Cancel", okButtonHandler:
            { _ -> Void in UIApplication.shared.openURL(URL(string: UIApplicationOpenSettingsURLString)!)}, cancelButtonHandler: { alertView in alertView.dismissAlertView() })
        dialog.show()
        return false
    }
    return true
}
1
répondu AKNinan 2017-05-04 14:12:45

code complet d'Accès Caméra et photothèque

import AVFoundation

pour gérer l'action de la caméra utilisez le code ci-dessous: L'appel de méthode

func openCameraOrLibrary(){
    let imagePicker = UIImagePickerController()
    let alertController : UIAlertController = UIAlertController(title: "Select Camera or Photo Library".localized, message: "", preferredStyle: .actionSheet)
    let cameraAction : UIAlertAction = UIAlertAction(title: "Camera".localized, style: .default, handler: {(cameraAction) in

        if UIImagePickerController.isSourceTypeAvailable(UIImagePickerControllerSourceType.camera) == true {
            if self.isCamAccessDenied() == false { **//Calling cam access method here**
                imagePicker.sourceType = .camera
                imagePicker.delegate = self
                self.present(imagePicker, animated: true, completion: nil)
            }

        }else{
            self.present(self.showAlert(Title: "", Message: "Camera is not available on this Device or accesibility has been revoked!".localized), animated: true, completion: nil)
            self.showTabbar()

        }

    })

    let libraryAction : UIAlertAction = UIAlertAction(title: "Photo Library", style: .default, handler: {(libraryAction) in

        if UIImagePickerController.isSourceTypeAvailable(UIImagePickerControllerSourceType.photoLibrary) == true {

            imagePicker.sourceType = .photoLibrary
            imagePicker.delegate = self
            self.present(imagePicker, animated: true, completion: nil)

        }else{
            self.showTabbar()
            self.present(self.showAlert(Title: "", Message: "Photo Library is not available on this Device or accesibility has been revoked!".localized), animated: true, completion: nil)
        }
    })

    let cancelAction : UIAlertAction = UIAlertAction(title: "Cancel".localized, style: .cancel , handler: {(cancelActn) in
        self.showTabbar()
    })

    alertController.addAction(cameraAction)

    alertController.addAction(libraryAction)

    alertController.addAction(cancelAction)

    alertController.popoverPresentationController?.sourceView = view
    alertController.popoverPresentationController?.sourceRect = view.frame

    self.present(alertController, animated: true, completion: nil)
    self.hideTabbar()

}

méthode pour gérer la fonctionnalité d'accès à la caméra

func isCamAccessDenied()-> Bool
{
    let status = AVCaptureDevice.authorizationStatus(for: AVMediaType.video)
    if status == .restricted || status == .denied {
    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: UIApplicationOpenSettingsURLString)!)
            {
                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 = "OK"

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

            let alert = UIAlertController(title: "Error", message: alertText, preferredStyle: .alert)
            alert.addAction(goAction)
            self.present(alert, animated: true, completion: nil)
        }
        return true
    }
    return false
}
0
répondu Alok 2018-07-04 05:01:12