简体   繁体   中英

iOS 7 UIImagePickerController Camera No Image

For some reason the first time I open the UIImagePickerController in camera mode on my app it comes up blank. I have to close and reopen that view to get the camera feed to start working. I'm using the standard code that works in iOS 6 perfectly for camera capture. From the sample below I'm firing the capturePhoto: method. Anyone else running into this jenkiness with the iOS 7 camera? I checked the Apple dev forums but its near impossible to find answers there.

- (IBAction)capturePhoto:(id)sender {
    [self doImagePickerForType:UIImagePickerControllerSourceTypeCamera];
}

- (void)doImagePickerForType:(UIImagePickerControllerSourceType)type {
    if (!_imagePicker) {
        _imagePicker = [[UIImagePickerController alloc] init];
        _imagePicker.mediaTypes = @[(NSString*)kUTTypeImage];
        _imagePicker.delegate = self;
    }
    _imagePicker.sourceType = type;
    [self presentViewController:_imagePicker animated:YES completion:nil];
}

为什么这么空?

I'm also using UIImagePickerController and ran into the same issue with a blank screen. I'd like to expand a little on what klaudz mentioned regarding iOS 7 authorization for the camera.

Reference: https://developer.apple.com/library/ios/documentation/AVFoundation/Reference/AVCaptureDevice_Class/Reference/Reference.html

"Recording audio always requires explicit permission from the user; recording video also requires user permission on devices sold in certain regions."

Here is some code fragments you can start with to check to see if you have permission for the camera and request it if your app hadn't previously requested it. If you are denied due to an earlier request, your app may need to put up a notice to the user to go into settings to manually enable access as klaudz pointed out.

iOS 7 example

NSString *mediaType = AVMediaTypeVideo; // Or AVMediaTypeAudio

AVAuthorizationStatus authStatus = [AVCaptureDevice authorizationStatusForMediaType:mediaType];

// This status is normally not visible—the AVCaptureDevice class methods for discovering devices do not return devices the user is restricted from accessing.
if(authStatus == AVAuthorizationStatusRestricted){
    NSLog(@"Restricted");
}

// The user has explicitly denied permission for media capture.
else if(authStatus == AVAuthorizationStatusDenied){
    NSLog(@"Denied");
}

// The user has explicitly granted permission for media capture, or explicit user permission is not necessary for the media type in question.
else if(authStatus == AVAuthorizationStatusAuthorized){
    NSLog(@"Authorized");
}

// Explicit user permission is required for media capture, but the user has not yet granted or denied such permission.
else if(authStatus == AVAuthorizationStatusNotDetermined){

    [AVCaptureDevice requestAccessForMediaType:mediaType completionHandler:^(BOOL granted) {

        // Make sure we execute our code on the main thread so we can update the UI immediately.
        //
        // See documentation for ABAddressBookRequestAccessWithCompletion where it says
        // "The completion handler is called on an arbitrary queue."
        //
        // Though there is no similar mention for requestAccessForMediaType, it appears it does
        // the same thing.
        //
        dispatch_async(dispatch_get_main_queue(), ^{

            if(granted){
                // UI updates as needed
                NSLog(@"Granted access to %@", mediaType);
            }
            else {
                // UI updates as needed
                NSLog(@"Not granted access to %@", mediaType);
            }
        });

    }];

}

else {
    NSLog(@"Unknown authorization status");
}

In iOS 7, an app could access the camera before getting authorize of the user. When an app accesses the camera the first time, iOS show an alert view to ask user. Users could also set the authorize in Settings--Privacy--Camera--[Your app's name] .

The camera will stay in a black blank view if the switch is off.

  1. If you call the camera by using AVCaptureDeviceInput , you can check like:

     NSError *inputError = nil; AVCaptureDeviceInput *captureInput = [AVCaptureDeviceInput deviceInputWithDevice:inputDevice error:&inputError]; if (inputError && inputError.code == AVErrorApplicationIsNotAuthorizedToUseDevice) { // not authorized } 
  2. If you call by using UIImagePickerController , I am still looking for a way to check whether got the authorize.

    I tried these two methods:

     [UIImagePickerController isSourceTypeAvailable:] [UIImagePickerController isCameraDeviceAvailable:] 

    but they did't work that they all returned YES.

UPDATE

Thanks for Scott's expanding. [AVCaptureDevice authorizationStatusForMediaType:] is a better way to check.

AVAuthorizationStatus authStatus = [AVCaptureDevice authorizationStatusForMediaType:AVMediaTypeVideo];
if (authStatus == AVAuthorizationStatusAuthorized) {
    // successful
} else {
    // failed, such as
    // AVAuthorizationStatusNotDetermined
    // AVAuthorizationStatusRestricted
    // AVAuthorizationStatusNotDetermined
}

But remember to check the iOS version, because [AVCaptureDevice authorizationStatusForMediaType:] and AVAuthorizationStatus are available above iOS 7.

if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7.0) {
    // code for AVCaptureDevice auth checking
}

I experienced the exact same problem, and tried every solution on the Internet with no luck. But finally I found out it was the background thread prevented the camera preview to show up. If you happen to have background thread running while trying to open the camera as I do, try to block the background thread and see what happens. Hope you can get around it.

I came across this control AQPhotoPicker . It's quite easy to use, and hopefully it will help you

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM