How can I detect if camera is restricted by user
Asked Answered
G

5

19

I'm doing an ios app with a button that launch the camera.

I want to enable/disable the button if the device has a camera available or not.

I want to detect if the device has a camera and also when the device has camera but it's restricted (with this) so you can't use it.

How can I detect these two options?

Thanks

Genitals answered 31/5, 2013 at 11:20 Comment(5)
Why don't you test this yourself? Why post a question?Terrazzo
I've tested it and I was able to detect if the device has camera or not but I can't detect when the device has a camera but it is restricted so you can't use it.Genitals
Sorry, I think I misread what you did. I thought you were asking if that code works if the camera has been restricted. That is why I suggested you simply test it. Out of curiosity, if you setup a device with a restricted camera, what does isSourceTypeAvailable return?Terrazzo
Sorry, I'm a total newbie on ios and I don't know how I've tried it before. Now I've tried it again and isSourceTypeAvailable return YES when the camera isn't restricted and NO when it's restricted, as expected. So, the question doesn't make sense. Sorry.Genitals
I've added an answer using isSourceTypeAvailable so that other people can easily see what to do. Please accept that answer if you think it's sufficient!Nicobarese
N
-6

As stated elsewhere, checking the AVAuthorizationStatus won't actually tell you if it's restricted, despite the presence of a "restricted" value in the enum. Instead, I have found that checking if source is enabled to be helpful:

BOOL isCameraAvailable = [UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera];

If isCameraAvailable is NO then the user has most likely disabled camera in Restrictions. See Detect existence of camera in iPhone app?

Nicobarese answered 30/7, 2015 at 0:8 Comment(0)
S
26

To check camera permission status in app use following snippet.

@import AVFoundation;

if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera])
 {
  AVAuthorizationStatus status = [AVCaptureDevice authorizationStatusForMediaType:AVMediaTypeVideo];

  if(status == AVAuthorizationStatusAuthorized) {
    // authorized
  } else if(status == AVAuthorizationStatusDenied){
    // denied
  } else if(status == AVAuthorizationStatusRestricted){
    // restricted
  } else if(status == AVAuthorizationStatusNotDetermined){
      // not determined
      [AVCaptureDevice requestAccessForMediaType:AVMediaTypeVideo completionHandler:^(BOOL granted) {
          if(granted){
            NSLog(@"Granted access");
          } else {
            NSLog(@"Not granted access");
          }
      }];
   }
}
Sennight answered 26/2, 2015 at 11:17 Comment(4)
Make sure to import AVFoundation @import AVFoundation;Hypothecate
This doesn't work (at least on iOS 8.4 which I've tested) for the scenario in question. If you have camera enabled for the app but restricted overall, it will return AVAuthorizationStatusAuthorized which is incorrect. I'm honestly not sure why AVAuthorizationStatusRestricted exists!Nicobarese
@Nicobarese well that may be the case. I havent tested it for the case u have mentioned.Sennight
This is actually half of the correct answer, and it DOES work in iOS 9. There are 3 states that can disable a camera. 1. No camera present, 2. Camera is disabled specifically for this app, and 3. Camera is disabled through Restrictions. Only this catches case 2, but not cases 1 & 3. [UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera] catches cases 1 & 3, but not case 2. If you want to check for all possible reasons a camera may not be available, you need to implement this AND isSourceTypeAvailableBanff
M
4

To check whether camera restricted AVAuthorizationStatus is not enough. As said in documentation:

This status is normally not visible—the AVCaptureDevice class methods for discovering devices do not return devices the user is restricted from accessing.

So for proper check you need to create some capture device, for example, as I did:

AVAuthorizationStatus authStatus = [AVCaptureDevice authorizationStatusForMediaType:AVMediaTypeVideo];
if (authStatus == AVAuthorizationStatusAuthorized) {
    BOOL atLeastOne = NO;
    NSArray *devices = [AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo];
    for (AVCaptureDevice *device in devices) {
        if (device) {
            atLeastOne = YES;
        }
    }
    if (!atLeastOne) {
        authStatus = AVAuthorizationStatusRestricted;
    }
}
Mica answered 10/6, 2015 at 16:21 Comment(0)
L
3

The first time the user tries to use to camera on ios 6 he/she is automatically asked for permission. You don't have to add extra code (before that the authorisationstatus is ALAuthorizationStatusNotDetermined ).

