Làm thế nào để kiểm tra xem người dùng đã cho phép sử dụng máy ảnh hay chưa?


81

Đang cố gắng viết cái này:

if usergavepermissiontousercamera  
  opencamera
else 
  showmycustompermissionview

Không thể tìm thấy cách hiện tại để thực hiện tác vụ đơn giản này.
Lưu ý: Cũng nên hoạt động iOS7 ngay cả khi nó yêu cầu một phương pháp khác


Bạn nên kiểm tra liên kết này. stackoverflow.com/questions/25803217/… Không khó để dịch sang Swift.
Mehdi.Sqalli

AVCaptureDevice và AVAuthorizationStatus đều không được xcode nhận dạng có thể là một lỗi hoặc một cái gì đó nhưng vâng, điều này làm cho nó khá khó khăn.
Esqarrouth

đã kiểm tra câu trả lời đó. của nó đối với các cuộn máy ảnh, không phải là máy ảnh nó tự
Esqarrouth

Câu trả lời:


176

Bạn có thể sử dụng mã sau để thực hiện tương tự:

if AVCaptureDevice.authorizationStatusForMediaType(AVMediaTypeVideo) ==  AVAuthorizationStatus.Authorized {
    // Already Authorized
} else {
    AVCaptureDevice.requestAccessForMediaType(AVMediaTypeVideo, completionHandler: { (granted: Bool) -> Void in
       if granted == true {
           // User granted
       } else {
           // User rejected
       }
   })
}

GHI CHÚ:

  1. Đảm bảo rằng bạn thêm AVFoundationKhung trong phần Liên kết Nhị phân của các giai đoạn xây dựng
  2. Bạn nên viết import AVFoundationtrên lớp của mình để nhậpAVFoundation

SWIFT 3

if AVCaptureDevice.authorizationStatus(forMediaType: AVMediaTypeVideo) ==  AVAuthorizationStatus.authorized {
   // Already Authorized
} else {
   AVCaptureDevice.requestAccess(forMediaType: AVMediaTypeVideo, completionHandler: { (granted: Bool) -> Void in
      if granted == true {
         // User granted
      } else {
         // User Rejected
      }
   })
}

Swift 4

if AVCaptureDevice.authorizationStatus(for: .video) ==  .authorized {
    //already authorized
} else {
    AVCaptureDevice.requestAccess(for: .video, completionHandler: { (granted: Bool) in
        if granted {
            //access allowed
        } else {
            //access denied
        }
    })
}

cảm ơn. nhập đã hoạt động mà không cần thêm vào liên kết nhị phân. nhưng tôi có Foundation trong các khuôn khổ. có liên quan không?
Esqarrouth

1
@Esq: Bạn không cần phải liên kết nhị phân vì theo Swift Imports Bất kỳ khung Objective-C nào (hoặc thư viện C) có thể truy cập được dưới dạng mô-đun có thể được nhập trực tiếp vào Swift. Điều này bao gồm tất cả các khung hệ thống Objective-C — chẳng hạn như Foundation, UIKit và SpriteKit — cũng như các thư viện C chung được cung cấp cùng với hệ thống. Merry X'mas ...
Midhun MP

cảm ơn, chúc mừng xmas cho bạn quá :) btw trong ios7 phương thức này nhập đã được ủy quyền mặc dù nó không bao giờ có yêu cầu. tại sao vậy và tôi có thể sửa nó như thế nào?
Esqarrouth

@Esq: Nếu ứng dụng của bạn đã có quyền và được đặt trong ứng dụng cài đặt, thì ứng dụng sẽ không hỏi lại. Kiểm tra ứng dụng cài đặt của bạn xem bạn có quyền hay không.
Midhun MP

tôi đặt lại cài đặt giả lập trước khi thử điều này. đã đi và kiểm tra cài đặt không có gì về ứng dụng trong đó. thử nó trên ios7.1 simulator
Esqarrouth

18

Giải pháp cập nhật Swift 3.0

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: alertPromptToAllowCameraAccessViaSetting()
    case .notDetermined: alertToEncourageCameraAccessInitially()
    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)
}

Tôi nghĩ rằng bạn đã trộn lẫn tên của các phương thức alertToEncourageCameraAccessInitially và alertPromptToAllowCameraAccessViaSetting;)
jonaszmclaren

Bạn có thể cải thiện câu trả lời. Nó sẽ tốt hơn. Nếu không khi nào rảnh tôi sẽ kiểm tra. Cảm ơn :) @jonaszmclaren
Sourabh Sharma

13

Sau đây là một câu trả lời đã được làm sạch được cập nhật cho Swift 4.x:

Bắt đầu với iOS 10, bạn cũng phải yêu cầu quyền trong tệp info.plist để tránh sự cố:

nhập mô tả hình ảnh ở đây

Quyền riêng tư - Mô tả Sử dụng Máy ảnh

Bạn phải cung cấp một chuỗi được hiển thị cho người dùng với khóa này. Nếu không làm như vậy sẽ dẫn đến sự cố khi cố truy cập vào máy ảnh.

import AVFoundation

func checkCameraAccess() {
    switch AVCaptureDevice.authorizationStatus(for: .video) {
    case .denied:
        print("Denied, request permission from settings")
        presentCameraSettings()
    case .restricted:
        print("Restricted, device owner must approve")
    case .authorized:
        print("Authorized, proceed")
    case .notDetermined:
        AVCaptureDevice.requestAccess(for: .video) { success in
            if success {
                print("Permission granted, proceed")
            } else {
                print("Permission denied")
            }
        }
    }
}

