민감한 데이터 액세스 필요성 결정

권한의 목적은 Android 사용자의 개인정보를 보호하는 것입니다. Android 앱에서는 민감한 사용자 데이터(예: 연락처, SMS) 및 특정 시스템 기능(예: 카메라, 인터넷)에 액세스할 수 있는 권한을 요청해야 합니다. 기능에 따라 시스템에서 자동으로 권한을 부여하거나 사용자에게 요청을 승인하라는 메시지를 표시할 수 있습니다.

Android 보안 아키텍처는 기본적으로 앱에 다른 앱, 운영체제 또는 사용자에게 안 좋은 영향을 미칠 수 있는 작업을 수행할 수 있는 권한이 없다는 것을 바탕으로 디자인되었습니다. 여기에는 사용자의 개인 데이터(예: 연락처 또는 이메일) 읽기/쓰기, 다른 앱 파일 읽기/쓰기, 네트워크 액세스 실행, 기기를 실행 상태로 유지 등이 포함됩니다.

이 페이지에서는 사용자에게 권한이 제공되는 방식, 설치 시간 및 런타임 권한 요청 간의 차이, 권한이 사용되는 방식, 권한의 유형 및 그룹 등 Android 권한의 작동 방식에 관한 개요를 제공합니다. 앱 권한 사용에 관한 안내 가이드만 필요하면 앱 권한 요청을 참조하세요.

권한 승인

앱에서는 앱 manifest <uses-permission> 태그를 포함하여 필요한 권한을 공개해야 합니다. 예를 들어 SMS 메시지를 보내야 하는 앱은 manifest에 다음 줄이 있어야 합니다.

    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
              package="com.example.snazzyapp">

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

        <application ...>
            ...
        </application>
    </manifest>
    

앱이 manifest에서 정상 권한(즉, 사용자 개인정보 또는 기기 작업에 많은 위험이 되지 않는 권한)을 나열하는 경우 시스템이 자동으로 이러한 권한을 부여합니다.

앱이 manifest에서 위의 SEND_SMS 권한과 같이 위험한 권한(즉, 사용자 개인정보 또는 기기의 정상 작업에 영향을 미칠 수 있는 권한)을 나열하는 경우 사용자가 이러한 권한을 부여하는 데 명시적으로 동의해야 합니다.

정상 권한 및 위험한 권한에 관한 자세한 정보는 보호 수준을 참조하세요.

위험한 권한에 요청 프롬프트

위험한 권한에만 사용자 동의가 필요합니다. Android에서 사용자에게 위험한 권한을 부여하도록 요청하는 방법은 사용자의 기기에서 실행되는 Android의 버전 및 앱에서 타겟팅하는 시스템 버전에 따라 다릅니다.

런타임 요청(Android 6.0 이상)

기기에서 Android 6.0(API 레벨 23) 이상을 실행하고 앱의 targetSdkVersion이 23 이상인 경우 설치 시 사용자에게 앱 권한에 관해 알리지 않습니다. 앱에서 사용자에게 런타임에 위험한 권한을 부여하도록 요청해야 합니다. 앱에서 권한을 요청하는 경우 사용자에게 앱에서 액세스하려고 하는 권한 그룹을 알려주는 시스템 대화상자가 표시됩니다(그림 1의 왼쪽). 대화상자에는 거부허용 버튼이 포함됩니다.

사용자가 권한 요청을 거부하면 앱에서 다음에 권한을 요청할 때 사용자가 권한 요청 메시지가 다시 표시되지 않도록 선택할 수 있는 체크박스가 대화상자에 포함됩니다(그림 1의 왼쪽).

그림 1. 초기 권한 대화상자(왼쪽) 및 추가 요청을 해제할 수 있는 옵션이 있는 보조 권한 요청(오른쪽)

사용자가 다시 묻지 않음 체크박스를 선택하고 거부를 탭하면 나중에 동일한 권한을 요청하려고 할 때 시스템에서 더 이상 사용자에게 메시지를 표시하지 않습니다.

사용자가 앱에서 요청한 권한을 앱에 부여하더라도 나에게 항상 권한이 부여되는 것은 아닙니다. 또한 사용자는 시스템 설정에서 권한을 하나씩 사용 설정하거나 중지할 수 있습니다. 런타임 오류(SecurityException)가 발생하지 않도록 런타임에 항상 권한을 확인하고 요청해야 합니다.

