스마트기기개발관련/안드로이드 개발

[android] 안드로이드 마쉬멜로우 버전 이상에서 권한처리하기.

AlrepondTech 2017. 11. 13. 18:04
반응형


/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////


출처: http://appsnuri.tistory.com/128


지 거부할지를 지정해야 한다. 즉, 권한 설정을 프로그램적으로 처리해야 사용자가 허용 또는 거부할 수 있기 때문에 프로그램적으로 처리하지 않으면 androidmanifest.xml에 권한 설정을 했다고 해도 구동이 안 되는 현상이 일어난다.

모든 권한에 대해서 프로그램적으로 처리해야 하는 것은 아니고 달력, 카메라, 연락처, 위치정보, 마이크, 전화, 센서, 문자, 저장소 등을 사용할 때는 처리해야 한다.

앱을 실행하고 권한을 필요로 하는 코드가 구동되기 전에 아래와 같은 코드를 이용해서 사용자가 권한을 허용할지 거부할지를 결정할 수 있는 창이 뜨게 처리한다.
<센서 권한을 허용 여부를 묻는 창의 예>




 

sdcard 읽기와 쓰기 권한 설정을 예로 들어 보겠다.

 
private static final int MY_PERMISSIONS_REQUEST_READ_CONTACTS = 1;
private static String[] PERMISSIONS_STORAGE = {
            Manifest.permission.READ_EXTERNAL_STORAGE,
            Manifest.permission.WRITE_EXTERNAL_STORAGE
    };