func presentCameraSettings() {
    let alertController = UIAlertController(title: "Error",
                                  message: "Camera access is denied",
                                  preferredStyle: .alert)
    alertController.addAction(UIAlertAction(title: "Cancel", style: .default))
    alertController.addAction(UIAlertAction(title: "Settings", style: .cancel) { _ in
        if let url = URL(string: UIApplicationOpenSettingsURLString) {
            UIApplication.shared.open(url, options: [:], completionHandler: { _ in
                // Handle
            })
        }
    })

    present(alertController, animated: true)
}

Điều này sẽ kiểm tra bốn câu trả lời có thể có, sau đó yêu cầu quyền nếu có notDeterminedhoặc hướng người dùng đến cài đặt để bật nếu có denied. Nếu đúng như vậy restricted, người dùng hiện tại có thể không kích hoạt được, nhưng bạn nên cung cấp một số hình thức hướng dẫn cho họ.


9

Thao tác này sẽ mở máy ảnh khi người dùng cho phép. Nếu không, hãy hiển thị cảnh báo khi yêu cầu quyền.

func openCamera(){
        
        let authStatus = AVCaptureDevice.authorizationStatus(for: AVMediaType.video)
        
        switch (authStatus){
            
        case .notDetermined, .restricted, .denied:
            showAlert(title: "Unable to access the Camera", message: "To enable access, go to Settings > Privacy > Camera and turn on Camera access for this app.")
        case .authorized:
            alert.dismiss(animated: true, completion: nil)
            if(UIImagePickerController .isSourceTypeAvailable(.camera)){
                picker.sourceType = .camera
                picker.showsCameraControls=true
                picker.allowsEditing=true
                self.viewController!.present(picker, animated: true, completion: nil)
            }
        }
}

sau khi gọi chức năng này để hiển thị cảnh báo

func showAlert(title:String, message:String) {
        let alert = UIAlertController(title: title,
                                      message: message,
                                      preferredStyle: UIAlertController.Style.alert)
        
        let okAction = UIAlertAction(title: "OK", style: .cancel, handler: nil)
        alert.addAction(okAction)
        
        let settingsAction = UIAlertAction(title: "Settings", style: .default, handler: { _ in
            // Take the user to Settings app to possibly change permission.
            guard let settingsUrl = URL(string: UIApplication.openSettingsURLString) else { return }
            if UIApplication.shared.canOpenURL(settingsUrl) {
                if #available(iOS 10.0, *) {
                    UIApplication.shared.open(settingsUrl, completionHandler: { (success) in
                        // Finished opening URL
                    })
                } else {
                    // Fallback on earlier versions
                    UIApplication.shared.openURL(settingsUrl)
                }
            }
        })
        alert.addAction(settingsAction)
        
        self.viewController!.present(alert, animated: true, completion: nil)
    }

+1, vì nó hoạt động với tôi sau một thay đổi nhỏ. Tất cả đều tốt ngoại trừ trường hợp lần đầu tiên .notDetined sẽ đúng, vì vậy chúng tôi có thể tiếp tục thực hiện tất cả những gì chúng tôi đã làm trong trường hợp .authorised, bởi vì nó sẽ yêu cầu cho phép / từ chối hoặc chúng tôi có thể giới thiệu người dùng với "AVCaptureDevice.requestAccess (cho : .video)". Từ lần thử tiếp theo, trường hợp chuyển đổi sẽ theo sau dựa trên phản hồi lần đầu tiên. Ngoài ra, cho đến lần đầu tiên chúng tôi từ chối / cho phép, chúng tôi sẽ không thấy điều này trong cài đặt quyền riêng tư.
Lokesh Purohit

2

Tôi đã sửa đổi câu trả lời ở trên và xóa lời nhắc ban đầu, vì khi chúng tôi muốn sử dụng máy ảnh của thiết bị, hệ thống sẽ tự nhắc cấp quyền:

func checkPermissions() {
    let authStatus = AVCaptureDevice.authorizationStatus(forMediaType: AVMediaTypeVideo)

    switch authStatus {
    case .authorized:
        setupCamera()
    case .denied:
        alertPromptToAllowCameraAccessViaSetting()
    default:
        // Not determined fill fall here - after first use, when is't neither authorized, nor denied
        // we try to use camera, because system will ask itself for camera permissions
        setupCamera()
    }
}

func alertPromptToAllowCameraAccessViaSetting() {
    let alert = UIAlertController(title: "Error", message: "Camera access required to...", preferredStyle: UIAlertControllerStyle.alert)

    alert.addAction(UIAlertAction(title: "Cancel", style: .default))
    alert.addAction(UIAlertAction(title: "Settings", style: .cancel) { (alert) -> Void in
        UIApplication.shared.openURL(URL(string: UIApplicationOpenSettingsURLString)!)
    })

    present(alert, animated: true)
}

2

Bạn có thể nhập khung công tác AVFoundation và sử dụng phương thức AuthorisedStatus (for :) được hiển thị bên dưới và xử lý các trường hợp tương ứng.

switch AVCaptureDevice.authorizationStatus(for: .video) {
    case .authorized: // The user has previously granted access to the camera.
        self.setupCaptureSession()

    case .notDetermined: // The user has not yet been asked for camera access.
        AVCaptureDevice.requestAccess(for: .video) { granted in
            if granted {
                self.setupCaptureSession()
            }
        }

    case .denied: // The user has previously denied access.
        return
    case .restricted: // The user can't grant access due to restrictions.
        return
}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.