런타임 권한 요청을 처리하는 방법에 관한 자세한 내용은 앱 권한 요청을 참조하세요.

설치 시간 요청(Android 5.1.1 이하)

기기에서 Android 5.1.1(API 레벨 22) 이하를 실행하거나 앱의 targetSdkVersion이 22 이하인 경우(실행 중인 Android 버전에는 제한이 없음) 시스템에서 사용자에게 설치 시 위험한 권한을 모두 앱에 부여하도록 자동으로 요청합니다(그림 2 참조).

그림 2. 설치 시간 권한 대화상자

사용자가 수락을 클릭하면 앱에서 요청한 모든 권한이 부여됩니다. 사용자가 권한 요청을 거부하면 시스템에서 앱 설치를 취소합니다.

앱 업데이트에 추가 권한을 포함해야 하는 경우 앱을 업데이트하기 전에 이러한 새 권한을 수락하라는 메시지가 사용자에게 표시됩니다.

권한 요청에 권장되는 사용자 환경 패턴의 개요는 앱 권한 권장사항을 참조하세요.

사용자의 권한을 확인하고 요청하는 방법을 알아보려면 앱 권한 요청을 참조하세요.

민감한 사용자 정보 액세스 요청 프롬프트

일부 앱에서는 통화 기록 및 SMS 메시지와 관련된 민감한 사용자 정보에 액세스할 수 있는 권한이 필요합니다. 통화 기록 및 SMS 메시지와 관련된 권한을 요청하고 앱을 Play 스토어에 게시하려면 이러한 런타임 권한을 요청하기 전에 사용자에게 앱을 핵심 시스템 기능의 기기 핸들러로 설정하라는 메시지를 표시해야 합니다.

사용자에게 기기 핸들러 메시지를 표시하는 방법 등 기기 핸들러에 관한 자세한 내용은 기기 핸들러에서만 사용되는 권한에 관한 가이드를 참조하세요.

선택적 하드웨어 기능에 관한 권한

일부 하드웨어 기능(예: 블루투스, 카메라)에 액세스하려면 앱 권한이 필요합니다. 하지만 모든 Android 기기에 실제로 이러한 하드웨어 기능이 있는 것은 아닙니다. 따라서 앱에서 CAMERA 권한을 요청하는 경우 manifest에 <uses-feature> 태그를 포함하여 이 기능이 실제로 필요한지 여부를 선언하는 것이 중요합니다. 예:

<uses-feature android:name="android.hardware.camera" android:required="false" />
    

기능에 관해 android:required="false"를 선언하면 Google Play에서 기능이 없는 기기에 앱을 설치할 수 있도록 허용합니다. 그런 다음 런타임에 PackageManager.hasSystemFeature()를 호출하여 현재 기기에 기능이 있는지 확인하고 기능을 사용할 수 없는 경우 기능을 적절하게 사용 중지해야 합니다.

<uses-feature> 태그를 제공하지 않는 경우 Google Play에서 앱이 권한을 요청하는 것으로 확인되면 앱에서 이 기능이 필요하다고 가정합니다. 따라서 <uses-feature> 태그에 android:required="true"를 선언한 것처럼 기능이 없는 기기에서 앱을 필터링합니다.

자세한 내용은 Google Play 및 기능 기반 필터링을 참조하세요.

권한 적용

권한은 시스템 기능을 요청하기 위해서만 사용되는 것은 아닙니다. 앱에서 제공하는 서비스에서는 맞춤 권한을 적용하여 서비스를 사용할 수 있는 사람을 제한할 수 있습니다. 맞춤 권한 선언에 관한 자세한 내용은 맞춤 앱 권한 정의를 참조하세요.

활동 권한 적용

android:permission 속성을 사용하여 manifest의 <activity> 태그에 적용된 권한에 따라 Activity를 시작할 수 있는 사람이 제한됩니다. 권한은 Context.startActivity()Activity.startActivityForResult() 동안 검사됩니다. 발신자에게 필요한 권한이 없으면 호출에서 SecurityException이 발생합니다.

서비스 권한 적용

