티스토리 뷰

Android

[Android] 권한 획득

best 2016. 7. 25. 14:36

안드로이드 권한 획득



권한 획득하기


- 마시멜로우(Marshmallow) 이전 버전


AndroidMenifest.xml에 <use-permission>으로 권한을 얻을 수 있다.

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

- 마시멜로우(Marshmallow) 버전


AndroidMenifest.xml에 <use-permission>으로 권한을 얻고,


실시간으로 권한을 허가하는 작업이 추가로 필요하다.




마시멜로우 버전인지 아닌지에 따라 필요한 코드가 달라지므로 버전이 마시멜로우 인지 확인해야 한다.


마시멜로우가 맞다면, 권한에 대해서 허가, 거부 한적이 있는지 확인한다.




MainActivity


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
package com.ktds.jmj.callapp;
 
import android.Manifest;
import android.app.Activity;
import android.support.v7.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v4.app.ActivityCompat;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;
 
public class MainActivity extends AppCompatActivity {
 
    private Button button;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
 
        button = (Button) findViewById(R.id.button);
 
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
 
                /**
                 * 사용자의 OS Version이 마시멜로우 이상인지 체크한다.
                 */
                if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M){ // 현재 버전 == 마시멜로우(M) 버전보다 높은지 확인
                    /**
                     * 사용자 단말기의 권한 중 "전화걸기" 권한이 허용되어 있는지 체크한다.
                     */
                    int permissionResult = checkSelfPermission(Manifest.permission.CALL_PHONE);
                    // Manifest 와 Permission 은 Android 로 Import 한다.
 
                    // CALL_PHONE 의 권한이 없을때
                    if ( permissionResult == PackageManager.PERMISSION_DENIED ){ // 현재 App 에서 권한에 대해서 DENIED 되어 있는지 알아보기
                        /**
                         * 사용자가 CALL_PHONE 권한을 한번이라도 "거부" 한 적이 있는지 조사한다.
                         * 거부한 적이 한번이라도 있다면, true 를 리턴한다.
                         * 거부한 이력이 없다면, False 를 리턴한다.
                         */
                        if( shouldShowRequestPermissionRationale(Manifest.permission.CALL_PHONE) ){
                            AlertDialog.Builder dialog = new AlertDialog.Builder(MainActivity.this);
                            dialog.setTitle("권한이 필요합니다.")
                                    .setMessage("이 기능을 사용하기 위해서는 단말기의 \"전화걸기\" 권한이 필요합니다. 계속하시겠습니까?")
                                    .setPositiveButton("네"new DialogInterface.OnClickListener() {
                                        @Override
                                        public void onClick(DialogInterface dialog, int which) {
                                            if( Build.VERSION.SDK_INT >= Build.VERSION_CODES.M ) {
                                                requestPermissions(new String[]{Manifest.permission.CALL_PHONE}, 1000);
                                            }
                                        }
                                    })
                                    .setNegativeButton("아니요"new DialogInterface.OnClickListener() {
                                        @Override
                                        public void onClick(DialogInterface dialog, int which) {
                                            Toast.makeText(MainActivity.this,"기능을 취소했습니다.", Toast.LENGTH_SHORT).show();
 
                                        }
                                    }).create().show();
                        }
                        // 최초로 권한을 요청 할 때
                        else{
                            // CALL_PHONE 권한을 Android OS 에 요청한다.
                            requestPermissions(new String[]{Manifest.permission.CALL_PHONE}, 1000);
                        }
                    }
                    // CALL_PHONE 의 권한이 있을때
                   else{
                        Intent intent = new Intent(Intent.ACTION_CALL, Uri.parse("tel:010-1111-2222"));
                        startActivity(intent);
                    }
                }
                else { // 사용자의 OS Version이 마시멜로우 이하일때
                    Intent intent = new Intent(Intent.ACTION_CALL, Uri.parse("tel:010-1111-2222"));
                    startActivity(intent);
                }
            }
        });
    }
 
    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
 
        if ( requestCode == 1000 ) {
            // 요청한 권한을 사용자가 "허용" 했다면...
            if( grantResults.length > 0 && grantResults[0]  == PackageManager.PERMISSION_GRANTED){
                Intent intent = new Intent(Intent.ACTION_CALL, Uri.parse("tel:010-6479-3612"));
                if (ActivityCompat.checkSelfPermission(this, Manifest.permission.CALL_PHONE) != PackageManager.PERMISSION_GRANTED) {
                    startActivity(intent);
                }
            }
            else{
                Toast.makeText(MainActivity.this"권한요청을 거부했습니다." , Toast.LENGTH_SHORT).show();
            }
        }
    }
}
 
cs



클래스 따로 생성해보기


권한 요청에 대한 클래스를 따로 생성하여 PermissionRequester.java를 만든다.



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
package com.ktds.jmj.callapp;
 
import android.app.Activity;
import android.content.DialogInterface;
import android.content.pm.PackageManager;
import android.os.Build;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AlertDialog;
/**
 * Created by 206-020 on 2016-06-13.
 */
public class PermissionRequester {
 
        /**
         * 요청 AndroidOS의 버젼이 마쉬멜로우 이상 버젼이 아닐 경우
         */
        public static final int NOT_SUPPORT_VERSION = 2;
 
        /**
         * 요청 권한을 이미 가지고 있을 경우
         */
        public static final int ALREADY_GRANTED = -1;
 
        /**
         * 권한을 System에게 요청한 경우
         * Activity의 onRequestPermissionsResult() 로 결과 리턴됨.
         */
        public static final int REQUEST_PERMISSION = 0;
 
        private Activity context;
        private Builder builder;
 
        private void setBuilder(Builder builder) {
            this.builder = builder;
        }
 
        private PermissionRequester(Activity context) {
            this.context = context;
        }
 
        public int request(final String permission, final int requestCode, final OnClickDenyButtonListener denyAction) {
 
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            /*
             * 해당 App이 특정 권한을 가지고 있는지 검사함.
             * 리턴결과는 PackageManager.PERMISSION_DENIED 와 PackageManager.PERMISSION_GRANTED로 나눠짐.
             * PackageManager.PERMISSION_DENIED : 권한이 없음
               * PackageManager.PERMISSION_GRANTED : 권한이 있음.
             */
                int permissionCheck = ContextCompat.checkSelfPermission(context, permission);
 
            /*
             * 해당 권한이 없을 경우 처리 방법
              */
                if (permissionCheck == PackageManager.PERMISSION_DENIED) {
 
                /*
                 * 권한을 취득할 때 사용자로부터 확인을 받아야 하는지 확인
                    * 여기서 True가 나올 경우는 해당 앱에서 한번이라도 권한을 Deny한 경우일 때 말고는 없음.
                 * 권한에 대해서 허가하지 않은 경우 다시 한번 권한의 취득을 위해 사용자에게 이유를 고지해야 함.
                 * Mashmellow 버젼 이상부터 사용가능함.
                 */
                    if (context.shouldShowRequestPermissionRationale(permission)) {
 
                    /*
                     * 권한 취득해야 하는 이유를 Dialog 등을 통해서 알린다.
                     */
                        AlertDialog.Builder dialog = new AlertDialog.Builder(context);
                        dialog.setTitle(builder.getTitle())
                                .setMessage(builder.getMessage())
                                .setPositiveButton(builder.getPositiveButtonName(), new DialogInterface.OnClickListener() {
                                    @Override
                                    public void onClick(DialogInterface dialog, int which) {
                                    /*
                                     * 권한의 취득을 요청한다.
                                     * 취득하고자 하는 권한을 배열에 넣고 요청한다.
                                     * 뒤에 들어가는 파라미터(requestCode)는 onRequestPermissionsResult() 에서 권한 취득 결과에서 사용된다.
                                     * startActiviryForResult의 Request Code와 유사함.
                                     */
                                        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                                            context.requestPermissions(new String[]{permission}, requestCode);
                                        }
                                    }
                                })
                                .setNegativeButton(builder.getNegativeButtonName(), new DialogInterface.OnClickListener() {
                                    @Override
                                    public void onClick(DialogInterface dialog, int which) {
                                        denyAction.onClick(context);
                                    }
                                }).create().show();
 
                        return REQUEST_PERMISSION;
                    } else {
                    /*
                     * 권한의 취득 요청을 처음 할 때
                        * 권한의 취득을 요청한다.
                     * 취득하고자 하는 권한을 배열에 넣고 요청한다.
                     * 뒤에 들어가는 파라미터(1000)는 onRequestPermissionsResult() 에서 권한 취득 결과에서 사용된다.
                     * startActiviryForResult의 Request Code와 유사함.
                     */
                        context.requestPermissions(new String[]{permission}, requestCode);
                        return REQUEST_PERMISSION;
                    }
 
                } else {
                /*
                 * 이미 권한을 가지고 있을 경우
                    * 해야할 일을 수행한다.
                 */
                    return ALREADY_GRANTED;
                }
 
            }
 
            return NOT_SUPPORT_VERSION;
        }
 
        public static class Builder {
 
            private PermissionRequester requester;
 
            public Builder(Activity context) {
                requester = new PermissionRequester(context);
            }
 
            private String title = "권한 요청";
            private String message = "기능의 사용을 위해 권한이 필요합니다.";
            private String positiveButtonName = "네";
            private String negativeButtonName = "아니요";
 
            public String getTitle() {
                return title;
            }
 
            public Builder setTitle(String title) {
                this.title = title;
                return this;
            }
 
            public String getMessage() {
                return message;
            }
 
            public Builder setMessage(String message) {
                this.message = message;
                return this;
            }
 
            public String getPositiveButtonName() {
                return positiveButtonName;
            }
 
            public Builder setPositiveButtonName(String positiveButtonName) {
                this.positiveButtonName = positiveButtonName;
                return this;
            }
 
            public String getNegativeButtonName() {
                return negativeButtonName;
            }
 
            public Builder setNegativeButtonName(String negativeButtonName) {
                this.negativeButtonName = negativeButtonName;
                return this;
            }
 
            public PermissionRequester create() {
                this.requester.setBuilder(this);
                return this.requester;
            }
 
        }
 
        public interface OnClickDenyButtonListener {
 
            public void onClick(Activity activity);
 
        }
 
}
 
