Пользовательские разрешения Android не срабатывают на основе заказа приложения

Проблемы с моими приложениями в Google Play. У меня есть бесплатное приложение, которое использует специальное разрешение. Это разрешение позволяет получить доступ к платным приложениям. Эти платные приложения действуют как "ключи" и разблокируют функции в бесплатном приложении. В основном бесплатное приложение попытается запустить намерение одного из платных приложений. Платное приложение будет делать некоторые вещи и возвращаться, говоря, бесплатное приложение должно разблокировать функции или нет.

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

  • Бесплатный манифест App (соответствующий код):

    ...
    <uses-permission android:name="com.company.license.PERMISSION" />
    ...
    
  • Бесплатный код приложения для проверки намерения (соответствующий код):

    Intent KeyApp = new Intent("com.company.license.action.AUTH_1");
    KeyApp.putExtra("com.company.license.challenge", 1);
    
    //If free app is installed first, an exception is thrown for not having the proper permission. If paid app is installed first, no exception is thrown
    try {
        startActivityForResult(KeyApp, COMMING_FROM_KEYAPP);
    } catch (Exception e) {
        cancelStartUp();
    }
    
  • Платный манифест приложения (соответствующий код):

    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
        package="com.company.installer.1"
    ...
    <permission
        android:name="com.company.license.PERMISSION"
        android:icon="@drawable/icon"
        android:label="@string/app_name"
        android:protectionLevel="normal" >
    </permission>
    
    <application
        android:icon="@drawable/icon"
        android:label="@string/app_name"
        android:theme="@android:style/Theme.NoDisplay" >
    
        <activity
            android:name="com.company.license.auth"
            android:configChanges="keyboardHidden|orientation"
            android:exported="true"
            android:permission="com.company.license.PERMISSION"
            android:theme="@style/Theme.Transparent" >
            <intent-filter>
                <action android:name="com.company.license.action.AUTH_1" />
    
                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>
        </activity>
    
        <activity
            android:name="com.company.installer.redirect"
            android:configChanges="keyboardHidden|orientation"
            android:exported="true"
            android:theme="@style/Theme.Transparent" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
    
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>
    
    </manifest>
    

Ответ 1

Поместите тот же элемент <permission> в оба приложения. Кроме того, поскольку это относится к вашим двум приложениям, я бы использовал android:protectionLevel="signature" вместо normal - это означает, что пользователю не нужно будет одобрять это разрешение, и никто другой не сможет запросить разрешение. И этот рецепт позволит установить в любом порядке.

ОБНОВЛЕНИЕ. Обратите внимание, однако, что использование пользовательских разрешений открывает потенциальные уязвимости, из-за Android "первый выигрывает" подход".

ОБНОВЛЕНИЕ # 2. И теперь это больше не поддерживается на Android 5.0, так как два приложения не могут оба имеют тот же элемент <permission>, если они не подписаны одним и тем же ключом подписи.

Ответ 2

Мне удалось решить проблему @CommonsWare, упомянутую в его обновлении №2. Просто объявить только разрешение в приложении, которое будет установлено первым.

Объяснение: У меня есть приложение A и приложение B, подписанное с различными сигнатурами. Приложение A должно использовать приложение B для входа в систему, но приложение A сначала устанавливается, и убедитесь, что пользователь устанавливает приложение B.

Поскольку приложение B, похоже, является службой (login), я объявил пользовательское разрешение в приложении B. В приложении B есть (намерение) служба, которую могут использовать другие приложения, если они используют это разрешение и находятся в нашем белом списке. Поэтому приложение B было объявлено о предоставлении услуги и разрешении.

Но поскольку приложение A установлено до обнаружения приложения BI, мне нужно было добавить это разрешение также в приложение A. В противном случае приложение A, похоже, не имело разрешения после установки приложения B. Мое лучшее предположение заключается в том, что это связано с тем, что разрешающая способность выполняется при установке. А так как приложение A не объявило разрешения, при установке ничего не произошло. Но тогда установлено приложение B, у которого есть разрешение, но приложение A по-прежнему не получает этого разрешения.

Но потом я тестировал на Android 5 и натыкался на их уникальные разрешения. Поэтому я протестировал некоторые потоки и объявления разрешений и разработал рабочее решение: Объявите пользовательское разрешение в приложении, которое будет установлено первым! Конечно, это работает только тогда, когда вы знаете, какое приложение будет установлено первым. Но в моем случае, когда приложение A зависит от приложения B, приложение A устанавливает приложение B, это было решение:)