android:permission 속성을 사용하여 manifest의 <service> 태그에 적용된 권한에 따라 연결된 Service를 시작하거나 결합할 수 있는 사람이 제한됩니다. 권한은 Context.startService(), Context.stopService()Context.bindService() 동안 검사됩니다. 발신자에게 필요한 권한이 없으면 호출에서 SecurityException이 발생합니다.

브로드캐스트 권한 적용

android:permission 속성을 사용하여 manifest의 <receiver> 태그에 적용된 권한에 따라 연결된 BroadcastReceiver에 브로드캐스트를 보낼 수 있는 사람이 제한됩니다. 이 권한은 시스템이 제출된 브로드캐스트를 지정된 수신자에게 제공하려고 시도하므로 Context.sendBroadcast()가 반환된 후에 검사됩니다. 따라서 권한 오류가 발생해도 발신자에게는 예외가 발생하지 않으며, 단지 Intent만 제공하지 않게 됩니다.

같은 방법으로, 권한을 Context.registerReceiver()에 제공하여 프로그래매틱 방식으로 등록된 수신자에게 브로드캐스트할 수 있는 사용자를 제어할 수 있습니다. 다르게는 Context.sendBroadcast()를 호출할 때 권한을 제공하여 브로드캐스트를 수신하도록 허용되는 broadcast receiver를 제한할 수도 있습니다.

수신기와 브로드캐스터 모두에 권한이 필요할 수 있습니다. 이 경우 두 권한 검사를 모두 통과해야만 인텐트가 연결된 대상에 제공됩니다. 자세한 내용은 권한으로 브로드캐스트 제한을 참조하세요.

콘텐츠 제공업체 권한 적용

android:permission 속성을 사용하여 <provider> 태그에 적용된 권한에 따라 ContentProvider의 데이터에 액세스할 수 있는 사람이 제한됩니다. (콘텐츠 제공업체가 사용할 수 있는 URI 권한이라고 하는 중요한 추가 보안 기능이 있습니다. 이에 관해서는 뒷부분에서 설명합니다.) 다른 구성 요소와 달리 두 가지 개별적인 권한 속성을 설정할 수 있습니다. android:readPermission은 제공업체로부터 데이터를 읽을 수 있는 사용자를 제한하고 android:writePermission은 제공업체에 데이터를 쓸 수 있는 사용자를 제한합니다. 참고로 제공업체가 읽기 및 쓰기 권한 모두를 사용하여 보호되는 경우 쓰기 권한만 보유할 경우에는 제공업체로부터 데이터를 읽을 수 없습니다.

먼저 제공업체를 검색할 때 권한이 검사되고(두 권한이 모두 없는 경우 SecurityException이 발생함) 그다음으로 제공업체에서 작업을 실행할 때 권한이 검사됩니다. ContentResolver.query()를 사용하려면 읽기 권한이 있어야 하고 ContentResolver.insert(), ContentResolver.update(), ContentResolver.delete()를 사용하려면 쓰기 권한이 있어야 합니다. 이러한 경우 모두 필요한 권한이 없으면 호출에서 SecurityException이 발생합니다.

URI 권한

지금까지 설명한 표준 권한 시스템으로는 콘텐츠 제공업체에 사용하는 데 충분하지 않은 경우가 많습니다. 콘텐츠 제공업체는 읽기 및 쓰기 권한을 사용하여 자체적으로 보호하기를 원할 수 있으며, 이 경우 직속 클라이언트는 다른 앱에서 작동하기 위해 특정 URI를 이러한 앱에 전달해야 합니다.

일반적인 예는 이메일 앱의 첨부파일입니다. 이메일은 민감한 사용자 데이터이므로 이메일의 액세스는 권한으로 보호되어야 합니다. 하지만, 이미지 첨부파일의 URI가 이미지 뷰어에 제공된 경우 이미지 뷰어가 모든 이메일에 액세스할 수 있는 권한을 가지고 있을 이유가 없으므로 이미지 뷰어가 더 이상 이 첨부파일을 열 수 있는 권한이 없습니다.

이 문제를 해결할 수 있는 방법은 URI별 권한입니다. 활동을 시작하거나 결과를 활동에 반환할 때 발신자는 Intent.FLAG_GRANT_READ_URI_PERMISSION 및/또는 Intent.FLAG_GRANT_WRITE_URI_PERMISSION을 설정할 수 있습니다. 이 설정은 콘텐츠 제공업체에서 인텐트에 해당하는 데이터에 액세스할 수 있는 권한이 있는지 여부에 상관없이 수신하는 활동 권한 액세스를 인텐트에 있는 특정 데이터 URI에 부여합니다.

