page.title=Разрешения page.tags=previewresources, androidm page.keywords=разрешения, среда выполнения, предварительная версия page.image={@docRoot}preview/features/images/permissions_check.png @jd:body

Краткое описание

Содержание документа

  1. Обзор
  2. Добавление в код разрешений на выполнение
  3. Тестирование разрешений на выполнение
  4. Советы и рекомендации

В версии M Developer Preview представлена новая модель разрешений для приложений, которая оптимизирует для пользователей процесс установки и обновления приложений. Если приложение, работающее в M Preview, поддерживает новую модель разрешений, пользователю не нужно предоставлять какие-либо разрешения при установке приложения или его обновлении. Вместо этого приложение запрашивает разрешения, когда в них возникает необходимость, — в таких случаях система отображает для пользователя диалоговое окно с просьбой предоставить соответствующее разрешение.

Если приложение поддерживает новую модель разрешений, его, тем не менее, можно установить и запустить на устройстве под управлением одной из более ранних версий Android, и оно будет использовать старую модель разрешений.

Обзор

В версии M Developer Preview представлена новая модель разрешений. Ниже приводится краткий обзор ее ключевых компонентов:

Новая модель разрешений влияет на поведение приложений при работе с функциями, для которых требуются разрешения. При использовании этой модели в разработке обратите внимание на следующие рекомендации:

Примечание. Если приложение предназначено для M Developer Preview, оно должно в обязательном порядке использовать новую модель разрешений.

На момент выпуска M Developer Preview не все приложения Google в полной мере реализуют новую модель разрешений. Google обновляет эти приложения по мере разработки M Developer Preview, чтобы они должным образом поддерживали настройки разрешений.

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

Предоставление приложениям системных разрешений и подписи

