Разрешения в Xamarin.Android

Обзор

Приложения Android выполняются в собственной песочнице и по соображениям безопасности не имеют доступа к определенным системным ресурсам или оборудованию на устройстве. Пользователь должен явно предоставить приложению разрешение, прежде чем он сможет использовать эти ресурсы. Например, приложение не может получить доступ к GPS на устройстве без явного разрешения от пользователя. Android создает исключение Java.Lang.SecurityException , если приложение пытается получить доступ к защищенному ресурсу без разрешения.

Разрешения объявляются в AndroidManifest.xml разработчиком приложений при разработке приложения. Android имеет два разных рабочего процесса для получения согласия пользователя на эти разрешения:

  • Для приложений, предназначенных для Android 5.1 (уровень API 22) или ниже, запрос на разрешение произошел при установке приложения. Если пользователь не предоставил разрешения, приложение не будет установлено. После установки приложения нет способа отмены разрешений, кроме удаления приложения.
  • Начиная с Android 6.0 (уровень API 23), пользователи получили больше контроля над разрешениями; они могут предоставлять или отзывать разрешения до тех пор, пока приложение установлено на устройстве. На снимках экрана показаны параметры разрешений для приложения "Контакты Google". Он содержит различные разрешения и позволяет пользователю включать или отключать разрешения:

Sample Permissions screen

Приложения Android должны проверка во время выполнения, чтобы узнать, есть ли у них разрешение на доступ к защищенному ресурсу. Если у приложения нет разрешений, он должен выполнять запросы с помощью новых API, предоставляемых пакетом SDK для Android, чтобы пользователь предоставил разрешения. Разрешения делятся на две категории:

  • Обычные разрешения — это разрешения, которые представляют мало риска для безопасности пользователя или конфиденциальности. Android 6.0 автоматически предоставляет обычные разрешения во время установки. Ознакомьтесь с документацией по Android, чтобы получить полный список обычных разрешений.
  • Опасные разрешения. В отличие от обычных разрешений, опасные разрешения — это те, которые защищают безопасность или конфиденциальность пользователя. Они должны быть явно предоставлены пользователем. Отправка или получение SMS-сообщения является примером действия, требующего опасного разрешения.

Внимание

Категория, к которой принадлежит разрешение, может меняться с течением времени. Возможно, разрешение, которое было классифицировано как "обычное" разрешение может быть повышено в будущих уровнях API до опасного разрешения.

Опасные разрешения делятся на группы разрешений. Группа разрешений будет содержать разрешения, которые логически связаны. Когда пользователь предоставляет разрешение одному участнику группы разрешений, Android автоматически предоставляет разрешение всем членам этой группы. Например, группа разрешений содержит как разрешения, STORAGE так WRITE_EXTERNAL_STORAGE и READ_EXTERNAL_STORAGE разрешения. Если пользователь предоставляет разрешение READ_EXTERNAL_STORAGE, то WRITE_EXTERNAL_STORAGE разрешение автоматически предоставляется одновременно.

Перед запросом одного или нескольких разрешений рекомендуется указать, почему приложению требуется разрешение перед запросом разрешения. Когда пользователь понимает обоснование, приложение может запросить разрешение от пользователя. Понимая обоснование, пользователь может принять обоснованное решение, если они хотят предоставить разрешение и понять последствия, если они этого не делают.

Весь рабочий процесс проверка и запроса разрешений называется разрешениями во время выполнения проверка и может быть обобщен на следующей схеме:

Run-time permission check flow chart

Библиотека поддержки Android поддерживает некоторые из новых API-интерфейсов для разрешений на более старые версии Android. Эти поддерживаемые API автоматически проверка версию Android на устройстве, поэтому не требуется выполнять уровень API проверка каждый раз.

В этом документе описано, как добавить разрешения в приложение Xamarin.Android и как приложения, предназначенные для Android 6.0 (уровень API 23) или более поздней версии, должны выполнять разрешения во время выполнения проверка.

Примечание.

Возможно, разрешения на оборудование могут повлиять на фильтрацию приложения с помощью Google Play. Например, если приложению требуется разрешение для камеры, Google Play не будет отображать приложение в Google Play Store на устройстве, на котором не установлена камера.

Требования

Настоятельно рекомендуется, чтобы проекты Xamarin.Android включали пакет NuGet Xamarin.Android.Support.Compat . Этот пакет будет возвращать определенные API-интерфейсы для более старых версий Android, предоставляя один общий интерфейс без необходимости постоянно проверка версию Android, на которую работает приложение.

Запрос разрешений системы

Первым шагом в работе с разрешениями Android является объявление разрешений в файле манифеста Android. Это необходимо сделать независимо от уровня API, на который нацелено приложение.

Приложения, предназначенные для Android 6.0 или более поздней версии, не могут предположить, что, так как пользователь предоставил разрешение в какой-то момент в прошлом, что разрешение будет действительным в следующий раз. Приложение, предназначенное для Android 6.0, всегда должно выполнять разрешения среды выполнения проверка. Приложения, предназначенные для Android 5.1 или более поздней версии, не должны выполнять разрешения во время выполнения проверка.

Примечание.

Приложения должны запрашивать только необходимые разрешения.

Объявление разрешений в манифесте

Разрешения добавляются в AndroidManifest.xml с элементом uses-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 о результатах.
  • разрешения — список запрошенных разрешений.
  • requestCode — целочисленное значение, которое используется для сопоставления результатов запроса разрешения на RequestPermissions вызов. Значение должно быть больше нуля.

Этот фрагмент кода является примером двух методов, которые были рассмотрены. Во-первых, выполняется проверка, чтобы определить, следует ли отображать обоснование разрешения. Если будет показано обоснование, то с помощью логики отображается панель закусок. Если пользователь нажимает кнопку "ОК " на панели "Закуска", приложение запрашивает разрешения. Если пользователь не принимает обоснование, приложение не должно продолжать запрашивать разрешения. Если обоснование не отображается, действие запросит разрешение:

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 вызове элемент управления передается операционной системе, который будет отображать пользовательский интерфейс для принятия разрешений:

Permssion Dialog

После завершения работы пользователя Android вернет результаты в действие с помощью метода OnRequestPermissionResultобратного вызова. Этот метод является частью интерфейса ActivityCompat.IOnRequestPermissionsResultCallback , который должен быть реализован действием. Этот интерфейс имеет один метод, OnRequestPermissionsResultкоторый будет вызываться Android для информирования о действии выбора пользователя. Если пользователь предоставил разрешение, приложение может перейти к использованию защищенного ресурса. Ниже показан пример реализации 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.