이 메커니즘은 사용자 상호작용(예: 첨부파일 열기, 목록에서 연락처 선택)이 세분화된 권한의 임시 부여를 유도하는 일반적인 기능 스타일 모델을 허용합니다. 이는 앱에 필요한 권한을 동작과 직접적으로 관련이 있는 권한으로 줄이는 데 핵심적인 기능일 수 있습니다.

다른 앱에서 앱 내의 작업을 책임지도록 안전하게 구현하려면 세분화된 권한을 이러한 방식으로 사용하고 android:grantUriPermissions 속성 또는 <grant-uri-permissions> 태그를 사용하여 앱에서 이 구현을 지원하도록 선언해야 합니다.

자세한 내용은 Context.grantUriPermission(), Context.revokeUriPermission()Context.checkUriPermission() 메서드에서 확인할 수 있습니다.

기타 권한 적용

원하는 대로 세분화된 권한을 모든 서비스 호출에 적용할 수 있습니다. 이 작업은 Context.checkCallingPermission() 메서드를 사용하여 실행합니다. 원하는 권한 문자열을 사용하여 호출합니다. 그러면 권한이 현재 호출하는 프로세스에 부여되었는지 여부를 나타내는 정수가 반환됩니다. 이 방법은 일반적으로 서비스에서 게시된 IDL 인터페이스를 통해서나 다른 프로세스에서 지정하는 다른 방법을 통해 다른 프로세스에서 들어오는 호출을 실행하는 경우에만 사용할 수 있습니다.

권한을 검사하는 데 유용한 여러 가지 다른 방법이 있습니다. 다른 프로세스의 프로세스 ID(PID)를 알고 있는 경우에는 Context.checkPermission() 메서드를 사용하여 PID에 대해 권한을 검사할 수 있습니다. 다른 앱의 패키지 이름을 알고 있는 경우에는 PackageManager.checkPermission() 메서드를 사용하여 특정 패키지에 특정 권한이 부여되었는지 여부를 확인할 수 있습니다.

자동 권한 조정

시간이 지남에 따라 새 제한사항이 플랫폼에 추가될 수 있습니다. 이 경우, 특정 API를 사용하기 위해서는 앱이 이전에는 필요하지 않았던 권한을 요청해야 합니다. 기존 앱은 이러한 API에 대한 액세스를 자유롭게 사용할 수 있다고 간주하므로 Android는 새 권한 요청을 앱의 manifest에 적용하여 새 플랫폼 버전에 설치된 앱이 손상되는 것을 방지하고, 따라서 권한과 관련하여 앱에 예외를 적용할 수 있습니다. Android는 targetSdkVersion 속성에 제공된 값에 따라 앱에 권한이 필요한지 여부를 결정합니다. 값이 권한이 추가된 버전보다 낮을 경우 Android가 권한을 추가합니다.

예를 들어 API 레벨 19부터 공유 저장소 공간의 액세스를 제한하기 위해 READ_EXTERNAL_STORAGE 권한이 적용된다고 가정합니다. targetSdkVersion이 18 이하이면 이 권한이 최신 버전의 Android에 설치된 앱에 추가됩니다.

주의: 권한이 앱에 자동으로 추가된 경우 앱이 실제적으로 권한을 필요로 하지 않더라도 이러한 추가 권한이 Google Play의 앱 목록에 나열됩니다. 이러한 권한 표시를 방지하고 필요하지 않은 기본 권한을 삭제하려면 항상 targetSdkVersion을 가능한 한 높게 업데이트하세요. Build.VERSION_CODES 문서에서 각 릴리스에 추가된 권한을 확인할 수 있습니다.

보호 수준

권한은 여러 보호 수준으로 나누어져 있습니다. 보호 수준은 런타임 권한 요청이 필요한지 여부에 영향을 미칩니다.

타사 앱에 영향을 미치는 보호 수준에는 정상, 서명, 위험한 권한 등 세 가지가 있습니다. 특정 권한의 보호 수준을 확인하려면 권한 API 참조 페이지를 방문하세요.

정상 권한

