티스토리 뷰


Android 6.0 Marshmallow 에서 checkSelfPermission 사용하기




안드로이드가 6.0 마시멜로로 업데이트 되면서 크게 바뀐게 하나 있습니다.

바로 권한인데요,  기본적인 인터넷 같은 사용권한은 기본권한에 포함되어 따로 사용자에게 동의를 구하지 않아도 됩니다.

하지만 기기를 제어할 수 있는( 파일읽기,카메라,블루투스,GPS제어 등등 ) 에 대한 권한은 동의를 받아야만 사용할 수 있습니다.

또한 사용자는 언제든지 그 권한 사용을 취소할 수 있습니다.


앱개발시 가령 갤러리를 만들어서 사용한다고 할때 기기의 파일을 읽는 권한인 READ_EXTERNAL_STORAGE 가 필요로 합니다.

마시멜로에서는 READ_EXTERNAL_STORAGE 권한에 대한 사용동의를 받지 않을경우 별다른 처리가 없으면 크레쉬가 발생합니다.


그렇다면 어떠한 권한을 사용할때 필요로 할까요?

Table 1. Dangerous permissions and permission groups.

Permission GroupPermissions
CALENDAR
CAMERA
CONTACTS
LOCATION
MICROPHONE
PHONE
SENSORS
SMS
STORAGE








위에 나열된 권한의 경우 사용자동의가 꼭! 필요한 권한입니다. 위에 명시되지 않은 권한의 경우 예전과 같이 매니퍼스트에 정의하면 바로 사용이 가능합니다

그럼 앱에서는 어떤식으로 처리해야 할까요? 예를들어 READ_EXTERNAL_STORAGE 를 사용할경우를 보도록 하겠습니다.

( 구글 공식문서에도 나와있는 내용입니다 [ 바로보기 ] )


1. 먼저 권한을 체크하고 상황에 맞게 동의,실행 절차를 진행합니다.


// 갤러리 사용 권한 체크( 사용권한이 없을경우 -1 )
if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
// 권한이 없을경우

// 최초 권한 요청인지, 혹은 사용자에 의한 재요청인지 확인
if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.READ_EXTERNAL_STORAGE)) {
// 사용자가 임의로 권한을 취소시킨 경우
// 권한 재요청
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, MY_PERMISSIONS_REQUEST_READ_CONTACTS);

} else {
// 최초로 권한을 요청하는 경우(첫실행)
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, MY_PERMISSIONS_REQUEST_READ_CONTACTS);
}
}else {
// 사용 권한이 있음을 확인한 경우
initLayout();
}





2. 만약 권한이 없을경우 권한사용 동의창을 띄우고 "동의","비동의" 에 대한 콜백을 아래와 같이 받습니다.

동의를 받았을경우 콜백에서 다음 작업을 진행주어야 합니다.


@Override
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
switch (requestCode) {
case MY_PERMISSIONS_REQUEST_READ_EXTERNAL_STORAGE: {
// 갤러리 사용권한에 대한 콜백을 받음
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// 권한 동의 버튼 선택
initLayout();
} else {
// 사용자가 권한 동의를 안함
// 권한 동의안함 버튼 선택
Toast.makeText(PhotoPickerActivity.this , "권한사용을 동의해주셔야 이용이 가능합니다." , Toast.LENGTH_LONG ).show();
finish();
}
return;
}
// 예외케이스
}
}



이것으로 권한체크에 대한 처리는 끝났습니다.

참고로 Android 6.0 이하버전에서는 checkSelfPermission 호출은 그냥 무시됩니다. ( return 0 반환 )

바로 else{} 를 타기때문에 분기처리는 따로 필요없습니다









댓글
  • 프로필사진 pro 도움이 많이 되었습니다. 2016.04.08 22:30 신고
  • 프로필사진 비밀댓글입니다 2016.04.29 11:05
  • 프로필사진 BlogIcon 이용범 Lee Yongbeom MY_PERMISSION_REQUEST_READ_EXTERNAL_STORAGE 는 적당한 값으로 선언해주시면됩니다

    private int MY_PERMISSION_REQUEST_READ_EXTERNAL_STORAGE = 1;
    이런식으루요^^
    2016.05.16 10:33 신고
  • 프로필사진 A12243 안녕하세요 블로그를 보고 마시멜로 권한 주기 를 구현해 보려고하는데 계속 오류가 나네요 ㅜㅜ

    혹시 제가 작성한 코드를 보시고 어디서 잘못된 것인지 알려 주실수 있으실까요

    package a12243.naver.com.myapplication;

    import android.content.pm.PackageManager;
    import android.os.Bundle;
    import android.support.v4.app.ActivityCompat;
    import android.support.v4.content.ContextCompat;
    import android.support.v7.app.AppCompatActivity;
    import android.util.Log;
    import android.view.WindowManager;
    import android.widget.Toast;

    public class MainActivity extends AppCompatActivity {

    int MY_PERMISSION_REQUEST_STORAGE = 1;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
    WindowManager.LayoutParams.FLAG_FULLSCREEN);
    setContentView(R.layout.activity_main);

    checkPermission();
    }

    private void checkPermission() {
    if(ContextCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE)
    != PackageManager.PERMISSION_GRANTED){
    if(ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.READ_EXTERNAL_STORAGE)){
    ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, MY_PERMISSION_REQUEST_STORAGE);
    }
    else {
    ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, MY_PERMISSION_REQUEST_STORAGE);
    }
    }
    else{

    }


    }

    @Override
    public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
    switch (requestCode) {
    case 1 :
    if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
    Log.e("","동의선택";);
    } else {
    Toast.makeText(this, "권한사용을동의해주세요",Toast.LENGTH_SHORT).show();
    finish();
    }
    return;
    }
    }
    }
    2016.05.30 11:23 신고
  • 프로필사진 BlogIcon 이용범 Lee Yongbeom 에러메시지를 올려주시는게 더 좋을것 같습니다ㅠㅠ 2016.06.20 23:24 신고
댓글쓰기 폼