다음을 통해 공유


Xamarin.Essentials:권한을

Permissions 클래스는 런타임 권한을 확인하고 요청하는 기능을 제공합니다.

시작하기

이 API를 사용하기 전에 라이브러리가 제대로 설치되고 프로젝트에 설정되어 있는지 확인하기 위해 Xamarin.Essentials에 대한 시작 가이드를 읽어보세요.

이 API는 Android에서 런타임 권한을 사용합니다. Xamarin.Essentials가 완전히 초기화되고 앱에서 사용 권한 처리가 설정되어 있는지 확인하세요.

Android 프로젝트의 MainLauncher 또는 시작된 ActivityOnCreate 메서드에서 Xamarin.Essentials를 초기화해야 합니다.

protected override void OnCreate(Bundle savedInstanceState) 
{
    //...
    base.OnCreate(savedInstanceState);
    Xamarin.Essentials.Platform.Init(this, savedInstanceState); // add this line to your code, it may also be called: bundle
    //...
}    

Android에서 런타임 권한을 처리하려면 Xamarin.Essentials가 OnRequestPermissionsResult를 받아야 합니다. 모든 Activity 클래스에 다음 코드를 추가합니다.

public override void OnRequestPermissionsResult(int requestCode, string[] permissions, Android.Content.PM.Permission[] grantResults)
{
    Xamarin.Essentials.Platform.OnRequestPermissionsResult(requestCode, permissions, grantResults);

    base.OnRequestPermissionsResult(requestCode, permissions, grantResults);
}

권한 사용

클래스에서 Xamarin.Essentials에 대한 참조를 추가합니다.

using Xamarin.Essentials;

권한 확인

권한의 현재 상태를 확인하려면 상태를 가져올 특정 권한과 함께 CheckStatusAsync 메서드를 사용합니다.

var status = await Permissions.CheckStatusAsync<Permissions.LocationWhenInUse>();

필요한 권한이 선언되지 않은 경우에는 PermissionException이 throw됩니다.

권한을 요청하기 전에 권한 상태를 확인하는 것이 좋습니다. 사용자에게 메시지가 표시되지 않는 경우 각 운영 체제는 다른 기본 상태를 반환합니다. iOS는 Unknown을 반환하고, 다른 운영 체제는 Denied를 반환합니다. 상태가 Granted인 경우 다른 호출을 하지 않아도 됩니다. iOS에서 상태가 Denied인 경우 사용자에게 설정에서 권한을 변경하라는 메시지를 표시해야 하며, Android에서는 ShouldShowRationale을 호출하여 과거에 사용자가 권한 요청을 거부한 적이 있는지 감지할 수 있습니다.

권한 요청

사용자에게 권한을 요청하려면 요청할 특정 권한과 함께 RequestAsync 메서드를 사용합니다. 사용자가 이전에 권한을 부여하고 취소하지 않은 경우 이 메서드는 즉시 Granted를 반환하고 대화 상자를 표시하지 않습니다.

var status = await Permissions.RequestAsync<Permissions.LocationWhenInUse>();

필요한 권한이 선언되지 않은 경우에는 PermissionException이 throw됩니다.

일부 플랫폼에서 권한 요청은 한 번만 활성화될 수 있습니다. 권한이 Denied 상태인지 확인하고 사용자에게 수동으로 설정하도록 요청하려면 개발자가 추가 프롬프트를 처리해야 합니다.

권한 상태

CheckStatusAsync 또는 RequestAsync를 사용하는 경우 다음 단계를 결정하는 데 사용할 수 있는 PermissionStatus가 반환됩니다.

  • 알 수 없음 - 권한이 알 수 없는 상태입니다.
  • 거부됨 - 사용자가 권한 요청을 거부했습니다.
  • 사용 안 함 - 디바이스에서 이 기능을 사용할 수 없습니다.
  • 부여됨 - 사용자가 권한을 부여했거나 권한이 자동으로 부여됩니다.
  • 제한됨 - 제한된 상태입니다.

권한이 필요한 이유 설명