정상 권한에는 앱이 앱의 샌드박스 외부에 있는 데이터 또는 리소스에 액세스해야 하는 영역이 포함되지만, 사용자 개인정보나 다른 앱의 작업에 위험이 거의 없는 영역은 포함되지 않습니다. 예를 들어 표준 시간대를 설정하는 권한은 정상 권한입니다.

앱이 manifest에 정상 권한이 필요하다고 선언하면 시스템이 설치 시 자동으로 권한을 앱에 부여합니다. 시스템에서 사용자에게 정상 권한을 부여하라는 메시지를 표시하지 않으면 사용자가 이러한 권한을 취소할 수 없습니다.

서명 권한

시스템에서 설치 시 이러한 앱에 권한을 부여하지만 권한을 사용하려고 하는 앱이 권한을 정의한 앱과 동일한 인증서를 사용하여 서명된 경우에만 권한을 부여합니다.

위험한 권한

위험한 권한에는 앱이 사용자의 개인정보를 포함하거나 사용자의 저장된 데이터나 다른 앱의 작업에 영향을 미칠 수 있는 데이터나 리소스를 필요로 하는 영역이 포함됩니다. 예를 들어 사용자의 연락처를 읽을 수 있는 권한은 위험한 권한입니다. 앱에서 위험한 권한이 필요하다고 선언하면 사용자가 이 권한을 앱에 명시적으로 부여해야 합니다. 사용자가 권한을 승인할 때까지 앱에서 이 권한에 종속되는 기능을 제공할 수 없습니다.

위험한 권한을 사용하려면 앱에서 사용자에게 런타임에 권한을 부여하라는 메시지를 표시해야 합니다. 사용자에게 메시지를 표시하는 방법에 관한 자세한 내용은 위험한 권한 요청 프롬프트를 참조하세요.

특별 권한

정상 권한 및 위험한 권한처럼 동작하지 않는 권한이 몇 개 있습니다. SYSTEM_ALERT_WINDOWWRITE_SETTINGS는 특히 민감하므로 대부분의 앱에서 이 권한을 사용하지 않아야 합니다. 앱이 이러한 권한 중 하나를 필요로 할 경우 manifest에 이 권한을 선언하고 사용자 승인을 요청하는 인텐트를 전송해야 합니다. 시스템은 사용자에게 세부 관리 화면을 표시하여 인텐트에 응답합니다.

이러한 권한을 요청하는 방법에 관한 자세한 내용은 SYSTEM_ALERT_WINDOWWRITE_SETTINGS 참조 항목을 참조하세요.

Android 시스템에서 제공하는 모든 권한은 Manifest.permission에서 확인할 수 있습니다.

권한 그룹

권한은 기기의 기능과 관련된 그룹으로 분류됩니다. 이 시스템에서는 그룹 수준에서 권한 요청이 처리되며 단일 권한 그룹은 앱 manifest의 여러 권한 선언에 해당합니다. 예를 들어 SMS 그룹에는 READ_SMSRECEIVE_SMS 선언이 모두 포함됩니다. 이런 방식으로 권한을 그룹화하면 사용자가 복잡하고 기술적인 권한 요청에 휘둘리지 않고도 보다 정확하고 의미 있는 선택을 할 수 있습니다.

모든 위험한 Android 권한은 권한 그룹에 속합니다. 모든 권한은 보호 수준과 관계없이 하나의 권한 그룹에 속할 수 있습니다. 하지만, 권한 그룹은 권한이 위험한 경우에만 사용자 환경에 영향을 미칩니다.

기기가 Android 6.0(API 레벨 23)을 실행하고 앱의 targetSdkVersion이 23 이상인 경우 앱이 위험한 권한을 요청할 때 다음 시스템 동작이 적용됩니다.

  • 현재 앱에 권한 그룹의 권한이 없는 경우 시스템에서 앱이 액세스하려는 권한 그룹을 설명하는 권한 요청 대화상자를 사용자에게 표시합니다. 이 대화상자에서는 권한 그룹의 특정 권한을 설명하지 않습니다. 예를 들어 앱이 READ_CONTACTS 권한을 요청하는 경우 앱이 기기의 연락처에 액세스해야 한다는 메시지만 시스템 대화상자에 나타납니다. 사용자가 승인하면 시스템에서 앱이 요청한 권한만 앱에 부여합니다.
  • 앱에 이미 동일한 권한 그룹 내에 있는 다른 위험한 권한이 부여된 경우 시스템이 사용자와의 상호작용 없이 이러한 권한을 즉시 부여합니다. 예를 들어 앱이 READ_CONTACTS 권한을 이전에 요청하여 부여받았으며 이후 WRITE_CONTACTS를 요청한 경우 시스템이 사용자에게 권한 대화상자를 표시하지 않고 즉시 이 권한을 부여합니다.

