본문 바로가기

안드로이드/자바

[안드로이드/Android] 권한 체크하기

반응형

안녕하세요. 오늘은 권한(Permission)에 관한 포스팅입니다. 권한은 앱에서 사용자 기기에 접근하여 사용자의 정보를 얻기 위해 얻는걸 말합니다.

마시멜로 이전 버전에서는 사용자가 인지하지 못한 상태에서 권한을 허용해서 사용자들의 개인정보가 유출되는 사고가 있었는데 그것을 보완하고자 개인정보 유출등의 우려가 있는 권한들을 위험권한으로 분류하고 사용자로부터 동의를 얻도록 변경되었습니다.

 

권한 설정

권한을 AndroidManifest.xml에 명시해야 앱에서 권한을 요청 및 사용할 수 있습니다.

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

 

권한 체크 

권한이 허용되지 않았는데 권한을 사용하면 에러가 발생하기 때문에 사용하기전 권한이 허용 유무를 체크해서 에러가 발생하지 않도록 유도해야 합니다. 

  int permission = ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA)
        if(permission == PackageManager.PERMISSION_DENIED){
            // 권한 없어서 요청
        }else{
            // 권한 있음
            startActivityForResult(new Intent(MediaStore.ACTION_IMAGE_CAPTURE),REQ_IMAGE_CAPTURE)
        }

카메라를 실행시키기 전에 권한을 체크해서 허용한 경우만 실행시키는 코드 입니다.

 

권한 요청

권한을 요청할땐 한개가 아닌 다수의 권한도 요청 가능합니다. 요청한 권한 피드백을 받기위해 request_code를 추가합니다.

int REQ_CAMERA_PERMISSION = 1001;
	...
ActivityCompat.requestPermissions(activity, 
	new String[]{Manifest.permission.CAMERA},REQ_CAMERA_PERMISSION);

권한 요청 결과 

동의 했을 경우와 거부 했을 경우를 앱의 정책에 따라 구현합니다. 

ex ) 동의했을 경우 : 카메라 실행 , 거부 했을 경우 : 토스트로 동의 필요 알림 

@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {

    switch (requestCode){

        case REQUEST_PERMISSION_CODE:

            if(grantResults[0]==PackageManager.PERMISSION_GRANTED){
                //동의 했을 경우
                .....
            }else{
                //거부했을 경우
                Toast toast=Toast.makeText(this,"기능 사용을 위한 권한 동의가 필요합니다.", Toast.LENGTH_SHORT);
                toast.show();
            }

            break;
    }
}

 

권한이 필요한 이유 설명

권한에 대해 거부감을 갖고 있는 유저들에게 권한이 필요한 이유를 설명함으로써 조금 더 원활하게 권한 동의를 얻습니다.

if(ActivityCompat.shouldShowRequestPermissionRationale(this
	,Manifest.permission.CAMERA)){
}

true 일 경우

  • 사용자가 이전 요청에서 거부했을 경우

false 일 경우

  • 사용자가 이전 요청에서 동의했을 경우
  • '다시 묻지 않기' 체크 후 거부했을 경우
  • 사용자 기기에서 해당 권한에 대해 거부했을 경우  

 

다음은 해당 포스팅의 예제 소스 입니다.

더보기
public class WriteMemoActivity extends AppCompatActivity {

	private final int CAMERA_CODE = 1111;
	private final int REQUEST_PERMISSION_CODE = 2222;

	@BindView(R.id.bt_select_photo)
	Button btSelectPhoto;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_wirte_memo);
		ButterKnife.bind(this);
        
	btSelectPhoto.setOnClickListener(onClick);
	}


	private View.OnClickListener onClick = new View.OnClickListener() {
		@Override
		public void onClick(View view) {
			switch (view.getId()) {
				case R.id.bt_select_photo:

					int permissionCheck = ContextCompat.checkSelfPermission(WriteMemoActivity.this,
					Manifest.permission.WRITE_EXTERNAL_STORAGE);

					if (permissionCheck == PackageManager.PERMISSION_GRANTED) {
						selectPhoto();
					} else {
						requestPermission();
						if (ActivityCompat.shouldShowRequestPermissionRationale(WriteMemoActivity.this
							, Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
							//거부했을 경우
							Toast toast=Toast.makeText(WriteMemoActivity.this,
								"기능 사용을 위한 권한 동의가 필요합니다.", Toast.LENGTH_SHORT);
							toast.show();
						}else{
							Toast toast=Toast.makeText(WriteMemoActivity.this,
								"기능 사용을 위한 권한 동의가 필요합니다.", Toast.LENGTH_SHORT);
							toast.show();
						}
					}
					break;
			}
		}
	};

	private void requestPermission() {
		ActivityCompat.requestPermissions(this,
		new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
        	REQUEST_PERMISSION_CODE);
	}

	private void selectPhoto() {
		Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
		startActivityForResult(intent, CAMERA_CODE);
	}


	@Override
	public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
		switch (requestCode){
			case REQUEST_PERMISSION_CODE:
			if(grantResults[0]==PackageManager.PERMISSION_GRANTED){
				//동의 했을 경우
				selectPhoto();
			}else{
				//거부했을 경우
				Toast toast=Toast.makeText(this,"기능 사용을 위한 권한 동의가 필요합니다.", Toast.LENGTH_SHORT);
				toast.show();
			}
			break;
		}
	}
}

 

 

위험 권한 목록 

 

CALENDAR

    • READ_CALENDAR 유저의 달력 데이터 읽기
    • WRITE_CALENDAR 유저의 달력 데이터 쓰기 

 

CAMREA

    • CAMERA 사진 촬영

 

CONTATTS

    • READ_CONTACTS 유저의 연락처 읽기

 

MICROPHONE

    • RECORD_AUDIO 마이크 소리 수신

 

PHONE

    • READ_PHONE_STATE 통화 상태 읽기
    • CALL_PHONE 통화걸기
    • READ_CALL_LOG 유저의 통화 기록 읽기
    • WRITE_CALL_LOG 유저의 통화기록 쓰기 
    • ADD_VOICEMAIL 음성 이메일 추가 
    • USE_SIP SIP 서비스 사용 
    • PROCESS_OUTGOING_CALLS 전화 발신 체크 

 

SENSORS

    • BODY_SENSORS 심장박동수와 같은 바디 센서로부터 측정된 데이터 접근 

 

SMS

    • SEND_SMS 문자 보내기 
    • RECEIVE_SMS 문자 받기 
    • READ_SMS 문자 읽기 
    • RECEIVE_WAP_PUSH WAP 푸시 
    • RECEIVE_MMS MMS 수

STORAGE

    • READ_EXTERNAL_STORAGE 외부저장소 파일 읽기
    • WRITE_EXTERNAL_STORAGE 외부저장소 파일 쓰기
 

 

 

이상으로 포스팅을 마치겠습니다. 

 

개발자 사이트를 참고해주세요

 

 

해당 포스팅은 지극히 주관적인 내용으로 저자의 복기 목적으로 작성된 것이고, 내용에대해 수정이나 추가 요청은 언제든 환영합니다. 

 

 

반응형