Wenn meine App unter iOS 8 zum ersten Mal versucht, auf die Kamera zuzugreifen, wird dem Benutzer ein Dialogfeld mit den Kameraberechtigungen angezeigt, ähnlich wie beim Mikrofon für den Mikrofonzugriff in iOS 7.
In iOS 7 war es möglich, den Mikrofonberechtigungsdialog vorher aufzurufen und zu prüfen, ob die Berechtigung erteilt wurde (siehe beispielsweise diese Frage ). Gibt es eine ähnliche Möglichkeit, den Kameraberechtigungsdialog in iOS 8 aufzurufen? Kann der Dialog für die Zugriffsberechtigung für Mikrofon UND Kamera kombiniert werden?
Antworten:
Hier ist der Ansatz, den wir letztendlich verwendet haben:
if ([AVCaptureDevice respondsToSelector:@selector(requestAccessForMediaType: completionHandler:)]) { [AVCaptureDevice requestAccessForMediaType:AVMediaTypeVideo completionHandler:^(BOOL granted) { // Will get here on both iOS 7 & 8 even though camera permissions weren't required // until iOS 8. So for iOS 7 permission will always be granted. if (granted) { // Permission has been granted. Use dispatch_async for any UI updating // code because this block may be executed in a thread. dispatch_async(dispatch_get_main_queue(), ^{ [self doStuff]; }); } else { // Permission has been denied. } }]; } else { // We are on iOS <= 6. Just do what we need to do. [self doStuff]; }
quelle
Ich habe ein ähnliches Problem: Wenn der Benutzer den Kamerazugriff verweigert, wenn er zum ersten Mal dazu aufgefordert wird, führt das Drücken der Taste zum Aufnehmen eines Schnappschusses zu einem schwarzen Bildschirm im Kameramodus.
Ich möchte jedoch feststellen, dass der Benutzer den Zugriff abgelehnt hat, und ihn auffordern, ihn einzuschalten, aber ich kann keine Funktionen finden, um den aktuellen Zugriff der Benutzerkamera zu überprüfen. Gibt es eine solche Funktion?
BEARBEITEN: Die folgende Überprüfung informiert Sie in IOS 8 über den Kamerazugriff:
#import <AVFoundation/AVFoundation.h> 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){ // Access has been granted ..do something } else { // Access denied ..do something } }]; }
Diese Informationen wurden in der folgenden Frage gefunden ( Woher wissen Sie, dass die Anwendung über Kamerazugriff verfügt oder nicht programmgesteuert in iOS8 ):
quelle
Hier ist meine Swift-Lösung (iOS 8). Ich brauchte die Kamera für das QR-Scannen, also musste ich sie wirklich auffordern.
Dies bietet
Ermutigen Sie den Benutzer, Zulassen zu wählen, wenn vor der Standardeinstellung die Frage zum Zugriff auf die Kamera zulässig ist
Einfache Möglichkeit, auf Einstellungen zuzugreifen, wenn der Benutzer die erste Anforderung abgelehnt hat.
Um es zum Laufen zu bringen, rufen Sie die Kamera in ViewDidAppear / oder ViewDidLoad usw. auf. Ich musste viewDidAppear verwenden, damit meine benutzerdefinierten Einschränkungen für Kameraansichten eingerichtet wurden.
func checkCamera() { let authStatus = AVCaptureDevice.authorizationStatus(forMediaType: AVMediaTypeVideo) switch authStatus { case .authorized: break // Do your stuff here i.e. allowScanning() case .denied: alertToEncourageCameraAccessInitially() case .notDetermined: alertPromptToAllowCameraAccessViaSetting() default: alertToEncourageCameraAccessInitially() } } func alertToEncourageCameraAccessInitially() { let alert = UIAlertController( title: "IMPORTANT", message: "Camera access required for QR Scanning", preferredStyle: UIAlertControllerStyle.alert ) alert.addAction(UIAlertAction(title: "Cancel", style: .default, handler: nil)) alert.addAction(UIAlertAction(title: "Allow Camera", style: .cancel, handler: { (alert) -> Void in UIApplication.shared.openURL(URL(string: UIApplicationOpenSettingsURLString)!) })) present(alert, animated: true, completion: nil) } func alertPromptToAllowCameraAccessViaSetting() { let alert = UIAlertController( title: "IMPORTANT", message: "Please allow camera access for QR Scanning", preferredStyle: UIAlertControllerStyle.alert ) alert.addAction(UIAlertAction(title: "Dismiss", style: .cancel) { alert in if AVCaptureDevice.devices(withMediaType: AVMediaTypeVideo).count > 0 { AVCaptureDevice.requestAccess(forMediaType: AVMediaTypeVideo) { granted in DispatchQueue.main.async() { self.checkCamera() } } } } ) present(alert, animated: true, completion: nil) }
Dank jamix oben für den Tipp zur Verwendung von dispatch_async - macht die Reaktion auf die Anzeige der neu eingestellten Kamerafunktion so viel schneller.
Entschuldigung für eine Mischung aus nachlaufenden Verschlüssen. Ich wollte sie ausprobieren.
quelle
style: .Default
denCancel
Knopf undstyle: .Cancel
den anderen Knopf ein? Ist es nur ein Fehler oder machst du es mit einem Zweck?Keine der Antworten scheint die Berechtigungen für Mikrofone und Kameras zu überprüfen. Unser Code vergleicht das Szenario, in dem Kameraberechtigungen erteilt werden, der Mikrofonzugriff jedoch verweigert wird.
Da wir Swift noch nicht kennen, ist es unwahrscheinlich, dass die knorrig verschachtelten Abschlüsse und
if
Anweisungen optimal sind. Bitte teilen Sie Vorschläge zur Verbesserung des Codes! Aber zumindest funktioniert es bisher beim Testen.AVCaptureDevice.requestAccessForMediaType(AVMediaTypeVideo, completionHandler: { (videoGranted: Bool) -> Void in if (videoGranted) { AVCaptureDevice.requestAccessForMediaType(AVMediaTypeAudio, completionHandler: { (audioGranted: Bool) -> Void in if (audioGranted) { dispatch_async(dispatch_get_main_queue()) { // Both video & audio granted } } else { // Rejected audio } }) } else { // Rejected video } })
quelle
Swift 3.0-Lösung
AVFoundation importieren
Hinweis: Fügen Sie in Ihrer Info.plist den Schlüssel Privacy - Camera Usage Description hinzu
// MARK: Kamerahandhabung
func callCamera(){ let myPickerController = UIImagePickerController() myPickerController.delegate = self; myPickerController.sourceType = UIImagePickerControllerSourceType.camera self.present(myPickerController, animated: true, completion: nil) NSLog("Camera"); } func checkCamera() { let authStatus = AVCaptureDevice.authorizationStatus(forMediaType: AVMediaTypeVideo) switch authStatus { case .authorized: callCamera() // Do your stuff here i.e. callCameraMethod() case .denied: alertToEncourageCameraAccessInitially() case .notDetermined: alertPromptToAllowCameraAccessViaSetting() default: alertToEncourageCameraAccessInitially() } } func alertToEncourageCameraAccessInitially() { let alert = UIAlertController( title: "IMPORTANT", message: "Camera access required for capturing photos!", preferredStyle: UIAlertControllerStyle.alert ) alert.addAction(UIAlertAction(title: "Cancel", style: .default, handler: nil)) alert.addAction(UIAlertAction(title: "Allow Camera", style: .cancel, handler: { (alert) -> Void in UIApplication.shared.openURL(URL(string: UIApplicationOpenSettingsURLString)!) })) present(alert, animated: true, completion: nil) } func alertPromptToAllowCameraAccessViaSetting() { let alert = UIAlertController( title: "IMPORTANT", message: "Camera access required for capturing photos!", preferredStyle: UIAlertControllerStyle.alert ) alert.addAction(UIAlertAction(title: "Dismiss", style: .cancel) { alert in if AVCaptureDevice.devices(withMediaType: AVMediaTypeVideo).count > 0 { AVCaptureDevice.requestAccess(forMediaType: AVMediaTypeVideo) { granted in DispatchQueue.main.async() { self.checkCamera() } } } } ) present(alert, animated: true, completion: nil) }
quelle
Für Swift 3 können Sie dies zu Ihrer
viewWillAppear
Methode Ihres ersten Ansichtscontrollers hinzufügen :Importieren Sie zuerst das
AVFoundation
Frameworkimport AVFoundation
Dann:
override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) let authorizationStatus = AVCaptureDevice.authorizationStatus(forMediaType: AVMediaTypeVideo) switch authorizationStatus { case .notDetermined: AVCaptureDevice.requestAccess(forMediaType: AVMediaTypeVideo) { granted in if granted { print("access granted") } else { print("access denied") } } case .authorized: print("Access authorized") case .denied, .restricted: print("restricted") } }
Vergessen Sie nicht,
Privacy - Camera Usage Description
Ihren Schlüssel hinzuzufügenInfo.plist
quelle
Für mich funktioniert diese Arbeit auf iOS7 und iOS8:
ALAuthorizationStatus status = [ALAssetsLibrary authorizationStatus]; switch (status) { case ALAuthorizationStatusAuthorized: break; case ALAuthorizationStatusRestricted: case ALAuthorizationStatusDenied: break; case ALAuthorizationStatusNotDetermined: break; }
quelle
#import <AssetsLibrary/AssetsLibrary.h>
Ich mache eine Zugriffsprüfung für den App-Delegaten.
import UIKit import AVFoundation import Photos func applicationDidBecomeActive(application: UIApplication) { cameraAllowsAccessToApplicationCheck() internetAvailabilityOnApplicationCheck() photoLibraryAvailabilityCheck() } //MARK:- CAMERA ACCESS CHECK func cameraAllowsAccessToApplicationCheck() { let authorizationStatus = AVCaptureDevice.authorizationStatusForMediaType(AVMediaTypeVideo) switch authorizationStatus { case .NotDetermined: // permission dialog not yet presented, request authorization AVCaptureDevice.requestAccessForMediaType(AVMediaTypeVideo, completionHandler: { (granted:Bool) -> Void in if granted { print("access granted") } else { print("access denied") } }) case .Authorized: print("Access authorized") case .Denied, .Restricted: alertToEncourageCameraAccessWhenApplicationStarts() default: print("DO NOTHING") } } //MARK:- PHOTO LIBRARY ACCESS CHECK func photoLibraryAvailabilityCheck() { if PHPhotoLibrary.authorizationStatus() == PHAuthorizationStatus.Authorized { } else { var cameraUnavailableAlertController = UIAlertController (title: "Photo Library Unavailable", message: "Please check to see if device settings doesn't allow photo library access", preferredStyle: .Alert) var settingsAction = UIAlertAction(title: "Settings", style: .Destructive) { (_) -> Void in let settingsUrl = NSURL(string:UIApplicationOpenSettingsURLString) if let url = settingsUrl { UIApplication.sharedApplication().openURL(url) } } var cancelAction = UIAlertAction(title: "Okay", style: .Default, handler: nil) cameraUnavailableAlertController .addAction(settingsAction) cameraUnavailableAlertController .addAction(cancelAction) self.window?.rootViewController!.presentViewController(cameraUnavailableAlertController , animated: true, completion: nil) } } func internetAvailabilityOnApplicationCheck() { //MARK:- INTERNET AVAILABLITY if InternetReachability.isConnectedToNetwork() { } else { dispatch_async(dispatch_get_main_queue(), { //INTERNET NOT AVAILABLE ALERT var internetUnavailableAlertController = UIAlertController (title: "Network Unavailable", message: "Please check your internet connection settings and turn on Network Connection", preferredStyle: .Alert) var settingsAction = UIAlertAction(title: "Settings", style: .Destructive) { (_) -> Void in let settingsUrl = NSURL(string:UIApplicationOpenSettingsURLString) if let url = settingsUrl { UIApplication.sharedApplication().openURL(url) } } var cancelAction = UIAlertAction(title: "Okay", style: .Default, handler: nil) internetUnavailableAlertController .addAction(settingsAction) internetUnavailableAlertController .addAction(cancelAction) self.window?.rootViewController!.presentViewController(internetUnavailableAlertController , animated: true, completion: nil) }) } }
* *
quelle
Das Problem für mich war , dass
Bundle name
undBundle Display Name
waren nicht in meinem Info.plist aufgrund einiger letzten Build - Konfigurationsänderungen festgelegt zu werden . Ein unwahrscheinlicher Fall ... Aber ich habe ein paar Stunden gebraucht, um das festzunageln. Hoffentlich hilft es jemand anderem.quelle