로메오의 블로그

[Android] Runtime permission 권한 인증 받기 본문

App & OS/Android

[Android] Runtime permission 권한 인증 받기

romeoh 2019. 6. 25. 04:03
반응형

adb로 권한 목록 조회하기

디바이스 목록을 조회합니다.

$ adb devices

 

디바이스를 선택하고 permission 목록을 조회합니다.

$ adb -s emulator-5554 shell pm list permissions -d -g

permission:android.permission.ACCESS_FINE_LOCATION

permission:android.permission.CAMERA

위 두 개의 permission을 획득해 보겠습니다.

 

Android 프로젝트 생성

Empty Activity를 선택하고 Next를 누릅니다.

Name, Save location, Language를 설정하고 Finish를 누릅니다.

 

AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.gaeyou.calllog">

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

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>​

AndroidManifest.xml 에 CAMERA와 ACCESS_FINE_LOCATION 권한을 추가합니다.

 

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <Button
        android:id="@+id/check_permission"
        android:layout_width="match_parent"
        android:layout_centerInParent="true"
        android:layout_height="wrap_content"
        android:text="Permission 확인"/>

    <Button
        android:id="@+id/request_permission"
        android:layout_below="@+id/check_permission"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Permission 요청"/>

</RelativeLayout>

화면에 버튼 두개를 추가합니다.

 

MainActivity.java

package com.gaeyou.calllog;

import android.content.DialogInterface;
import android.content.pm.PackageManager;
import android.os.Build;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.design.widget.Snackbar;
import android.view.View;
import android.widget.Button;

import static android.Manifest.permission.ACCESS_FINE_LOCATION;
import static android.Manifest.permission.CAMERA;

public class MainActivity extends AppCompatActivity implements View.OnClickListener {

    private static final int PERMISSION_REQUEST_CODE = 200;
    private View view;

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

        Button check_permission = (Button) findViewById(R.id.check_permission);
        Button request_permission = (Button) findViewById(R.id.request_permission);
        check_permission.setOnClickListener(this);
        request_permission.setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {
        view = v;
        int id = view.getId();
        switch (id) {
            case R.id.check_permission:
                // permission 확인
                if (checkPermission()) {
                    Snackbar.make(view, "이미 permission 인증 받았습니다.", Snackbar.LENGTH_LONG).show();
                } else {
                    Snackbar.make(view, "permission을 요청하세요.", Snackbar.LENGTH_LONG).show();
                }
                break;

            case R.id.request_permission:
                // permission 요청하기
                if (!checkPermission()) {
                    requestPermission();
                } else {
                    Snackbar.make(view, "이미 permission 인증 받았습니다.", Snackbar.LENGTH_LONG).show();
                }
                break;
        }
    }

    // permission 확인
    private boolean checkPermission() {
        int result = ContextCompat.checkSelfPermission(getApplicationContext(), ACCESS_FINE_LOCATION);
        int result1 = ContextCompat.checkSelfPermission(getApplicationContext(), CAMERA);

        return result == PackageManager.PERMISSION_GRANTED && result1 == PackageManager.PERMISSION_GRANTED;
    }

    // permission 요청
    private void requestPermission() {
        ActivityCompat.requestPermissions(this,
                new String[]{ACCESS_FINE_LOCATION, CAMERA},
                PERMISSION_REQUEST_CODE);
    }

    // permission 요청 결과
    @Override
    public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
        switch (requestCode) {
            case PERMISSION_REQUEST_CODE:
                if (grantResults.length > 0) {
                    boolean locationAccepted = grantResults[0] == PackageManager.PERMISSION_GRANTED;
                    boolean cameraAccepted = grantResults[1] == PackageManager.PERMISSION_GRANTED;

                    if (locationAccepted && cameraAccepted)
                        Snackbar.make(view, "Permission Granted, locaion과 camera에 access 할 수 있습니다..", Snackbar.LENGTH_LONG).show();
                    else {

                        Snackbar.make(view, "Permission Denied, location과 camera에 access 할 수 없습니다.", Snackbar.LENGTH_LONG).show();

                        // 마시멜로 윗버전 일 경우 상세 설명과 함께 permission을 다시 요청한다.
                        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                            if (shouldShowRequestPermissionRationale(ACCESS_FINE_LOCATION)) {
                                showMessageOKCancel("permission을 허용해야 앱을 사용 할 수 있습니다.\n허용하시겠습니까?",
                                        new DialogInterface.OnClickListener() {
                                            @Override
                                            public void onClick(DialogInterface dialog, int which) {
                                                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                                                    requestPermissions(new String[]{ACCESS_FINE_LOCATION, CAMERA},
                                                            PERMISSION_REQUEST_CODE);
                                                }
                                            }
                                        });
                                return;
                            }
                        }
                    }
                }
                break;
        }
    }


    private void showMessageOKCancel(String message, DialogInterface.OnClickListener okListener) {
        new AlertDialog.Builder(MainActivity.this)
                .setMessage(message)
                .setPositiveButton("OK", okListener)
                .setNegativeButton("Cancel", null)
                .create()
                .show();
    }
}

App build

Permission 확인 버튼을 누릅니다.

permisson을 요청하라고 Snackbar가 표시됩니다.

permission 요청 버튼을 누릅니다.

두개의 permission 요청 창이 뜹니다.

Deny를 눌러봅니다.

마시멜로 상위 버전에서는 권한 상세 설명과 함께 다시 권한을 요청할 수 있습니다.

OK를 눌러서 다시 권한을 요청합니다.

 

Allow를 눌러서 권한을 획득합니다.

permission 확인을 눌러서 권한을 확인 할 수 있습니다.

반응형
Comments