Как запросить разрешения у службы в Android Marshmallow

101

В Android Marshmallow разрешения следует запрашивать во время выполнения, когда они необходимы, а не все сразу при установке приложения. Однако я могу запрашивать разрешения только у Activity, что является проблемой, поскольку мое приложение содержит только Services. (Почему это так, вы можете спросить? В приложение встроен циферблат Android Wear, и все, что делает телефон, - это искать фотографии поблизости и отправлять их на часы - никаких действий не требуется. Но для этого требуется разрешение на определение местоположения.)

Итак, есть ли способ запросить разрешения у службы? Или как-то принудительно выдавать разрешения во время установки, как раньше?

Тони Уикхэм
источник
эта проблема также внутри класса Application
итжар
Попробуйте, это может быть работа stackoverflow.com/a/41221852/5488468
Бипин Бхарти
Моя библиотека позволяет легко обрабатывать разрешения времени выполнения из любого контекста, а также обрабатывает «Больше не спрашивать». github.com/nabinbhandari/Android-Permissions
Набин Бхандари

Ответы:

47

requestPermission()может вызываться только из, Activityа не из Service(в отличие от checkPermission()этого только требует PackageManager). Так что вам нужно проделать дополнительную работу, чтобы обойти это; вам нужно указать Activityв своем приложении, и, например, вы Serviceможете проверить необходимые разрешения, и если они еще не предоставлены, он может создать уведомление и сообщить пользователю короткое описательное сообщение о том, почему существует уведомление и что должно произойти, когда они нажимают на уведомление и т. д.

Али Наддаф
источник
Это решение, которое предложил Бенджамин Поеш . Вы можете слушать этот подкаст от 23:40
Xiaomi
Вы также можете вызвать requestPermission () внутри фрагмента.
Мисаг Эмамверди,
3
Каково решение в случае, если запущенная фоновая служба периодически проверяет наличие обновлений местоположения, и я просто отключил разрешение на определение местоположения в настройках. Поскольку нет активности, это приводит к сбою моей службы, когда я снова
открываю
1
@ stud91 По крайней мере, перехватывайте исключения безопасности или разрешения запросов каждый раз, когда вы запрашиваете обновления местоположения. Это предотвратит сбой вашего приложения (хотя вы не получите никаких местоположений, если разрешение было отозвано). Еще лучше: проверьте разрешение и, если оно отсутствует, отобразите уведомление, которое переводит пользователя в Activity, которая является просто заполнителем для диалогового окна разрешений.
user149408 09
8
Вот как я это решил: github.com/mvglasow/satstat/blob/master/src/com/vonglasow/… Его можно вызвать из любого, Contextкоторый также реализует OnRequestPermissionsResultCallback. Функциональность аналогична стандартной requestPermission().
user149408 09
15

Я согласен, это очень проблематично для служб, я думаю, вам следует сообщить о проблеме на странице предварительного просмотра Android Developer Preview.

На данный момент я думаю, что лучшим решением является проверка разрешения на сервис и отображение уведомления, если разрешение отсутствует. Более того, создайте DialogActivity для запроса разрешения, когда пользователи нажимают на уведомление.

Дерек Фанг
источник
7

Взгляните на библиотеку PermissionEverywhere . Это позволяет вам запрашивать разрешение из любого контекста.

Он создает уведомление, при нажатии на которое открывается действие, запрашивающее разрешение.

Пример кода со страницы библиотеки на github: -

@Override
  protected Boolean doInBackground(Void... params) {
      PermissionResponse response = PermissionEverywhere.getPermission(getApplicationContext(), 
      new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
              REQ_CODE,
              "Notification title", 
              "This app needs  a write permission", 
              R.mipmap.ic_launcher)
              .call();
      //waits..
      boolean isGranted = response.isGranted();

      if(isGranted){ //changed from isGrante to isGranted
      // Do stuff
      }
  }
Гейзенберг
источник
1
Я пробовал асинхронную версию в Сервисе, и это не сработало. onComplete никогда не
вызывается
Хорошая идея, но ее нет в репозитории
naXa 02
2
Этот пакет у меня сработал, спасибо за предложение. Однако отмечу, что асинхронную версию я не пробовал. Кроме того, для тех, у кого возникают проблемы с использованием PermissionEverywhere, убедитесь, что вы объявляете вспомогательную активность в своем манифесте И убедитесь, что при ее объявлении она привязана к правильному пакету (если вы используете PermissionEverywhereкак отдельный пакет). Мне потребовалось много времени, чтобы понять, что на самом деле я не указывал PermissionEverywhereпакет в манифесте.
user3570982
Я запустил PermissionEverywhereдемонстрационное приложение, но оно не сработало.
Ixx
3

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

Попробуйте: разрешения Android

Нишкарш
источник
-2

Вы можете использовать ResultReceiverдля создания получателя ответа пользователя, а затем передать его как обратный вызов Activity через уведомления PendingIntent. Ссылка

Фаррукс Баходиров
источник