// 권한을 획득하기전에 현재 Acivity에서 지정된 권한을 사용할 수 있는지 여부 체크
if (ContextCompat.checkSelfPermission(thisActivity,
                Manifest.permission.WRITE_EXTERNAL_STORAGE)
        != PackageManager.PERMISSION_GRANTED) {

    // 권한 획득에 대한 설명 보여주기
    if (ActivityCompat.shouldShowRequestPermissionRationale(thisActivity,
            Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
        // 사용자에게 권한 획득에 대한 설명을 보여준 후 권한 요청을 수행
        
    } else {

        // 권한 획득의 필요성을 설명할 필요가 없을 때는 아래 코드를
        //수행해서 권한 획득 여부를 요청한다.

        ActivityCompat.requestPermissions(thisActivity,
                PERMISSIONS_STORAGE,
                MY_PERMISSIONS_REQUEST_READ_CONTACTS);

    }
}
------------------------------
위의 코드가 실행되서 사용자가 권한 획득을 허용하거나 거부하면 아래 메서드가
호출됨
@Override
public void onRequestPermissionsResult(int requestCode,
        String permissions[], int[] grantResults) {
    switch (requestCode) {
        case MY_PERMISSIONS_REQUEST_READ_CONTACTS: {
            //권한 획득이 거부되면 결과 배열은 비어있게 됨
            if (grantResults.length > 0
                && grantResults[0] == PackageManager.PERMISSION_GRANTED) {

                //권한 획득이 허용되면 수행해야 할 작업이 표시됨
                //일반적으로 작업을 처리할 메서드를 호출

            } else {

                //권한 획득이 거부되면 수행해야 할 적업이 표시됨
                //일반적으로 작업을 처리할 메서드를 호출
            }
            return;
        }
    }
}



출처: http://appsnuri.tistory.com/128 [이야기앱 세상]



/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////


출처: http://kylblog.tistory.com/12


오버레이 설정 관련 PERMISSION은 http://kylblog.tistory.com/8 이전 포스트에서 먼저 설명드려서 참고하시면 됩니다!


PERMISSION 관련되어 한번 정리를 해보도록 하겠습니다.



이 표에 해당하는 Permissions은 꼭 사용자에게 권한 요청을 해야 하는 Permissions 입니다.


Permission Group

Permissions
CALENDAR
CAMERA
CONTACTS
LOCATION
MICROPHONE
PHONE
SENSORS
SMS
STORAGE


출처: http://gun0912.tistory.com/55







외부 저장소를 위한 PERMISSION 요청 설정



위의 두가지 STORAGE PERMISSION을 위한 허가 요청 문입니다.

 private void checkPermission() {

   if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { // 마시멜로우 버전과 같거나 이상이라면
if(checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED
|| checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
if(shouldShowRequestPermissionRationale(Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
Toast.makeText(this, "외부 저장소 사용을 위해 읽기/쓰기 필요", Toast.LENGTH_SHORT).show();
}

requestPermissions(new String[]
{Manifest.permission.WRITE_EXTERNAL_STORAGE,Manifest.permission.READ_EXTERNAL_STORAGE},
2); //마지막 인자는 체크해야될 권한 갯수

} else {
//Toast.makeText(this, "권한 승인되었음", Toast.LENGTH_SHORT).show();
}
}
}


checkPermission() 을 호출 하면 사진/ 미디어/ 파일에 대한 요청문이 나오면서 거부, 허용 을 할 수 있도록 합니다.

허용, 거부에 대한 결과 값을 잡아 주는 메소드는 OnRequestPermissionResult 입니다.

예시로는 저 메소드에 대한 검색을 통해 사용해보시면 됩니다.



위의 권한이 필요한 코드가 실행이 되며 권한 요청이 없다면 코드가 실행되지 않습니다!

일부 앱에서는 처음 실행 할 때 필요한 권한을 모두 요청받는 형태로 구현하기도 하며

권한 체크 하는 라이브러리 까지 만들어 제공해 주고 있다니 찾아보시면 도움이 되리라 생각합니다!


-------------------------------------------------------------------------------------------------
 OnRequestPermissionResult 사용방법 추가 - 20170809

requestPermissions 메서드는
shouldShowRequestPermissionRationale : (한번 거절 후 다시보지 않기 체크 되기 전까지 계속 호출될 수 있는 것)
에서 다시보지않기 체크 후엔 다이얼로그 호출이 되지 않아 다시 되묻는 것이 없어 .. 그 이벤트를 잡아주는 다이얼로그가 필요합니다.
사용자가 권한 허용을 다시보지않기 체크할 만큼 끝까지 안하는 경우에 말이죠..

 @Override

public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResult){
  super.onRequestPermissionsResult(requestCode, permissions, grantResults);
  //위 예시에서 requestPermission 메서드를 썼을시 , 마지막 매개변수에 0을 넣어 줬으므로, 매칭
  if(requestCode == 0){
     // requestPermission의 두번째 매개변수는 배열이므로 아이템이 여러개 있을 수 있기 때문에 결과를 배열로 받는다.
     // 해당 예시는 요청 퍼미션이 한개 이므로 i=0 만 호출한다.
     if(grantResult[0== 0){
        //해당 권한이 승낙된 경우.
     }else{
        //해당 권한이 거절된 경우.

위의 onRequestPermissionsResult 메서드는 마지막에 항상 결과값 리턴을 위해 호출되는 메서드로

이것을 활용하여 권한을 되묻는 것을 자체적으로 추가하시면 됩니다.



출처: http://kylblog.tistory.com/12 [ylblog]


/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////


출처: http://myandroidarchive.tistory.com/2


안드로이드 6.0으로 업그레이드 되면서 권한설정이 방식이 변경되었다.


기존에는 앱에서 요청하는 모든 권한을 허용해야 앱을 사용할 수 있다.


구글은 그러한 권한방식이 좋아하지 않았는지 바꿔버렸다.


------------------------------------------------------------------------------------------------------


public class MainActivity extends AppCompatActivity {
private Activity mainActivity = this;

private static final int REQUEST_MICROPHONE = 3;
private static final int REQUEST_EXTERNAL_STORAGE = 2;
private static final int REQUEST_CAMERA = 1;

private TextView resultText;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

Button cameraBtn = (Button)findViewById(R.id.cameraBtn);
Button storageBtn = (Button)findViewById(R.id.storageBtn);
Button micBtn = (Button)findViewById(R.id.micBtn);

resultText = (TextView)findViewById(R.id.resultText);

cameraBtn.setOnClickListener(buttonClickListener);
storageBtn.setOnClickListener(buttonClickListener);
micBtn.setOnClickListener(buttonClickListener);
}

private View.OnClickListener buttonClickListener = new View.OnClickListener() {
@Override
public void onClick(View v) {
int id = v.getId();
switch (id) {
case R.id.cameraBtn:
int permissionCamera = ContextCompat.checkSelfPermission(getApplicationContext(), Manifest.permission.CAMERA);
if(permissionCamera == PackageManager.PERMISSION_DENIED) {
ActivityCompat.requestPermissions(mainActivity, new String[]{Manifest.permission.CAMERA}, REQUEST_CAMERA);
} else {
resultText.setText("camera permission authorized");
}
break;
case R.id.storageBtn:
int permissionReadStorage = ContextCompat.checkSelfPermission(getApplicationContext(), Manifest.permission.READ_EXTERNAL_STORAGE);
int permissionWriteStorage = ContextCompat.checkSelfPermission(getApplicationContext(), Manifest.permission.WRITE_EXTERNAL_STORAGE);
if(permissionReadStorage == PackageManager.PERMISSION_DENIED || permissionWriteStorage == PackageManager.PERMISSION_DENIED) {
ActivityCompat.requestPermissions(mainActivity, new String[]{Manifest.permission.READ_EXTERNAL_STORAGE,Manifest.permission.WRITE_EXTERNAL_STORAGE}, REQUEST_EXTERNAL_STORAGE);
} else {
resultText.setText("read/write storage permission authorized");
}
break;
case R.id.micBtn:
int permissionAudio = ContextCompat.checkSelfPermission(getApplicationContext(), Manifest.permission.RECORD_AUDIO);
if(permissionAudio == PackageManager.PERMISSION_DENIED) {
ActivityCompat.requestPermissions(mainActivity, new String[]{Manifest.permission.RECORD_AUDIO}, REQUEST_MICROPHONE);
} else {
resultText.setText("recording audio permission authorized");
}
break;
}
}
};

@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
switch (requestCode) {
case REQUEST_CAMERA:
for (int i = 0; i < permissions.length; i++) {
String permission = permissions[i];
int grantResult = grantResults[i];
if (permission.equals(Manifest.permission.CAMERA)) {
if(grantResult == PackageManager.PERMISSION_GRANTED) {
resultText.setText("camera permission authorized");
} else {
resultText.setText("camera permission denied");
}
}
}
break;
case REQUEST_EXTERNAL_STORAGE:
for (int i = 0; i < permissions.length; i++) {
String permission = permissions[i];
int grantResult = grantResults[i];
if (permission.equals(Manifest.permission.READ_EXTERNAL_STORAGE)) {
if(grantResult == PackageManager.PERMISSION_GRANTED) {
resultText.setText("read/write storage permission authorized");
} else {
resultText.setText("read/write storage permission denied");
}
}
}
break;
case REQUEST_MICROPHONE:
for (int i = 0; i < permissions.length; i++) {
String permission = permissions[i];
int grantResult = grantResults[i];
if (permission.equals(Manifest.permission.RECORD_AUDIO)) {
if(grantResult == PackageManager.PERMISSION_GRANTED) {
resultText.setText("recording audio permission authorized");
} else {
resultText.setText("recording audio permission denied");
}
}
}
break;
}
}
}


---------------------------------------------------------------------------------------------------------



카메라의 권한설정 메커니즘만 설명하겠다.


---------------------------------------------------------------------------------------------------------



int permissionCamera = ContextCompat.checkSelfPermission(getApplicationContext(), Manifest.permission.CAMERA);
if(permissionCamera == PackageManager.PERMISSION_DENIED) {
ActivityCompat.requestPermissions(mainActivity, new String[]{Manifest.permission.CAMERA}, REQUEST_CAMERA);
} else {
resultText.setText("camera permission authorized");
}


---------------------------------------------------------------------------------------------------------



permissionCamera를 이용하여 권한을 확인한다.

권한이 있다면 else문으로 빠져나간다. 

반면에 권한이 없다면 권한을 요청한다.



---------------------------------------------------------------------------------------------------------


switch (requestCode) {
case REQUEST_CAMERA:
for (int i = 0; i < permissions.length; i++) {
String permission = permissions[i];
int grantResult = grantResults[i];
if (permission.equals(Manifest.permission.CAMERA)) {
if(grantResult == PackageManager.PERMISSION_GRANTED) {
resultText.setText("camera permission authorized");
} else {
resultText.setText("camera permission denied");
}
}
}
break;


---------------------------------------------------------------------------------------------------------


onRequestPermissionsResult는 사용자의 권한 선택을 한 내용들이 들어있다.


여기서 Camera의 권한이 있다면 camera permission authorized가 출력되고


권한이 없다면 camera permission denied가 출력된다.


예제 코드는


android permisstion : https://github.com/pchan1401-ICIL/AndroidPermission


더 좋은 설명은 아래 블로그를 참고하자


박상권님 블로그 : http://gun0912.tistory.com/55



출처: http://myandroidarchive.tistory.com/2 [개발 아카이브]

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////


/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

반응형