출처 : http://g-y-e-o-m.tistory.com/47
[권한]
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; } }
주석 부분 참고
앱이 실행되고 처음에 권한 요청된 모습
거부를 누른 경우
앱을 완전히 종료하고 다시 실행시켰을 때
'Android(기능)' 카테고리의 다른 글
[Android] 외부 라이브러리 제거하기 (Gradle아닌 Module로 Import한 경우) (0) | 2017.08.31 |
---|---|
[Android] 카메라 사진 찍기 및 앨범에서 사진 가져오기, 크롭(Crop)하기, 프로바이더 설정하기, 이미지뷰에 띄우기 (49) | 2017.08.28 |
[Android] 위험 권한, 권한 전용 팝업 만들기 (0) | 2017.08.28 |
[Android] 문자 수신 처리 (브로드캐스트 리시버, BroadcastReceiver) 2 : 동적 리시버 (0) | 2017.08.24 |
[Android] 바탕화면에 바로가기 아이콘(ShortCut) 만들기 (1) | 2017.08.16 |
[Android] 액션바 제거, 상태바 설정 (0) | 2017.07.31 |
'개발 > APP' 카테고리의 다른 글
[Android] 내부 SQL(SQLite) Database 사용하기 (0) | 2018.10.15 |
---|---|
안드로이드 6.0 (Marshmallow) 권한 획득하기! (0) | 2018.10.15 |
웹앱 하이브리드앱의 앱스토어 통과 검수하기 위한 기준 (0) | 2018.10.15 |
안드로이드 발신, 수신 통화 모니터링하기 (0) | 2018.10.11 |
안드로이드 앱에서 웹뷰로 데이터 전송 (0) | 2018.10.10 |