Как правило, когда пользователь устанавливает приложение, система предоставляет такому приложению только те разрешения, которые соответствуют константе {@link android.content.pm.PermissionInfo#PROTECTION_NORMAL PROTECTION_NORMAL}. Однако в определенных ситуациях система предоставляет приложению больше разрешений:

В обоих случаях пользователь по-прежнему может в любое время отозвать разрешения, обратившись к экрану Настройки и выбрав Приложения > название_приложения > Разрешения. Поэтому приложение все равноу должно проверять наличие разрешений во время выполнения и при необходимости запрашивать их.

Совместимость с предыдущими и последующими версиями

Если приложение не предназначено для M Developer Preview, оно продолжает использовать старую модель разрешений даже на устройствах под управлением M Preview. В таком случае при установке приложения система предлагает пользователю предоставить все разрешения, указанные в манифесте приложения.

Примечание. На устройствах под управлением M Developer Preview пользователь может отключить разрешения для любого приложения (включая устаревшие приложения) на экране «Настройки». Если пользователь решит отключить разрешения для устаревших приложений, система автоматически отключит соответствующие функциональные возможности. Когда приложение пытается выполнить операцию, для которой требуется такое разрешение, это не обязательно приведет к возникновению исключения. Вместо этого оно может выдать пустой набор данных, сигнал об ошибке или иным образом обозначить непредвиденное поведение. Например, если запросить календарь, не имея соответствующего разрешения, метод возвратит пустой набор данных.

При установке приложения с использованием новой модели разрешений на устройство под управлением другой версии ОС, отличной от M Preview, система рассматривает такое приложение как любое другое и предлагает пользователю предоставить все объявленные разрешения уже во время установки.

Примечание. В случае с предварительной версией в качестве минимальной версии пакета SDK следует задать версию SDK M Preview, чтобы получить возможность компилировать код с помощью пакета SDK предварительной версии. Это означает, что вы не сможете протестировать такие приложения на старых платформах во время использования предварительной версии для разработчиков.

Разрешения и намерения

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

Например, предположим, что вашему приложению требуется возможность делать снимки с помощью камеры устройства. Ваше приложение может запросить разрешение android.permission.CAMERA, которое позволит ему напрямую получить доступ к камере. Затем ваше приложение использует API-интерфейсы камеры для управления камерой и получения снимков. Благодаря такому подходу ваше приложение получает полный контроль над процессом фотографирования. Кроме того, это позволяет вам вставить пользовательский интерфейс камеры в свое приложение.

Если же вам не требуется такой контроль, просто воспользуйтесь намерением {@link android.provider.MediaStore#ACTION_IMAGE_CAPTURE ACTION_IMAGE_CAPTURE} для запроса изображения. Когда вы запускаете намерение, пользователю предлагается выбрать приложение камеры (если оно отличается от приложения камеры по умолчанию), после чего это приложение делает снимок. Приложение камеры возвращает полученное изображение в метод {@link android.app.Activity#onActivityResult onActivityResult()} вашего приложения.

Аналогичным образом, если вам необходимо позвонить, получить доступ к контактам пользователя и так далее, можно создать соответствующее намерение или запросить разрешение и напрямую получить доступ к нужным объектам. У каждого подхода есть как преимущества, так и недостатки.

При использовании разрешений:

При использовании намерений:

Добавление в код разрешений на выполнение

Если ваше приложение предназначено для новой версии M Developer Preview, вы должны в обязательном порядке использовать новую модель разрешений. Это означает, что кроме объявления требуемых разрешений в манифесте, вам следует проверять наличие этих разрешений во время выполнения, а также запрашивать их, если у вас еще нет необходимых разрешений.

Активация новой модели разрешений

Чтобы активировать новую модель разрешений M Developer Preview, задайте для атрибута targetSdkVersion приложения значение "MNC", а для атрибута compileSdkVersion – значение "android-MNC". Это позволит включить все функции новой модели разрешений.

В случае с предварительной версией необходимо задать для параметра minSdkVersion значение "MNC", чтобы получить возможность компилировать код с помощью пакета SDK предварительной версии.

Назначение разрешений только для M Preview

В манифесте приложения можно использовать новый элемент <uses-permission-sdk-m>, чтобы указать, что разрешение требуется только для M Developer Preview. Если объявить разрешение таким способом, то при установке приложения на устройство с более старой версией платформы система не будет отправлять запрос пользователю или предоставлять разрешение приложению. С помощью элемента <uses-permission-sdk-m> вы можете добавлять новые разрешения в обновленные версии вашего приложения без принудительного запроса у пользователей разрешений при установке обновления.

Если приложение запущено на устройстве под управлением M Developer Preview, поведение элемента <uses-permission-sdk-m> аналогично поведению <uses-permission>. Система не запрашивает у пользователей предоставление каких-либо разрешений, когда они устанавливают приложение. Вместо этого приложение само запрашивает разрешения, когда они требуются.

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

Если ваше приложение использует новую модель разрешений M Developer Preview, то при первом запуске приложения на устройстве под управлением M Preview пользователю не предлагается предоставить все разрешения. Вместо этого приложение само запрашивает разрешения, когда они требуются. Когда приложение запрашивает разрешение, система отображает для пользователя соответствующее диалоговое окно.

Если ваше приложение запущено на устройстве с пакетом SDK уровня 22 или более низкого, то приложение использует старую модель разрешений. То есть при каждой устновке приложения пользователю будет предложено предоставить приложению все разрешения, запрашиваемые в манифесте приложения, кроме отмеченных элементом <uses-permission-sdk-m>.

Проверка платформы, на которой выполняется приложение

Новая модель разрешений поддерживается только на устройствах под управлением M Developer Preview. Прежде чем вызывать любые из этих методов, приложению следует проверить, на какой платформе оно выполняется, обратившись к значению параметра {@link android.os.Build.VERSION#CODENAME Build.VERSION.CODENAME}. Если устройство работает под управлением M Developer Preview, то значение параметра{@link android.os.Build.VERSION#CODENAME CODENAME} будет "MNC".

Проверка наличия у приложения необходимого разрешения

Когда пользователи пытаются выполнить какое-либо действие, для которого требуется разрешение, приложение проверяет, имеется ли у него в настоящее время разрешение на выполнение этой операции. Для этого приложение вызывает метод Context.checkSelfPermission(permission_name). Приложению следует выполнять такую проверку даже в том случае, если ему известно, что пользователь уже предоставил необходимое разрешение, поскольку пользователь может в любое время отозвать разрешения приложения. Например, если пользователь хочет получить снимок с помощью приложения, то приложение вызывает метод Context.checkSelfPermission(Manifest.permission.CAMERA).

Таблица 1. Разрешения и группы разрешений.

Группа разрешений Разрешения
android.permission-group.CALENDAR
  • android.permission.READ_CALENDAR
  • android.permission.WRITE_CALENDAR
android.permission-group.CAMERA
  • android.permission.CAMERA
android.permission-group.CONTACTS
  • android.permission.READ_CONTACTS
  • android.permission.WRITE_CONTACTS
  • android.permission.READ_PROFILE
  • android.permission.WRITE_PROFILE
android.permission-group.LOCATION
  • android.permission.ACCESS_FINE_LOCATION
  • android.permission.ACCESS_COARSE_LOCATION
android.permission-group.MICROPHONE
  • android.permission.RECORD_AUDIO
android.permission-group.PHONE
  • android.permission.READ_PHONE_STATE
  • android.permission.CALL_PHONE
  • android.permission.READ_CALL_LOG
  • android.permission.WRITE_CALL_LOG
  • com.android.voicemail.permission.ADD_VOICEMAIL
  • android.permission.USE_SIP
  • android.permission.PROCESS_OUTGOING_CALLS
android.permission-group.SENSORS
  • android.permission.BODY_SENSORS
  • android.permission.USE_FINGERPRINT
android.permission-group.SMS
  • android.permission.SEND_SMS
  • android.permission.RECEIVE_SMS
  • android.permission.READ_SMS
  • android.permission.RECEIVE_WAP_PUSH
  • android.permission.RECEIVE_MMS
  • android.permission.READ_CELL_BROADCASTS

Запрос разрешений при необходимости

Если у приложения нет требуемого разрешения, оно вызывает метод Activity.requestPermissions(String[], int), чтобы запросить его. Приложение передает в него требуемые разрешения, а также целочисленный код запроса. Этот метод выполняется асинхронно: он возвращает результат сразу же, а после того как пользователь предоставляет ответ в диалоговом окне, система вызывает метод обратного вызова приложения с результатами и передает в него тот же код запроса, который приложение передало в метод requestPermissions().

Ниже представлен пример кода для проверки наличия у приложения разрешения на чтение контактов пользователя и запроса соответствующего разрешения при необходимости.

if (checkSelfPermission(Manifest.permission.READ_CONTACTS)
        != PackageManager.PERMISSION_GRANTED) {
    requestPermissions(new String[]{Manifest.permission.READ_CONTACTS},
            MY_PERMISSIONS_REQUEST_READ_CONTACTS);

    // MY_PERMISSIONS_REQUEST_READ_CONTACTS is an
    // app-defined int constant

    return;
}

Обработка ответа на запрос разрешений

Когда приложение запрашивает разрешения, система отображает для пользователя соответствующее диалоговое окно. После получения ответа от пользователя система вызывает метод Activity.onRequestPermissionsResult(int, String[], int[]) вашего приложения и передает в него ответ пользователя. Вашему приложению необходимо переопределить этот метод. В обратном вызове передается тот же код запроса, который вы передали в метод requestPermissions(). Например, если приложение запрашивает доступ на READ_CONTACTS, то метод обратного вызова может быть следующим:

@Override
public void onRequestPermissionsResult(int requestCode,
        String permissions[], int[] grantResults) {
    switch (requestCode) {
        case MY_PERMISSIONS_REQUEST_READ_CONTACTS: {
            if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {

                // permission was granted, yay! do the
                // calendar task you need to do.

            } else {

                // permission denied, boo! Disable the
                // functionality that depends on this permission.
            }
            return;
        }

        // other 'switch' lines to check for other
        // permissions this app might request
    }
}

Если пользователь предоставляет разрешение, система, в свою очередь, представляет все разрешения, запрашиваемые в манифесте приложения для обозначенной функциональной области. Если пользователь отказывает в предоставлении разрешения, вам необходимо принять меры. Например, вы можете отключить любые пункты меню , для использования которых требуется это разрешение.

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

Тестирование разрешений на выполнение

Если ваше приложение предназначено для новой версии M Developer Preview, то вы должны протестировать его и убедиться в том, что оно должным образом обрабатывает разрешения. Не надо исходить из того, что к началу работы ваше приложение уже имеет любые определенные разрешения. При первом запуске приложения оно, скорее всего, не будет обладать разрешениями, а в дальнейшем пользователь может в любой момент отозвать или восстановить разрешения.

Вам следует протестировать ваше приложение и убедиться в том, что оно ведет себя должным образом в любых ситуациях, касающихся разрешений. Мы включили в состав пакета SDK M Preview SDK новые команды Android Debug Bridge (ADB), чтобы вы могли протестировать ваше приложение с любыми настройками разрешений, которые вы хотите попробовать в действии.

Новые команды и параметры ADB

В состав пакета инструментов SDK M Preview входит ряд новых команд, позволяющих протестировать обработку разрешений вашим приложением.

Установка с разрешениями

Можно воспользоваться новым параметром -g команды adb install, который служит для установки приложения и предоставления всех разрешений, указанных в его манифесте:

$ adb install -g <path_to_apk>

Предоставление разрешений и их отзыв

Для предоставления разрешений установленному приложению и их отзыва можно использовать новые команды диспетчера пакетов ADB. Такая функциональная возможность может быть полезна для автоматизированного тестирования.

Для представления разрешения используйте команду grant диспетчера пакетов:

$ adb pm grant <package_name> <permission_name>

Например, чтобы представить пакету com.example.myapp разрешение на запись аудио, воспользуйтесь следующей командой:

$ adb pm grant com.example.myapp android.permission.RECORD_AUDIO

Чтобы отозвать разрешение, используйте команду revoke диспетчера пакетов:

$ adb pm revoke <package_name> <permission_name>

Советы и рекомендации

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

Запрашивайте только те разрешения, которые необходимы

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

Например, во многих случаях можно предоставить приложению доступ к нужной функции посредством намерения вместо запроса разрешений. Если вашему приложению необходимо получить снимки с камеры телефона, можно использовать намерение {@link android.provider.MediaStore#ACTION_IMAGE_CAPTURE MediaStore.ACTION_IMAGE_CAPTURE}. Когда ваше приложение выполняет намерение, система предлагает пользователю выбрать уже установленное приложение камеры для получения снимков.

Не перегружайте пользователя запросами

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

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

Если в вашем приложении имеются обучающие материалы, может оказаться целесообразным запросить необходимые разрешения после того, как пользователь изучит материалы.

Всегда поясняйте, для чего требуются те или иные разрешения

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

Например, приложению для фотографирования может потребоваться доступ к службам геолокации, чтобы фотографии можно было снабдить геотегами. Не все пользователи знают, что фотография может содержать данные о месте съемки, и им может показаться странным, что приложение для фотографирования запрашивает данные о местоположении. В этом случае полезно рассказать пользователю о такой возможности, прежде чем вызывать метод requestPermissions().

Это можно сделать, в частности, внедрив такие запросы в обучающие материалы приложения. В обучающих материалах могут содержаться описания каждой из функций приложения с пояснением, какие разрешения необходимы для их использования. Например, в обучающий материал по работе с приложением для фотографирования можно включить описание функции обмена контентом с контактами, после чего пояснить, что для этого пользователю следует предоставить приложению доступ к его контактам. После этого приложение может вызвать метод requestPermissions() для запроса доступа. Конечно, не все пользователи обращаются к обучающим материалам, поэтому вам по-прежнему следует проверять наличие разрешений и при необходимости запрашивать их во время обычной работы приложения.