Xamarin.Android의 사용 권한

개요

Android 애플리케이션은 자체 샌드박스에서 실행되며 보안상의 이유로 디바이스의 특정 시스템 리소스 또는 하드웨어에 액세스할 수 없습니다. 사용자는 이러한 리소스를 사용하려면 먼저 앱에 명시적으로 권한을 부여해야 합니다. 예를 들어 애플리케이션은 사용자의 명시적 권한 없이 디바이스의 GPS에 액세스할 수 없습니다. 앱이 Java.Lang.SecurityException 권한 없이 보호된 리소스에 액세스하려고 하면 Android가 throw됩니다.

권한은 앱이 개발될 때 애플리케이션 개발자가 AndroidManifest.xml 선언합니다. Android에는 이러한 권한에 대한 사용자의 동의를 얻기 위한 두 가지 워크플로가 있습니다.

  • Android 5.1(API 수준 22) 이하를 대상으로 하는 앱의 경우 앱이 설치되었을 때 권한 요청이 발생했습니다. 사용자가 권한을 부여하지 않은 경우 앱이 설치되지 않습니다. 앱이 설치되면 앱을 제거하는 것 외에는 사용 권한을 취소할 방법이 없습니다.
  • Android 6.0(API 수준 23)부터 사용자에게 권한을 더 많이 제어할 수 있습니다. 디바이스에 앱을 설치하는 한 권한을 부여하거나 취소할 수 있습니다. 이 스크린샷은 Google 연락처 앱에 대한 사용 권한 설정을 보여줍니다. 다양한 사용 권한을 나열하고 사용자가 사용 권한을 사용하거나 사용하지 않도록 설정할 수 있습니다.

Sample Permissions screen

Android 앱은 보호된 리소스에 액세스할 수 있는 권한이 있는지 확인하기 위해 런타임에 검사 합니다. 앱에 권한이 없는 경우 사용자가 권한을 부여할 수 있도록 Android SDK에서 제공하는 새 API를 사용하여 요청해야 합니다. 사용 권한은 다음 두 가지 범주로 나뉩니다.

  • 일반 사용 권한 – 사용자의 보안 또는 개인 정보에 보안 위험을 거의 초래하지 않는 권한입니다. Android 6.0은 설치 시 자동으로 일반 권한을 부여합니다. 일반 사용 권한의 전체 목록은 Android 설명서를 참조하세요.
  • 위험한 사용 권한 – 일반적인 사용 권한과 달리 위험한 사용 권한은 사용자의 보안 또는 개인 정보를 보호하는 권한입니다. 사용자가 명시적으로 부여해야 합니다. SMS 메시지를 보내거나 받는 것은 위험한 권한이 필요한 작업의 예입니다.

Important

사용 권한이 속한 범주는 시간이 지남에 따라 변경 될 수 있습니다. "정상" 권한으로 분류된 권한은 향후 API 수준에서 위험한 권한으로 승격될 수 있습니다.

위험한 권한은 권한 그룹으로 더 세분화됩니다. 권한 그룹은 논리적으로 관련된 권한을 보유합니다. 사용자가 사용 권한 그룹의 한 구성원에게 사용 권한을 부여하면 Android는 해당 그룹의 모든 멤버에게 권한을 자동으로 부여합니다. 예를 들어 사용 권한 그룹에는 STORAGE 사용 권한과 READ_EXTERNAL_STORAGE 사용 권한이 모두 WRITE_EXTERNAL_STORAGE 있습니다. 사용자가 권한을 READ_EXTERNAL_STORAGEWRITE_EXTERNAL_STORAGE 부여하면 사용 권한이 동시에 자동으로 부여됩니다.

하나 이상의 권한을 요청하기 전에 권한을 요청하기 전에 앱에 사용 권한이 필요한 이유에 대한 근거를 제공하는 것이 가장 좋습니다. 사용자가 근거를 이해하면 앱은 사용자의 권한을 요청할 수 있습니다. 근거를 이해하면 사용자는 사용 권한을 부여하고 그렇지 않은 경우 영향을 이해하려는 경우 정보에 입각한 결정을 내릴 수 있습니다.

검사 및 권한 요청의 전체 워크플로는 검사 런타임 권한이라고 하며 다음 다이어그램에 요약할 수 있습니다.

Run-time permission check flow chart

Android 지원 라이브러리는 이전 버전의 Android에 대한 사용 권한을 위해 일부 새 API를 백포트합니다. 이러한 백포칭 API는 디바이스에서 Android 버전을 자동으로 검사 매번 API 수준 검사 수행할 필요가 없습니다.

이 문서에서는 Xamarin.Android 애플리케이션에 권한을 추가하는 방법과 Android 6.0(API 수준 23) 이상을 대상으로 하는 앱이 런타임 권한 검사 수행하는 방법에 대해 설명합니다.

참고 항목

하드웨어에 대한 사용 권한은 Google Play에서 앱을 필터링하는 방법에 영향을 줄 수 있습니다. 예를 들어 앱에 카메라에 대한 권한이 필요한 경우 Google Play는 카메라가 설치되지 않은 디바이스의 Google Play 스토어에 앱을 표시하지 않습니다.

요구 사항

Xamarin.Android 프로젝트에는 Xamarin.Android.Support.Compat NuGet 패키지가 포함되어 있는 것이 좋습니다. 이 패키지는 권한 특정 API를 이전 버전의 Android로 백포팅하여 앱이 실행 중인 Android 버전을 지속적으로 검사 필요 없이 하나의 공통 인터페이스를 제공합니다.

시스템 권한 요청

Android 사용 권한을 사용하는 첫 번째 단계는 Android 매니페스트 파일에서 사용 권한을 선언하는 것입니다. 이 작업은 앱이 대상으로 하는 API 수준에 관계없이 수행해야 합니다.

Android 6.0 이상을 대상으로 하는 앱은 사용자가 과거에 사용 권한을 부여했기 때문에 다음에 권한이 유효하다고 가정할 수 없습니다. Android 6.0을 대상으로 하는 앱은 항상 런타임 권한 검사 수행해야 합니다. Android 5.1 이하를 대상으로 하는 앱은 런타임 권한 검사 수행할 필요가 없습니다.

참고 항목

애플리케이션은 필요한 권한만 요청해야 합니다.

매니페스트에서 사용 권한 선언

사용 권한은 요소를 사용하여 AndroidManifest.xmluses-permission 추가됩니다. 예를 들어 애플리케이션이 디바이스의 위치를 찾으려면 올바른 과정 위치 권한이 필요합니다. 매니페스트에 다음 두 요소가 추가됩니다.

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

Visual Studio에 기본 제공되는 도구 지원을 사용하여 사용 권한을 선언할 수 있습니다.

  1. 솔루션 탐색기 속성을두 번 클릭하고 속성 창 Android 매니페스트 탭을 선택합니다.

    Required permissions in the Android Manifest tab

  2. 애플리케이션에 아직 AndroidManifest.xml 없는 경우 AndroidManifest.xml 없음을 클릭합니다 . 아래와 같이 하나를 추가 하려면 클릭합니다.

    No AndroidManifest.xml message

  3. 필수 사용 권한 목록에서 애플리케이션에 필요한 권한을 선택하고 다음을 저장합니다 .

    Example CAMERA permissions selected

Xamarin.Android는 빌드 시 빌드 디버그에 일부 권한을 자동으로 추가합니다. 이렇게 하면 애플리케이션을 더 쉽게 디버깅할 수 있습니다. 특히 두 가지 주목할 만한 사용 권한은 다음과 같습니다 INTERNETREAD_EXTERNAL_STORAGE. 이러한 자동 설정 권한은 필수 사용 권한 목록에서 사용하도록 설정되지 않은 것으로 보입니다. 그러나 릴리스 빌드는 필수 사용 권한 목록에 명시적으로 설정된 권한 만 사용합니다.

Android 5.1(API 수준 22) 이하를 대상으로 하는 앱의 경우 더 이상 수행해야 할 작업이 없습니다. Android 6.0(API 23 수준 23) 이상에서 실행되는 앱은 런타임 권한 검사 수행하는 방법에 대한 다음 섹션으로 진행해야 합니다.

Android 6.0의 런타임 권한 검사

ContextCompat.CheckSelfPermission 메서드(Android 지원 라이브러리에서 사용 가능)는 특정 권한이 부여된 경우 검사 데 사용됩니다. 이 메서드는 다음 두 값 중 하나가 있는 열거형을 반환 Android.Content.PM.Permission 합니다.

  • Permission.Granted – 지정한 사용 권한이 부여되었습니다.
  • Permission.Denied – 지정한 사용 권한이 부여되지 않았습니다.

이 코드 조각은 활동에서 카메라 권한에 대해 검사 방법의 예입니다.

if (ContextCompat.CheckSelfPermission(this, Manifest.Permission.Camera) == (int)Permission.Granted) 
{
    // We have permission, go ahead and use the camera.
} 
else 
{
    // Camera permission is not granted. If necessary display rationale & request.
}

사용 권한을 부여하기 위해 정보에 입각한 결정을 내릴 수 있도록 애플리케이션에 권한이 필요한 이유를 사용자에게 알리는 것이 가장 좋습니다. 예를 들어 사진을 찍고 지리적 태그를 지정하는 앱이 있습니다. 사용자에게 카메라 권한이 필요하다는 것은 분명하지만 앱에 디바이스 위치도 필요한 이유가 명확하지 않을 수 있습니다. 근거는 사용자가 위치 권한이 바람직한 이유와 카메라 권한이 필요한 이유를 이해하는 데 도움이 되는 메시지를 표시해야 합니다.

ActivityCompat.ShouldShowRequestPermissionRationale 메서드는 근거를 사용자에게 표시해야 하는지 여부를 결정하는 데 사용됩니다. 지정된 권한에 대한 근거를 표시해야 하는 경우 이 메서드가 반환 true 됩니다. 이 스크린샷은 앱이 디바이스의 위치를 알아야 하는 이유를 설명하는 애플리케이션에서 표시하는 스낵바의 예를 보여줍니다.

Rationale for location

사용자가 권한을 부여하면 메서드를 ActivityCompat.RequestPermissions(Activity activity, string[] permissions, int requestCode) 호출해야 합니다. 이 메서드에는 다음 매개 변수가 필요합니다.

  • 활동 – 권한을 요청하는 활동이며 Android에서 결과를 알려야 합니다.
  • permissions – 요청되는 사용 권한 목록입니다.
  • requestCode – 호출에 대한 권한 요청의 결과를 일치시키는 데 사용되는 정수 값입니다 RequestPermissions . 이 값은 0보다 커야 합니다.

이 코드 조각은 설명된 두 가지 메서드의 예입니다. 먼저 사용 권한 근거를 표시해야 하는지 여부를 확인하기 위해 검사 만들어집니다. 근거를 표시할 경우 근거와 함께 스낵바가 표시됩니다. 사용자가 스낵바에서 확인을 클릭하면 앱에서 사용 권한을 요청합니다. 사용자가 근거를 수락하지 않으면 앱에서 사용 권한을 요청하지 않아야 합니다. 근거를 표시하지 않으면 활동에서 사용 권한을 요청합니다.

if (ActivityCompat.ShouldShowRequestPermissionRationale(this, Manifest.Permission.AccessFineLocation)) 
{
    // Provide an additional rationale to the user if the permission was not granted
    // and the user would benefit from additional context for the use of the permission.
    // For example if the user has previously denied the permission.
    Log.Info(TAG, "Displaying camera permission rationale to provide additional context.");

    var requiredPermissions = new String[] { Manifest.Permission.AccessFineLocation };
    Snackbar.Make(layout, 
                   Resource.String.permission_location_rationale,
                   Snackbar.LengthIndefinite)
            .SetAction(Resource.String.ok, 
                       new Action<View>(delegate(View obj) {
                           ActivityCompat.RequestPermissions(this, requiredPermissions, REQUEST_LOCATION);
                       }    
            )
    ).Show();
}
else 
{
    ActivityCompat.RequestPermissions(this, new String[] { Manifest.Permission.Camera }, REQUEST_LOCATION);
}

RequestPermission 는 사용자가 이미 사용 권한을 부여한 경우에도 호출할 수 있습니다. 후속 호출은 필요하지 않지만 사용자에게 사용 권한을 확인(또는 해지)할 수 있는 기회를 제공합니다. RequestPermission 호출되면 컨트롤이 운영 체제에 전달되며, 권한 수락을 위한 UI가 표시됩니다.

Permssion Dialog

사용자가 완료되면 Android는 콜백 메서드 OnRequestPermissionResult를 통해 결과를 활동으로 반환합니다. 이 메서드는 Activity에서 구현해야 하는 인터페이스 ActivityCompat.IOnRequestPermissionsResultCallback 의 일부입니다. 이 인터페이스에는 사용자의 선택에 대한 활동을 알리기 위해 Android에서 호출하는 단일 메서드 OnRequestPermissionsResult가 있습니다. 사용자가 권한을 부여한 경우 앱은 계속 진행하여 보호된 리소스를 사용할 수 있습니다. 구현 OnRequestPermissionResult 방법의 예는 다음과 같습니다.

public override void OnRequestPermissionsResult(int requestCode, string[] permissions, Permission[] grantResults)
{
    if (requestCode == REQUEST_LOCATION) 
    {
        // Received permission result for camera permission.
        Log.Info(TAG, "Received response for Location permission request.");

        // Check if the only required permission has been granted
        if ((grantResults.Length == 1) && (grantResults[0] == Permission.Granted)) {
            // Location permission has been granted, okay to retrieve the location of the device.
            Log.Info(TAG, "Location permission has now been granted.");
            Snackbar.Make(layout, Resource.String.permission_available_camera, Snackbar.LengthShort).Show();            
        } 
        else 
        {
            Log.Info(TAG, "Location permission was NOT granted.");
            Snackbar.Make(layout, Resource.String.permissions_not_granted, Snackbar.LengthShort).Show();
        }
    } 
    else 
    {
        base.OnRequestPermissionsResult(requestCode, permissions, grantResults);
    }
}

요약

이 가이드에서는 Android 디바이스에서 사용 권한을 추가하고 검사 방법에 대해 설명했습니다. 이전 Android 앱(API 수준 23)과 새 Android 앱(API 수준 <> 22) 간에 사용 권한이 작동하는 방식의 차이점입니다. Android 6.0에서 런타임 권한 검사 수행하는 방법을 설명했습니다.