Проблема с дубликатом провайдера Android

Мы пытаемся опубликовать платную версию казуального приложения без рекламы, которая в настоящее время публикуется бесплатно с рекламой. Мы преобразовали все имена пакетов в com.mycompanyname.appname.pro, бесплатный пакет на рынке не имеет .pro в конце. Мы также зашли в нашего поставщика контента и изменили полномочия на такие же, как имя пакета. Итак, «бесплатная версия» имеет

AUTHORITY = "com.mycompanyname.appname" 

а "платная версия без рекламы имеет

AUTHORITY = "com.mycompanyname.appname.pro" 

но по-прежнему мы не можем установить и бесплатную, и «профессиональную» версию на одно и то же устройство. Как бы то ни было, имя класса для провайдера одинаково в обоих приложениях.

Мы не можем установить из apk напрямую, и если мы попытаемся загрузить с Android Market, мы получим сообщение об ошибке «дубликат полномочий провайдера».

Что нам не хватает? Есть ли другое место, где нам нужно искать проблемы, или у нас есть что-то принципиально неправильное здесь?


person thefish7    schedule 21.06.2011    source источник


Ответы (4)


По сути, я создал абстрактный базовый класс для каждого из моих ContentProviders и наследовал его для каждого приложения, которое я хочу создать, переопределяя путь полномочий. Итак, в моем AbstractContentProvider у меня есть:

public AbstractContentProvider() {
    sURIMatcher.addURI(getAuthority(), BASE_PATH, ITEMS);
    sURIMatcher.addURI(getAuthority(), BASE_PATH + "/#", ITEM_ID);
}

protected abstract String getAuthority();

а затем в каждом подклассе у меня есть:

private static final String AUTHORITY = "my.package.app1.ContentProvider";

@Override
protected String getAuthority() {
    return AUTHORITY;
}

В AndroidManifest я регистрирую их с помощью:

    <provider
          android:name="my.package.app1.ContentProvider"
          android:authorities="my.package.app1.ContentProvider">
    </provider>

Теперь хитрость в том, что я хочу получить доступ к этим поставщикам контента в общем (библиотечном) коде, который не знает о конкретных классах приложения. Для этого я определяю строку в файле strings.xml, которую переопределяю для каждого приложения. Тогда я могу использовать:

Uri.parse(getString(R.string.contentProviderUri))

и в каждом приложении правильный ContentProvider используется без каких-либо конфликтов. Таким образом, в основном используется механизм конфигурации для внедрения зависимостей.

person koljaTM    schedule 18.10.2012

Допустим, пакет вашей библиотеки com.android.app.library бесплатный пакет com.android.app.free платный пакет com.android.app.paid

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

Пример:

  1. Создайте новый пакет в бесплатной версии с помощью com.android.app.data.

  2. Создайте файл с именем Authority.java и внутри (Authority.java) поместите:

    public class Authority {

    `public static final String CONTENT_AUTHORITY = "YOUR PROVIDER";`
    

    }

  3. Повторите это для платной версии, не забудьте сохранить имя пакета и имя класса.

Теперь в вашем файле контракта в вашей библиотеке используйте следующее:

public static String AUTHORITY = initAuthority();

    private static String initAuthority() {
        String authority = "something.went.wrong.if.this.is.used";

        try {

            ClassLoader loader = Contract.class.getClassLoader();

            Class<?> clz = loader.loadClass("com.android.app.data.Authority");
            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;
    }

    public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY);

Теперь вы должны иметь возможность использовать два авторитета.

Предоставлено: Ян Варик Android — наличие полномочий провайдера в проекте приложения

person Jerryl15    schedule 11.01.2014
comment
@ Jerryl15 у меня была та же проблема, какие органы власти я должен объявить в манифесте, будь то com.android.app.data.Authority или авторитет = что-то.пошло.неправильно.если.это.используется - person Manoj; 16.10.2014

Google по умолчанию добавляет поставщика измерения приложений в ваше приложение, поэтому в файле build.gradle вам необходимо определить applicationID в теге android exaple defaultConfig { applicationId "com.example.my.app" minSdkVersion 15 targetSdkVersion 19 versionCode 1 версияНазвание "1.0" }

person Abhishek    schedule 10.02.2016
comment
Это тоже решило мою проблему. У людей возникала ошибка 505 при установке нашего приложения в Google Play Store. - person Jeenyus; 03.06.2016

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

Мне было любопытно, сталкивался ли кто-нибудь еще с тем же самым, и, конечно же, это похоже на ошибку в платформе Android. См. сведения о проблеме здесь или аналогичный пост SO здесь.

person areyling    schedule 30.03.2012