티스토리 뷰
안드로이드 권한 획득
권한 획득하기
- 마시멜로우(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 |
전화 걸리는 화면
이미 권한이 존재 한다면 로그가 찍힌다.
'Android' 카테고리의 다른 글
[Android] 웹에 요청하기 (0) | 2016.07.26 |
---|---|
[Android] 항목 선택 MultiChoiceItems, SingleChoiceItems (1) | 2016.07.25 |
[Android] AlertDialog 를 이용한 알림창 (0) | 2016.07.21 |
[Android] onBackPressed 뒤로가기 버튼 처리 (0) | 2016.07.21 |
[Android] startActivityForResult (0) | 2016.07.21 |
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
- Total
- Today
- Yesterday
TAG
- algorithm
- AlertDialog.Builder
- order by
- 예외처리
- BFS
- RequestMapping
- INSERT
- restfb
- list
- DP
- onBackPressed
- maven
- Spring
- jsp
- table
- servlet
- indexOf
- 안드로이드 스튜디오
- REDIRECT
- java
- sort
- onPostExecute
- boj
- 자바
- mybatis
- 이클립스
- Baekjoon Online Judege
- DFS
- controller
- 안드로이드 비콘
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
글 보관함