So if user denies the first time you cannot ask again.

You can use ALAssetsLibrary to check this. Check this answer for this solutions : ask-permission-to-access-camera

Hope it helps you.

Larder answered 31/5, 2013 at 11:34 Comment(1)
It seems that ALAssetsLibrary just tells you if you have access to the photos, not the camera.Teethe
H
2

To decide if the camera button should even be enabled (or hidden)You should check the:

    if UIImagePickerController.isSourceTypeAvailable(.Camera){ }

But then I would check to see if the user allowed access to camera as apple suggests in their PhotoPicker example (PhotoPicker example Objective-C):

*please note you have to import AVFoundation

SWIFT 5

    let authStatus = AVCaptureDevice.authorizationStatus(for: AVMediaType.video)
    switch authStatus {
        /*
         Status Restricted -
         The client is not authorized to access the hardware for the media type. The user cannot change the client's status, possibly due to active restrictions such as parental controls being in place.
         */
    case .denied, .restricted:
        // Denied access to camera
        // Explain that we need camera access and how to change it.
        let dialog = UIAlertController(title: "Unable to access the Camera", message: "To enable access, go to Settings > Privacy > Camera and turn on Camera access for this app.", preferredStyle: UIAlertController.Style.alert)

        let okAction = UIAlertAction(title: "OK", style: UIAlertAction.Style.default, handler: nil)

        dialog.addAction(okAction)
        self.present(dialog, animated:true, completion:nil)
    case .notDetermined:
        // The user has not yet been presented with the option to grant access to the camera hardware.
        // Ask for it.
        AVCaptureDevice.requestAccess(for: AVMediaType.video, completionHandler: { (grantd) in
        // If access was denied, we do not set the setup error message since access was just denied.
           if grantd {
           // Allowed access to camera, go ahead and present the UIImagePickerController.
            self.showImagePickerForSourceType(sourceType: UIImagePickerController.SourceType.camera)
            }
        })
    case .authorized:
        // Allowed access to camera, go ahead and present the UIImagePickerController.
        self.showImagePickerForSourceType(sourceType: UIImagePickerController.SourceType.camera)
    @unknown default:
        break; //handle other status
    }

SWIFT 3

let authStatus = AVCaptureDevice.authorizationStatus(forMediaType: AVMediaTypeVideo)
    
if authStatus == AVAuthorizationStatus.denied {
    // Denied access to camera
    // Explain that we need camera access and how to change it.
    let dialog = UIAlertController(title: "Unable to access the Camera", message: "To enable access, go to Settings > Privacy > Camera and turn on Camera access for this app.", preferredStyle: UIAlertControllerStyle.alert)
        
    let okAction = UIAlertAction(title: "OK", style: UIAlertActionStyle.default, handler: nil)
        
    dialog.addAction(okAction)
    self.present(dialog, animated:true, completion:nil)
        
} else if authStatus == AVAuthorizationStatus.notDetermined {     // The user has not yet been presented with the option to grant access to the camera hardware.
    // Ask for it.
    AVCaptureDevice.requestAccess(forMediaType: AVMediaTypeVideo, completionHandler: { (grantd) in
    // If access was denied, we do not set the setup error message since access was just denied.
       if grantd {
       // Allowed access to camera, go ahead and present the UIImagePickerController.
            self.showImagePickerForSourceType(sourceType: UIImagePickerControllerSourceType.camera)
        }
    })
} else {
        
    // Allowed access to camera, go ahead and present the UIImagePickerController.
    self.showImagePickerForSourceType(sourceType: UIImagePickerControllerSourceType.camera)

}

func showImagePickerForSourceType(sourceType: UIImagePickerControllerSourceType) {
    
    let myPickerController = UIImagePickerController()
    myPickerController.delegate = self;
    myPickerController.sourceType = sourceType  
    self.present(myPickerController, animated: true, completion: nil)
}
Hardness answered 3/5, 2017 at 10:41 Comment(0)
N
-6

As stated elsewhere, checking the AVAuthorizationStatus won't actually tell you if it's restricted, despite the presence of a "restricted" value in the enum. Instead, I have found that checking if source is enabled to be helpful:

BOOL isCameraAvailable = [UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera];

If isCameraAvailable is NO then the user has most likely disabled camera in Restrictions. See Detect existence of camera in iPhone app?

Nicobarese answered 30/7, 2015 at 0:8 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.