Отказ в разрешении Android, если другое приложение не установлено первым

#android #permissions

#Android #разрешения

Вопрос:

Я пытаюсь прочитать содержимое с помощью курсора следующим образом:

 cursor = context.getContentResolver().query(TASKS_URI, null, null, new String[]{"-1", "true"}, null);
  

Где TASKS_URI:

 private final static Uri TASKS_URI = Uri.parse("content://org.dayup.gtask.data/tasks");
  

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

В моем manifest.xml я определяю свое разрешение как:

    <uses-permission android:name="org.dayup.gtask.permission.READ_TASKS"/>
  

Проблема в том, что если мое приложение было установлено раньше другого приложения (в данном случае gtask), я получаю следующую ошибку:

 05-08 15:26:45.380: ERROR/ActivityThread(18564): Failed to find provider info for org.dayup.gtask.key
05-08 15:26:45.390: ERROR/AndroidRuntime(18509): FATAL EXCEPTION: Thread-12
java.lang.SecurityException: Permission Denial: reading org.dayup.gtask.GoogleTaskProvider uri content://org.dayup.gtask.data/tasks from pid=18509, uid=10114 requires org.dayup.gtask.permission.READ_TASKS
at android.os.Parcel.readException(Parcel.java:1322)
at android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.java:160)
at android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.java:114)
at android.content.ContentProviderProxy.bulkQueryInternal(ContentProviderNative.java:372)
at android.content.ContentProviderProxy.query(ContentProviderNative.java:408)
at android.content.ContentResolver.query(ContentResolver.java:264)
  

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

Комментарии:

1. Можете ли вы использовать android: required = «false» для разрешений или это только функции?

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

3. Привет, вам удалось заставить его работать на более новых версиях Android? Используя предложенный вами взлом, невозможно установить другое приложение из-за дублирования определений разрешений.

Ответ №1:

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

Вот пример:

 <uses-permission android:name="com.timsu.astrid.permission.READ_TASKS" />
<permission android:name="com.timsu.astrid.permission.READ_TASKS"
    android:permissionGroup="android.permission-group.PERSONAL_INFO"
    android:protectionLevel="dangerous" android:label="read astrid tasks data" />
<uses-permission android:name="android.permission.CHANGE_COMPONENT_ENABLED_STATE" />
<!-- dato gtask -->
<uses-permission android:name="org.dayup.gtask.permission.READ_TASKS" />
<permission android:name="org.dayup.gtask.permission.READ_TASKS"
    android:permissionGroup="android.permission-group.PERSONAL_INFO"
    android:protectionLevel="dangerous" android:label="read dato gtasks tasks data" />
  

Комментарии:

1. Увы, это больше не работает с Lollipop и вызывает собственное исключение, когда два приложения определяют одно и то же разрешение.

Ответ №2:

На странице безопасности Android указано

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

поэтому я не думаю, что вы можете изменить разрешения во время выполнения. Единственный способ, который я вижу, чтобы обойти это, — это иметь своего рода приложение-оболочку с android.permission.INSTALL_PACKAGES набором, которое проверяет наличие требуемого приложения и устанавливает его перед установкой вашего.