Проблем с дублиращия се доставчик на 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 или Authority = something.went.wrong.if.this.is.used - 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