Intereting Posts
Сделать DatePicker и TimePicker меньше Как создать новый проект Android в eclipse и поделиться им в локальном репозитории git? Андроид не может найти класс из внешней банки Не удалось решить: android.arch.lifecycle: extensions: 1.0.0-alpha1 android studio 3.0 Доступ к локальному ПК ПК с подключенного к USB-мобильному устройству Android Java.lang.RuntimeException: не удается создать обработчик внутри потока, который не вызвал Looper.prepare () Android BluetoothSocket.isConnected всегда возвращает false Вычислить расстояние между устройством Bluetooth в android Android InApp Billing: запрашиваемый вами товар недоступен для покупки. Несогласованность в разных учетных записях google Единичный тест Класс Java, который загружает собственную библиотеку Начать новую активность без анимации перехода в android 1.6 Как сделать веб-сервис ASP.NET Web API доступным в локальной сети Вход в Facebook NullPointerException Import com.google.android.gms.common.api.GoogleApiClient; не может быть решен FFMpeg Android Stagefright SIGSEGV ошибка (декодирование h264)

Пользовательские разрешения Android – Marshmallow

Задний план

Исторически, пользовательские разрешения Android были беспорядком и были зависимыми от порядка установки , которые, как известно, подвергли уязвимости .

До API 21 было нерегулярное временное решение, в котором объявлялось пользовательское разрешение другого приложения в манифесте, предоставлялось разрешение … Однако, поскольку API 21, только одно приложение может объявлять пользовательское разрешение и устанавливать другое заявление, объявляющее Это же разрешение будет предотвращено.

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

проблема

Начиная с Android Marshmallow (6.0 – API 23), приложение должно запросить разрешение от пользователя, чтобы использовать его собственное пользовательское разрешение . Заявленное пользовательское разрешение не предоставляется автоматически.

Это кажется странным, учитывая, что только одно приложение может его объявить.

Повторить

Объявите пользовательское разрешение и BroadcastReceiver в манифесте.

<permission android:name="com.example.app.permission.CONTROL_EXAMPLE_APP" android:description="@string/control_description" android:icon="@mipmap/ic_launcher" android:label="@string/control_label" android:protectionLevel="normal or dangerous"/> <uses-permission android:name="com.example.app.permission.CONTROL_EXAMPLE_APP"/> // etc <receiver android:name="com.example.app.MyBroadcastReceiver" android:permission="com.example.app.permission.CONTROL_EXAMPLE_APP"> <intent-filter android:priority="999"> <action android:name="com.example.app.REQUEST_RECEIVER"/> </intent-filter> </receiver> 