cs




PermissionRequester 를 이용하여 MainActivity에서 권한 요청을 한다.



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
package com.ktds.jmj.callapp;
 
import android.Manifest;
import android.app.Activity;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v4.app.ActivityCompat;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;
 
public class MainActivity extends AppCompatActivity {
 
    private Button button;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
 
        button = (Button) findViewById(R.id.button);
 
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
 
                int result = new PermissionRequester.Builder(MainActivity.this)
                        .create()
                        .request(Manifest.permission.CALL_PHONE, 1000 , new PermissionRequester.OnClickDenyButtonListener() {
                            @Override
                            public void onClick(Activity activity) {
                                Log.d("RESULT""취소함.");
                            }
                        });
 
                if (result == PermissionRequester.ALREADY_GRANTED) {
                    Log.d("RESULT""권한이 이미 존재함.");
                    if (ActivityCompat.checkSelfPermission(MainActivity.this,
                            Manifest.permission.CALL_PHONE) == PackageManager.PERMISSION_GRANTED) {
                        Intent intent = new Intent(Intent.ACTION_CALL, Uri.parse("tel:010-6479-3612"));
                        startActivity(intent);
                    }
                }
                else if(result == PermissionRequester.NOT_SUPPORT_VERSION)
                    Log.d("RESULT""마쉬멜로우 이상 버젼 아님.");
                else if(result == PermissionRequester.REQUEST_PERMISSION)
                    Log.d("RESULT""요청함. 응답을 기다림.");
 
            }
        });
    }
 
    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
 
        if ( requestCode == 1000 ) {
            // 요청한 권한을 사용자가 "허용" 했다면...
            if( grantResults.length > 0 && grantResults[0]  == PackageManager.PERMISSION_GRANTED){
                Intent intent = new Intent(Intent.ACTION_CALL, Uri.parse("tel:010-6479-3612"));
                if (ActivityCompat.checkSelfPermission(this, Manifest.permission.CALL_PHONE) != PackageManager.PERMISSION_GRANTED) {
                    startActivity(intent);
                }
            }
            else{
                Toast.makeText(MainActivity.this"권한요청을 거부했습니다." , Toast.LENGTH_SHORT).show();
            }
        }
    }
}
 
cs




전화 걸리는 화면



이미 권한이 존재 한다면 로그가 찍힌다.






댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
«   2024/12   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31
글 보관함