Things take time

[Android] 위험 권한, 권한 전용 팝업 만들기 본문

Android(기능)

[Android] 위험 권한, 권한 전용 팝업 만들기

겸손할 겸 2017. 8. 28. 14:15

[권한]


https://developer.android.com/guide/topics/security/permissions.html?hl=ko#normal-dangerous


안드로이드 앱 개발시 TargetSDK가 마시멜로 버전(APK 23)이상인 경우, 디바이스의 특정 기능을 사용할 때 권한을 요구하는데 그 권한 중에 위험 권한으로 분류된 권한은 개발자가 직접 사용자에게 권한 허용을 물을 수 있도록 작성해야한다. 즉, 코드로 작성해야한다는 것이다.


페이지에서 확인한 위험 권한 리스트들을 매니페스트에 작성하게 된다면, 매니페스트 작성 + 코드로 작성 까지 두 번을 작업해야한다는 의미이다.

기본적으로 누가 버전을 탑재하고 나오는 요즘에 이 권한 작성 프로그래밍은 기본이다.


다른 사람은 모르겠지만, 나의 경우 권한 요청 소스가 짧지가 않기 때문에 따로 클래스를 두고, context 객체를 생성자로 넘겨준다. 그래야 권한 요청 응답에 따른 result를 요청한 액티비티 클래스에서 받을 수 있다. 예제에서는 이 방법없이 간단하게 하나의 클래스에서 작성한다.


[예제]


만약 디바이스의 외장메모리에 접근해야하는 기능을 사용한다면 매니페스트에는 아래와 같은 문구가 적히게 된다.

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

여기까지가 마시멜로 이전까지 사용하는 방법이었지만, 이제는 사용자에게도 권한에 대한 여부를 묻는 코드를 작성해야한다.

public class MainActivity extends AppCompatActivity {

    private static final int MY_PERMISSION_STORAGE = 1111;

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

        checkPermission();
    }

    private void checkPermission(){
        if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
            // 다시 보지 않기 버튼을 만드려면 이 부분에 바로 요청을 하도록 하면 됨 (아래 else{..} 부분 제거)
            // ActivityCompat.requestPermissions((Activity)mContext, new String[]{Manifest.permission.CAMERA, Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE}, MY_PERMISSION_CAMERA);

            // 처음 호출시엔 if()안의 부분은 false로 리턴 됨 -> else{..}의 요청으로 넘어감
            if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
                new AlertDialog.Builder(this)
                        .setTitle("알림")
                        .setMessage("저장소 권한이 거부되었습니다. 사용을 원하시면 설정에서 해당 권한을 직접 허용하셔야 합니다.")
                        .setNeutralButton("설정", new DialogInterface.OnClickListener() {
                            @Override
                            public void onClick(DialogInterface dialogInterface, int i) {
                                Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
                                intent.setData(Uri.parse("package:" + getPackageName()));
                                startActivity(intent);
                            }
                        })
                        .setPositiveButton("확인", new DialogInterface.OnClickListener() {
                            @Override
                            public void onClick(DialogInterface dialogInterface, int i) {
                                finish();
                            }
                        })
                        .setCancelable(false)
                        .create()
                        .show();
            } else {
                ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.READ_EXTERNAL_STORAGE}, MY_PERMISSION_STORAGE);
            }
        }
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        switch (requestCode) {
            case MY_PERMISSION_STORAGE:
                for (int i = 0; i < grantResults.length; i++) {
                    // grantResults[] : 허용된 권한은 0, 거부한 권한은 -1
                    if (grantResults[i] < 0) {
                        Toast.makeText(MainActivity.this, "해당 권한을 활성화 하셔야 합니다.", Toast.LENGTH_SHORT).show();
                        return;
                    }
                }
                // 허용했다면 이 부분에서..

                break;
        }
    }

주석 부분 참고 



앱이 실행되고 처음에 권한 요청된 모습



거부를 누른 경우



앱을 완전히 종료하고 다시 실행시켰을 때