Из стороннего приложения объявите, что он использует пользовательские разрешения в манифесте (и принимает его через диалог или настройки) и вызывает:

  final Intent intent = new Intent("com.example.app.REQUEST_RECEIVER"); context.sendOrderedBroadcast(intent, "com.example.app.permission.CONTROL_EXAMPLE_APP", new BroadcastReceiver() { @Override public void onReceive(final Context context, final Intent intent) { // getResultCode(); } }, null, Activity.RESULT_CANCELED, null, null); 

Результат вернет CANCELED, и журнал покажет:

System_process W / BroadcastQueue: отказ в доступе: получение намерения {act = com.example.app.REQUEST_RECEIVER flg = 0x10 (имеет дополнительные функции)} to com.example.app/.MyBroadcastReceiver требует com.example.app.permission.CONTROL_EXAMPLE_APP из-за отправителя com.example.thirdparty

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

Вопрос

Это ожидаемое поведение? Или я почему-то что-то упустил?

Казалось бы, смешно поднимать диалог, говорящий

Приложение примера приложения хочет получить разрешение на использование приложения «Пример»

И это действительно может касаться пользователя, предоставляя им такую ​​бессмысленную просьбу.

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

Заметка

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

Спасибо, что прочитали это.

Изменить: Чтобы уточнить, для других реализаций, таких как объявление разрешения на службу (которая была бы наиболее простой для репликации), объявленное пользовательское разрешение автоматически предоставляется.

Solutions Collecting From Web of "Пользовательские разрешения Android – Marshmallow"

Как я понял, вы пытались сделать следующее (по крайней мере, так я смог воспроизвести вашу проблему):

  1. Вы сначала объявляете свое новое пользовательское разрешение (разрешаете его F)

     <permission android:name="com.example.app.permission.CONTROL_EXAMPLE_APP" android:description="@string/control_description" android:icon="@mipmap/ic_launcher" android:label="@string/control_label" android:protectionLevel="normal or dangerous"/> 
  2. Вы определяете, что ваше приложение F использует разрешение com.example.app.permission.CONTROL_EXAMPLE_APP . Это правильно, как говорится в руководстве.

     <uses-permission android:name="com.example.app.permission.CONTROL_EXAMPLE_APP"/> 
  3. Вы объявляете свой собственный широковещательный приемник в своем приложении F. Чтобы общаться с этой трансляцией вашего приложения (независимо от того, какой из них, F или другое приложение), вы должны получить свое пользовательское разрешение

     <receiver android:name="com.example.app.MyBroadcastReceiver" android:permission="com.example.app.permission.CONTROL_EXAMPLE_APP"> <intent-filter android:priority="999"> <action android:name="com.example.app.REQUEST_RECEIVER"/> </intent-filter> </receiver> 
  4. Вы определяете, что вы используете второе (разрешает вызов S) приложение использует разрешение com.example.app.permission.CONTROL_EXAMPLE_APP . Поскольку вы хотите разрешить S-приложению отправлять широковещательные сообщения в приемник F-приложений.

     <uses-permission android:name="com.example.app.permission.CONTROL_EXAMPLE_APP"/> 
  5. Наконец, вы пытаетесь отправить широковещательное сообщение из своего S-приложения, используя этот код.

     final Intent intent = new Intent("com.example.app.REQUEST_RECEIVER"); context.sendOrderedBroadcast(intent, "com.example.app.permission.CONTROL_EXAMPLE_APP", new BroadcastReceiver() { @Override public void onReceive(final Context context, final Intent intent) { // getResultCode(); } }, null, Activity.RESULT_CANCELED, null, null); 

    И это важно , вы предоставили разрешение своему S-приложению, но вы не предоставили разрешение своему F-приложению.

    В результате ваш вещательный приемник, объявленный в приложении F, ничего не получил.

  6. После того, как вы предоставили разрешение своему F-приложению (обратите внимание, что теперь S и F предоставили ваше пользовательское разрешение) все работает нормально. Широковещательный приемник, объявленный в приложении F, получил сообщение из приложения S.

Я думаю, это правильное поведение, потому что этот документ говорит нам:

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

И приложение, объявляющее разрешение, также должно запрашивать одно и то же разрешение для связи с самим собой.

Как результат, API-интерфейс Android 23 должен сначала получить доступ к использованию вашей формы разрешения. И мы должны получить 2 предоставленных разрешения, сначала из F-приложения (потому что guidline говорит как это), и второе из S-приложения (потому что нам просто нужно получить доступ).

Но я не поймал ваш следующий момент:

Казалось бы, смешно поднимать диалог, говорящий

Приложение примера приложения хочет получить разрешение на использование приложения «Пример»

Мой родной Android API 23 показывает мне что-то вроде этого:

Приложение приложения App хочет

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

Эта часть требует, чтобы приложение com.example.thirdparty имело разрешение:

 <receiver android:name="com.example.app.MyBroadcastReceiver" android:permission="com.example.app.permission.CONTROL_EXAMPLE_APP"> 

И эта часть требует, чтобы приложение com.example.app также имело разрешение:

 context.sendOrderedBroadcast(intent, "com.example.app.permission.CONTROL_EXAMPLE_APP", ... 

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

 <service android:name="com.example.app.MyService" android:permission="com.example.app.permission.CONTROL_EXAMPLE_APP"> 

И затем привяжите его следующим образом:

 context.bindService(serviceIntent, mServiceConnection, ... 

То этого достаточно, если com.example.thirdparty имеет предоставленное разрешение, в то время как com.example.app не нужно его иметь.

Другими словами, я думаю, что это поведение по дизайну, и разница, которую вы видите между поведением Broadcast и Service, заключается в том, что в случае Broadcast вы специально запрашиваете, чтобы com.example.app пользовался специальным разрешением, тогда как в Служебном случае вы нет.

Надеюсь, я не понял вашу проблему неправильно. Если да, сообщите мне, и я удалю этот ответ.

Я не думаю, что полностью верно, что заявленное пользовательское разрешение не будет автоматически предоставлено приложению. Если пользовательское разрешение имеет уровень защиты «обычный» или «подпись», то разрешение предоставляется во время установки. В противном случае, если уровень защиты «опасный», то это разрешение времени выполнения, и оно работает так же, как и другие опасные разрешения: вам нужно будет предложить пользователю предоставить разрешение на приложение.

Хотя для пользователя может быть неоднозначным видеть запрос на разрешение для приложения, которое объявлено в том же приложении, это то, как андроид предназначен для работы с зефира. Я думаю, что на взгляд андроид поведение по-своему и правильно.

Сначала добавьте разрешения в файл манифеста после

  <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />