본문으로 바로가기

Camera.opne() Error: 해결


참고: https://developer.android.com/training/permissions/requesting.html

(Beginning in Android 6.0 (API level 23), users grant permissions to apps while the app is running, not when they install the app.)


안드로이드 6.0 버전(marshmallow, API level 23)부터 앱이 필요한 권한을 얻는 방법이 달라졌다.

앱을 설치할 때 권한을 설정하는 것이었지만, 6.0 버전부터는 앱이 실행중일 때에 그 때마다 필요한 권한을 사용자에게 요청한다.

때문에, runtime에 권한을 요청하도록 구현해주어야 문제를 해결할 수 있다.

아래처럼 구현한다.





camera 권한을 요청할 것이다.

runtime중 권한 요청이지만 당연히 manifest.xml에도 권한을 명시해주어야 한다.


1. AndroidManifest.xml에 권한을 명시한다.

....

<uses-permission android:name="android.permission.CAMERA"></uses-permission>

<application .....


2. yourCode.java에서 권한 요청을 작성한다.


step1) 기기의 API Level을 확인하고, Level이 23 이상이면 권한을 요청한다.

        final int MY_PERMISSION_REQUEST_CODE = 100;

        int APIVersion = android.os.Build.VERSION.SDK_INT;

        if (APIVersion >= android.os.Build.VERSION_CODES.M) {

            if (checkCAMERAPermission()) {  //이미 권한이 허가되어 있는지 확인한다. (표.1 로 구현)

                mCamera = Camera.open(Camera.CameraInfo.CAMERA_FACING_BACK);  //카메라를 open() 할 수 있다.

            } else {  //카메라 권한을 요청한다.

               ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.CAMERA}, MY_PERMISSION_REQUEST_CODE);

            }

        }


표.1

 private boolean checkCAMERAPermission() {

    int result = ContextCompat.checkSelfPermission(getApplicationContext(), Manifest.permission.CAMERA);

return result == PackageManager.PERMISSION_GRANTED;

 }

// 카메라 권한이 허용되어있는지 여부를 result에 받는다(허용되어있을 경우 반환되는 값: PackageManager.PERMISSION_GRANTED)



step2) ActivityCompat.requestPermissions()의 결과를 처리하는 함수를 Override한다.

@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String permissions[], @NonNull int[] grantResults) {
switch (requestCode) { // 권한 요청을 여러가지 했을 경우를 대비해 switch문으로 묶어 관리한다.
case MT_PERMISSION_REQUEST_CODE: //권한 요청시 전달했던 '권한 요청'에 대한 식별 코드
if (grantResults.length > 0) {
boolean cameraAccepted = (grantResults[0] == PackageManager.PERMISSION_GRANTED;) //권한을 허가받았는지 boolean값으로 저장한다.
if (cameraAccepted) {

                mCamera = Camera.open(Camera.CameraInfo.CAMERA_FACING_BACK);  //카메라를 open() 할 수 있다.

}
else { //권한 승인을 거절당했다. ㅠ
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (shouldShowRequestPermissionRationale(CAMERA)) { //이 함수는 권한 요청을 실행한 적이 있고, 사용자가 이를 거절했을 때 true를 리턴한다.

showMessagePermission("권한 허가를 요청합니다~ 문구", //표.2 로 구현

new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
requestPermissions(new String[]{CAMERA}, MT_PERMISSION_REQUEST_CODE); //1)에서 요청했던 함수와 동일
}
}
});
return;
}
}

}
}

break;
}
}


step3) 권한 승인을 재요청하는 대화상자(Dialog)를 구현한다.

표.2

  private void showMessagePermission(String message, DialogInterface.OnClickListener okListener) {

  new android.support.v7.app.AlertDialog.Builder(this)

            .setMessage(message)

            .setPositiveButton("허용", okListener)

            .setNegativeButton("거부", null)

            .create()

            .show();

  }