Подтвердить что ты не робот

Android - наличие полномочий поставщика в проекте приложения

Проект библиотеки андроида содержит несколько поставщиков, полномочия которых определены в классе контрактов:

public static final String CONTENT_AUTHORITY = "my.com.library.providers.tester";
private static final Uri BASE_CONTENT_URI = Uri.parse("content://" + CONTENT_AUTHORITY);

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

4b9b3361

Ответ 1

Приложение - это единственное, что абсолютно необходимо знать о полномочиях, поскольку оно объявляет <provider> в манифесте с атрибутом android:authorities.

Следовательно, в принципе, он должен "просто работать", пока вы удаляете из поставщика всю специфичную для авторизации логику, например:

  • те статические члены данных (которые теперь переходят к хостинговому приложению)
  • UriMatcher (сканируйте что-то самостоятельно, не проверяя полномочия, но фокусируясь на остальной части Uri)

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

  • Так как a ContentProvider является естественным одноэлементным, назначьте его статическому члену данных, а затем предоставите ему строку полномочий с помощью настраиваемого метода из пользовательского класса Application (поскольку поставщики сначала инициализируются, поэтому это должно работать)

  • Если вы поддерживаете только API уровня 11+, используйте Application класс call() call() для

    для предоставления полномочий ContentProvider
  • Предположим, что единственные реальные вызовы (например, query(), insert()) действительны и просто лениво инициализируют вашу власть на основе того, что входит в первую Uri, которую вы видите

Ответ 2

Я знаю, что это старая тема, но сегодня столкнулась с этой проблемой, и мы развиваемся довольно долго, поэтому не были готовы пройти все статики в Контракте поставщика контента и изменить их, также потому, что наш поставщик контента и БД генерируются Механоидный плагин для Eclipse (Да, я тоже автор!:))

Решение, с которым я столкнулся, состояло в том, чтобы добавить статический инициализатор в наш сгенерированный контракт, который использует отражение для поиска класса и использует статическое поле CONTENT_AUTHORITY, если оно существует, если оно не возвращается к умолчанию:

public class QuxContract  {
    public static final String CONTENT_AUTHORITY = initAuthority();

    private static String initAuthority() {
        String authority = "com.example.app.data.qux";

        try {

            ClassLoader loader = QuxContract.class.getClassLoader();

            Class<?> clz = loader.loadClass("com.example.app.data.QuxContentProviderAuthority");
            Field declaredField = clz.getDeclaredField("CONTENT_AUTHORITY");

            authority = declaredField.get(null).toString();
        } catch (ClassNotFoundException e) {} 
        catch (NoSuchFieldException e) {} 
        catch (IllegalArgumentException e) {
        } catch (IllegalAccessException e) {
        }

        return authority;
    }

    private static final Uri BASE_CONTENT_URI = Uri.parse("content://" + CONTENT_AUTHORITY);
// ...

Теперь в каждом проекте, который ссылается на проект библиотеки, могут быть предоставлены собственные полномочия:

package com.example.app.data;

public class QuxContentProviderAuthority {
    public static final String CONTENT_AUTHORITY = "com.example.app.data.baz";
}

Кроме того, не забудьте также изменить полномочия в манифесте