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

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

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

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

 50086529 мая 2012 г., 00:12
Это может быть дубликатомstackoverflow.com/questions/10320689/…, но никто не ответил до сих пор.

Ответы на вопрос(2)

Решение Вопроса

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

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

those static data members (which now move to the hosting app) UriMatcher (roll something yourself that does not examine the authority, but focuses on the rest of the Uri)

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

Since a ContentProvider is a natural singleton, assign it to a static data member, and then supply the authority string to it by a custom method from a custom Application class (as providers are initialized first, so this should work)

If you are only supporting API Level 11+, have the custom Application class use call() on ContentResolver to supply the authority to the ContentProvider

Assume that the only real calls (e.g., to query(), insert()) are valid, and just lazy-initialize your authority based on what comes in on the first Uri you see

 29 мая 2012 г., 00:53
@AlexLockwood: извините за это. Если тебе от этого становится лучше, то и со мной тоже. Кроме того, не бойтесь просто идти вперед и публиковать свой ответ, когда такого рода вещи случаются. Возможно, что ваша фраза или что-то будет лучше отвечать спрашивающему, чем существующий ответ. Кроме того, если вы прошли через все трудности, чтобы набрать (большую часть) ответ, вы также можете опубликовать его.
 29 мая 2012 г., 00:42
Я почти закончил отвечать на вопрос ... потом я увидел "1 новый ответ" всплывающее окно, и, конечно, это был CommonsWare, чей ответ охватил все, что я упомянул и многое другое Просто моя удача ...: P
 20 авг. 2015 г., 16:59
Ни одно из вышеупомянутых решений не сработало для меня: 1. Исправьте, что ContentProvider является одноэлементным, но что, если использовать ContentProvider в библиотеке, в которой есть виджет, теперь пользователь не будет открывать приложение, чтобы поместить виджет на экран, чтобы полномочия ContentProvider не инициализировались с публичная статическая константа. 2. вызвать метод ContentResolver, который я не могу использовать в соответствии с предложением @ Dra & # x161; koKoki & # x107 ;: 3. Что если я выполняю вызовы query () из самой библиотеки, а не из приложения, то в этом случае третье решение также не будет работать
 50086529 мая 2012 г., 00:55
Я понял Я думал о модификации кода во время компиляции. Разве это не возможно? Если это возможно, это будет легко и вероятно просто, чем этот подход.
 29 мая 2012 г., 01:01
@ 500865: "Разве это не возможно?" - не очень, если вы не собираетесь запускать свою собственную задачу Ant или что-то, что делает копию библиотеки, корректирует источник, корректируетproject.properties приложения хостинга, чтобы указать на копию и т. д. "Если это возможно, это будет легко и, вероятно, проще, чем этот подход. & quot; - Я думаю, что изменение кода во время компиляции будет на несколько порядков сложнее. В конце концов, ленивый поиск вашегоUri на основании первогоquery()и т. д. вызов должен быть не более 10 строк кода.

Я знаю, что это старая тема, но сегодня мы сталкивались с этой проблемой, и мы уже довольно давно занимаемся ее разработкой, поэтому не были готовы просмотреть всю статистику в нашем Контракте с контент-провайдером и изменить ее, в том числе из-за того, что наш провайдер контента и БД генерируютсяПлагин Mechanoid для 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";
}

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

 03 мая 2016 г., 05:57
Это решение просто потрясающе! Большое спасибо! : D
 50086529 янв. 2013 г., 22:07
Близко к решению, которое я реализовал. Спасибо, что поделился!!
 22 авг. 2014 г., 19:42
Спасибо, теперь я могу выпустить сегодня!
 16 окт. 2014 г., 16:02
@ Ian Warwick На самом деле я новичок в Android, я работаю со Android Studio для меня та же проблема с полномочиями, вы можете помочь мне с некоторыми примерами

Ваш ответ на вопрос