Фон
Исторически, пользовательские разрешения 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: отказ в разрешении: получение Intent { 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()
, чтобы позволить пользователю принять разрешение, приемник, как и следовало ожидать, работает правильно.
Вопрос
Является ли это ожидаемым поведением? Или я почему-то не заметил чего-то?
Казалось бы, смешно поднимать диалог, говорящий
Приложение Пример приложения хочет получить разрешение на использование примера App
И это действительно может касаться пользователя, предоставляя им такой бессмысленный запрос.
Я могу, конечно, изменить описание и имя разрешений на то, что они будут принимать, например, "общаться с другими установленными приложениями", но прежде чем вздохнуть и принять такой подход, я подумал, что задаю этот вопрос.
Примечание
Пример упорядоченной передачи - это репликация проблемы. Мое приложение использует другие реализации поставщиков контента и связанную службу. Это не альтернативная реализация, которую я требую, это подтверждение проблемы.
Благодарим за то, что вы читаете это.
Изменить: Чтобы уточнить, для других реализаций, таких как объявление разрешения на службу (которое было бы наиболее простым для репликации), автоматически предоставляется объявленное пользовательское разрешение.