애플리케이션에 특정 권한이 필요한 이유를 설명하는 것이 모범 사례입니다. iOS에서는 사용자에게 표시하는 문자열을 지정해야 합니다. Android에는 이 기능이 없으며 기본 권한 상태도 사용 안 함으로 설정되어 있습니다. 이 때문에 사용자가 권한을 거부했는지 또는 사용자에게 메시지를 처음으로 표시하는지 여부를 파악하지 못합니다. ShouldShowRationale 메서드를 사용하여 교육용 UI를 표시할지 여부를 결정할 수 있습니다. 메서드가 true를 반환한다면 사용자가 이전에 권한을 거부하거나 사용하지 않도록 설정한 것입니다. 다른 플랫폼은 이 메서드를 호출할 때 항상 false를 반환합니다.

사용 가능한 권한

Xamarin.Essentials는 최대한 많은 권한을 추상화하려고 시도합니다. 그러나 각 운영 체제에는 서로 다른 런타임 권한 집합이 있습니다. 또한 일부 권한에 대해 단일 API를 제공한다는 차이점이 있습니다. 다음은 현재 사용할 수 있는 권한에 대한 가이드입니다.

아이콘 지침:

  • Full Support -지원
  • Not Supported - 지원되지 않음/필수
Permission Android iOS UWP watchOS tvOS Tizen
CalendarRead Android supported iOS supported UWP not supported watchOS supported tvOS not supported Tizen not supported
CalendarWrite Android supported iOS supported UWP not supported watchOS supported tvOS not supported Tizen not supported
카메라 Android supported iOS supported UWP not supported watchOS not supported tvOS not supported Tizen supported
ContactsRead Android supported iOS supported UWP supported watchOS not supported tvOS not supported Tizen not supported
ContactsWrite Android supported iOS supported UWP supported watchOS not supported tvOS not supported Tizen not supported
손전등 Android supported iOS not supported UWP not supported watchOS not supported tvOS not supported Tizen supported
LocationWhenInUse Android supported iOS supported UWP supported watchOS supported tvOS supported Tizen supported
LocationAlways Android supported iOS supported UWP supported watchOS supported tvOS not supported Tizen supported
미디어 Android not supported iOS supported UWP not supported watchOS not supported tvOS not supported Tizen not supported
마이크 Android supported iOS supported UWP supported watchOS not supported tvOS not supported Tizen supported
휴대폰 Android supported iOS supported UWP not supported watchOS not supported tvOS not supported Tizen not supported
사진 Android not supported iOS supported UWP not supported watchOS not supported tvOS supported Tizen not supported
미리 알림 Android not supported iOS supported UWP not supported watchOS supported tvOS not supported Tizen not supported
센서 Android supported iOS supported UWP supported watchOS supported tvOS not supported Tizen not supported
Sms Android supported iOS supported UWP not supported watchOS not supported tvOS not supported Tizen not supported
음성 Android supported iOS supported UWP not supported watchOS not supported tvOS not supported Tizen not supported
StorageRead Android supported iOS not supported UWP not supported watchOS not supported tvOS not supported Tizen not supported
StorageWrite Android supported iOS not supported UWP not supported watchOS not supported tvOS not supported Tizen not supported

사용 권한이 표시 not supported 되면 검사 또는 요청될 때 항상 반환 Granted 됩니다.

일반적인 사용법

다음 코드에서는 사용 권한이 부여되었는지 확인하고 부여되지 않은 경우 요청하기 위한 일반적인 사용 패턴을 보여 줍니다. 이 코드는 Xamarin.Essentials 버전 1.6.0 이상에서 제공되는 기능을 사용합니다.

public async Task<PermissionStatus> CheckAndRequestLocationPermission()
{
    var status = await Permissions.CheckStatusAsync<Permissions.LocationWhenInUse>();
    
    if (status == PermissionStatus.Granted)
        return status;        
    
    if (status == PermissionStatus.Denied && DeviceInfo.Platform == DevicePlatform.iOS)
    {
        // Prompt the user to turn on in settings
        // On iOS once a permission has been denied it may not be requested again from the application
        return status;
    }
    
    if (Permissions.ShouldShowRationale<Permissions.LocationWhenInUse>())
    {
        // Prompt the user with additional information as to why the permission is needed
    }   

    status = await Permissions.RequestAsync<Permissions.LocationWhenInUse>();

    return status;
}

각 권한 형식에는 메서드를 직접 호출할 수 있도록 생성된 인스턴스가 있을 수 있습니다.

public async Task GetLocationAsync()
{
    var status = await CheckAndRequestPermissionAsync(new Permissions.LocationWhenInUse());
    if (status != PermissionStatus.Granted)
    {
        // Notify user permission was denied
        return;
    }

    var location = await Geolocation.GetLocationAsync();
}

public async Task<PermissionStatus> CheckAndRequestPermissionAsync<T>(T permission)
            where T : BasePermission
{
    var status = await permission.CheckStatusAsync();
    if (status != PermissionStatus.Granted)
    {
        status = await permission.RequestAsync();
    }

    return status;
}

권한 확장

권한 API는 Xamarin.Essentials에 포함되지 않은 추가 유효성 검사 또는 권한이 필요한 애플리케이션을 위해 유연하고 확장 가능하도록 만들어졌습니다. BasePermission에서 상속되는 새 클래스를 만들고 필요한 추상 메서드를 구현합니다.

public class MyPermission : BasePermission
{
    // This method checks if current status of the permission
    public override Task<PermissionStatus> CheckStatusAsync()
    {
        throw new System.NotImplementedException();
    }

    // This method is optional and a PermissionException is often thrown if a permission is not declared
    public override void EnsureDeclared()
    {
        throw new System.NotImplementedException();
    }

    // Requests the user to accept or deny a permission
    public override Task<PermissionStatus> RequestAsync()
    {
        throw new System.NotImplementedException();
    }
}

특정 플랫폼에서 권한을 구현하는 경우 BasePlatformPermission 클래스를 상속할 수 있습니다. 그러면 자동으로 선언을 확인하는 추가 플랫폼 도우미 메서드가 제공됩니다. 이는 그룹화를 수행하는 사용자 지정 권한을 만들 때 유용할 수 있습니다. 예를 들어 다음 사용자 지정 권한을 사용하여 Android에서 스토리지에 대한 읽기 및 쓰기 권한을 요청할 수 있습니다.

public class ReadWriteStoragePermission : Xamarin.Essentials.Permissions.BasePlatformPermission
{
    public override (string androidPermission, bool isRuntime)[] RequiredPermissions => new List<(string androidPermission, bool isRuntime)>
    {
        (Android.Manifest.Permission.ReadExternalStorage, true),
        (Android.Manifest.Permission.WriteExternalStorage, true)
    }.ToArray();
}

그런 다음 Android 프로젝트에서 새 권한을 호출할 수 있습니다.

await Permissions.RequestAsync<ReadWriteStoragePermission>();

공유 코드에서 이 API를 호출하려는 경우 인터페이스를 만들고 종속성 서비스를 사용하여 구현을 등록하고 가져올 수 있습니다.

public interface IReadWritePermission
{        
    Task<PermissionStatus> CheckStatusAsync();
    Task<PermissionStatus> RequestAsync();
}

그런 다음 플랫폼 프로젝트에 인터페이스를 구현합니다.

public class ReadWriteStoragePermission : Xamarin.Essentials.Permissions.BasePlatformPermission, IReadWritePermission
{
    public override (string androidPermission, bool isRuntime)[] RequiredPermissions => new List<(string androidPermission, bool isRuntime)>
    {
        (Android.Manifest.Permission.ReadExternalStorage, true),
        (Android.Manifest.Permission.WriteExternalStorage, true)
    }.ToArray();
}

그런 다음 특정 구현을 등록할 수 있습니다.

DependencyService.Register<IReadWritePermission, ReadWriteStoragePermission>();

그리고 공유 프로젝트에서 구현을 해결하고 사용할 수 있습니다.

var readWritePermission = DependencyService.Get<IReadWritePermission>();
var status = await readWritePermission.CheckStatusAsync();
if (status != PermissionStatus.Granted)
{
    status = await readWritePermission.RequestAsync();
}

플랫폼 구현 관련 정보

권한은 Android 매니페스트 파일에 일치하는 특성이 설정되어 있어야 합니다. 권한 상태의 기본값이 거부됨입니다.

자세한 내용은 Xamarin.Android 권한 설명서를 참조하세요.

API

Channel 9YouTube에서 더 많은 Xamarin 비디오를 확인하세요.