BuildVariants, ContentProvider и authorities (Android)

Имеем:

  • использование BuildVariants ( Build Types и/или Product Flavors) для создания разных версий приложения с одной кодовой базой (проектом)
  • использование ContentProvider (например, FileProvider или SuggestionsProvider), описанного в манифесте

Получаем:

При попытке установки 2-х разных версий приложения на одном устройстве получаем ошибку:


Причина

У ContentProvider есть атрибут authorities, который должен быть уникальным для всех установленных приложений на устройстве. Но при использовании BuildVariants этот уникальный идентификатор становится в системе уже “не таким уникальным”, как хотелось бы. Нужно это исправить.

Варианты решения проблемы:

1) в поле authorities можно добавить динамически формируемый идентификатор приложения ${applicationId}.

Допустим, в build.gradle у нас есть:

Теперь в манифесте у ContentProvider можно указать:

Для получения текущего идентификатора приложения в коде можно использовать автоматически генерируемую константу BuildConfig.APPLICATION_ID.

2) для каждого BuildVariant можно использовать (переопределить) свой файл манифеста.

Например:

  • /src/main/AndroidManifest.xml – манифест “по-умолчанию” (нужен обязательно)
  • /src/free/AndroidManifest.xml – для версии com.example.myapp.free
  • /src/pro/AndroidManifest.xml – для версии com.example.myapp.full

В каждом манифесте прописываем свой уникальный идентификатор  authoriries.


Примечание

Если в манифесте, кроме FileProvider, используется и SuggestionProvider (например, SearchRecentSuggestionsProvider), то его authorities тоже нужно сделать уникальным:

В коде:

При этом, в searchable.xml атрибут searchSuggestAuthority должен совпадать с атрибутом  authorities из манифеста. Но в нем нельзя использовать свойство ${applicationId}, т.к. это уже обычный ресурсный файл, а не файл манифеста или файл сборки проекта (типа build.gradle).

Для этого идентификаторы каждой версии приложения можно сохранить в виде строки в  отдельных  string.xml. Например, создать:

  • файл  /src/fre/res/values/string.xml со строкой:
  • файл  /src/pro/res/values/string.xml с аналогичной строкой, только с pro вместо free.

Файл  searchable.xml теперь должен выглядеть так:

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *