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

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

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

RxPermissions

RxPermissions — это библиотека, которая позволяет использовать RxJava с моделью разрешений Android Marshmallow. Прежде чем углубиться в работу с этой библиотекой, рекомендую ознакомиться с основами Rx. Для тех, кто предпочитает не использовать Rx, существует несколько других хороших вариантов:

  • Dexter: библиотека Android, которая упрощает процесс запроса разрешений во время выполнения;
  • Easypermissions: библиотека-оболочка для упрощения базовой логики системных разрешений при таргетинге на Android M или выше;
  • PermissionsDispatcher: предоставляет простой API на основе аннотаций для обработки разрешений среды выполнения.

Цель использования этих библиотек — сохранить чистоту и безопасность нашего кода. С их помощью мы можем сократить количество строк шаблонного кода. А теперь давайте начнем углубленное знакомство с библиотекой RxPermissions.

Подробное руководство

Чтобы разобраться как можно лучше, давайте пройдем весь путь по шагам. Для использования этой библиотеки ваша версия SDK должна быть как минимум >= 11.

Шаг 1: Добавляем зависимости

В корень или в build.gradle на уровне проекта добавьте:

projects {
    repositories {
        ...
        maven { url 'https://jitpack.io' }
    }
}

Далее добавьте зависимость RxPermission в build.gradle на уровне приложения:

dependencies {
    //Rx   
    implementation 'io.reactivex.rxjava2:rxjava:2.2.12'
    implementation 'io.reactivex.rxjava2:rxandroid:2.1.1'
    implementation 
'com.github.tbruyelle:rxpermissions:0.10.2'

}

Шаг 2: Инициализируем RxPermissions

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

// Здесь находится экземпляр активности или фрагмента
val rxPermissions = RxPermissions(this)

Примечание: При инициализации RxPermission внутри фрагмента в качестве параметра конструктора нужно передать экземпляр фрагмента new RxPermissions(this), а не new RxPermissions(fragment.getActivity()). В противном случае можно столкнуться с исключением “java.lang.IllegalStateException: FragmentManager is already executing transactions”.

Шаг 3. Используем для запроса разрешения

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

rxPermissions
    .request(Manifest.permission.CAMERA,
             Manifest.permission.READ_PHONE_STATE)
    .subscribe(granted -> {
        if (granted) {
           // Все запрошенные разрешения предоставлены
        } else {
           // Как минимум один запрос разрешения отклонен
        }
    });

Разве это не проще, чем использовать дополнительные классы и методы? Мы можем легко обработать результат и, основываясь на выходных данных, выполнять нужные нам действия. Например, выполнить что-либо при получении разрешения и нажать на “Больше не показывать этот диалог», чтобы перейти на страницу настроек, и так далее.

Шаг 4. Запрос группы разрешений

Мы также можем запросить группу разрешений и получить результат каждого запроса по отдельности или в группе, как показано ниже.

Получение индивидуального результата:

private fun requestPermissionsStorage() {
        // Должно быть выполнено во время фазы инициализации, например onCreate
        rxPermissions?.requestEach(Manifest.permission.READ_EXTERNAL_STORAGE)
            ?.subscribe { permission: Permission ->
                // Будут произведены два объекта Permission
                if (permission.granted) {
                    // `permission.name` получено!
                    showToast(1)
                } else if (permission.shouldShowRequestPermissionRationale) {
                    // Запрос разрешения отклонен без указания "никогда больше не спрашивать"
                    showToast(2)
                } else { // Запрос разрешения отклонен с указанием "никогда больше не спрашивать"
                    // Необходимо перейти в настройки
                    showToast(3)
                }
            }
    }

Получение группового результата:

rxPermissions
    .requestEachCombined(Manifest.permission.CAMERA,
             Manifest.permission.READ_PHONE_STATE)
    .subscribe(permission -> { // будет произведен 1 объект Permission
        if (permission.granted) {
           // Все разрешения получены!
        } else if (permission.shouldShowRequestPermissionRationale)
           // По меньшей мере один запрос разрешения отклонен без указания "никогда больше не спрашивать"
        } else {
           // По меньшей мере один запрос разрешения отклонен с указанием "никогда больше не спрашивать"
           // Необходимо перейти в настройки
        }
    });

Вот и все! Надеюсь, эта статья оказалась для вас полезной.

Читайте также:

Читайте нас в Telegram, VK и Яндекс.Дзен


Перевод статьи Satya Pavan Kantamani: “RxPermissions: The easiest way to Handle Android M Permissions”

Предыдущая статьяРазработка и развёртывание приложения машинного обучения: полное руководство
Следующая статьяФункции Java 15: скрытые и запечатанные классы, сопоставление шаблонов и текстовые блоки