주의: 이후 Android SDK 버전에서 특정 권한을 한 그룹에서 다른 그룹으로 이동할 수도 있습니다. 따라서 이러한 권한 그룹의 구조를 기반으로 앱의 로직을 구성하지 마세요.

예를 들어 Android 8.1(API 레벨 27) 현재 READ_CONTACTSWRITE_CONTACTS와 동일한 권한 그룹에 있습니다. 앱에서 READ_CONTACTS 권한을 요청한 다음 WRITE_CONTACTS 권한을 요청하는 경우 시스템에서 자동으로 WRITE_CONTACTS 권한을 부여할 수 있다고 가정하지 마세요.

기기가 Android 5.1(API 레벨 22) 이하를 실행하거나 앱의 targetSdkVersion이 22 이하인 경우 시스템이 설치 시 권한을 부여하도록 사용자에게 요청합니다. 다시 한번 설명하지만, 시스템은 사용자에게 개별 권한이 아니라 앱이 필요로 하는 권한 그룹만 알립니다. 예를 들어 앱에서 READ_CONTACTS를 요청하는 경우 설치 대화상자에 연락처 그룹이 나열됩니다. 사용자가 수락하면 READ_CONTACTS 권한만 앱에 부여됩니다.

참고: 사용자가 이미 동일한 그룹에 있는 다른 권한을 부여한 경우라도 앱이 필요한 모든 권한을 명시적으로 요청해야 합니다. 향후 Android 릴리스에서는 권한 그룹화도 변경될 수 있습니다. 코드에 동일한 그룹에 있는 특정 권한 집합에 의존하는 로직이 없어야 합니다.

앱의 권한 보기

설정 앱 및 셸 명령어 adb shell pm list permissions를 사용하여 시스템에 현재 정의되어 있는 모든 권한을 볼 수 있습니다. 설정 앱을 사용하려면 설정 > 으로 이동하세요. 앱을 선택하고 아래로 스크롤하여 앱이 사용하는 권한을 확인합니다. 개발자의 경우 adb '-s' 옵션을 사용하면 사용자에게 권한이 표시되는 방법과 유사한 형태로 권한이 표시됩니다.

    $ adb shell pm list permissions -s
    All Permissions:

    Network communication: view Wi-Fi state, create Bluetooth connections, full
    internet access, view network state

    Your location: access extra location provider commands, fine (GPS) location,
    mock location sources for testing, coarse (network-based) location

    Services that cost you money: send SMS messages, directly call phone numbers

    ...
    

adb -g 옵션을 사용하여 에뮬레이터 또는 테스트 기기에 앱을 설치할 때 모든 권한을 자동으로 부여할 수도 있습니다.

    $ adb shell install -g MyApp.apk
    

추가 리소스

  • 앱 권한 요청: 앱에서 권한을 요청하는 방법에 관한 안내 가이드입니다.
  • 기능 요구사항을 암시하는 권한: 일부 권한을 요청하는 것이 어떤 식으로 하드웨어 또는 소프트웨어 기능을 포함하는 기기로 앱을 암묵적으로 제한하는지 설명하는 정보입니다.
  • <uses-permission>: 앱의 필수 권한을 선언하는 manifest 태그에 관한 API 참조입니다.
  • 기기 호환성: 여러 가지 유형의 기기에서 Android의 작동 방식과 앱을 각 기기에 맞춰 최적화하는 방법 또는 여러 가지 기기에 앱의 가용성을 제한하는 방법 등에 관한 정보입니다.
  • Android 보안 개요: Android 플랫폼의 보안 모델의 자세한 설명입니다.
  • "Mother, May I?" 권한 요청: Android Dev Summit 2015의 이 동영상에서는 권한 요청의 권장사항을 설명합니다.
  • Android M 권한: Google I/O 2015의 이 동영상에서는 Android 6.0 권한 모델의 변경사항을 설명합니다.