Проверка лицензии для pro ключа

Поэтому я хотел бы сделать бесплатное приложение с загруженной полной функциональностью. Профессиональная функциональность будет отключена, пока приложение не обнаружит лицензионный профессиональный ключ. И, конечно же, я хотел бы, чтобы ключ pro проверял свою лицензию с помощью LVL. Хотя я знаю, как все делать правильно до этого момента, я не знаю, как заставить ключ pro связываться с приложением, чтобы оно включало функциональные возможности pro.

Вот основной код приложения (com.test.mainapp):

public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    context = getApplicationContext();

    final PackageManager pacman = getPackageManager();
    final int signatureMatch = pacman.checkSignatures(getPackageName(),
            "com.test.mainapp_key");

    if (signatureMatch == PackageManager.SIGNATURE_MATCH) {
        Toast.makeText(context, "Pro key detected!", Toast.LENGTH_SHORT)
                .show();
    } else {
        Toast.makeText(context, "Free version", Toast.LENGTH_SHORT).show();
    }
}

Хотя это не позволяет другим делать поддельные ключи для моего приложения, они по-прежнему могут делиться ключевым приложением в Интернете с другими, и оно будет работать. Поскольку мы не можем выполнить проверку LVL из другого приложения, я бы хотел, чтобы приложение лицензионного ключа проверяло свою собственную лицензию, и если оно правильное, только тогда пользователь получает профессиональные функции. Как сделать так, чтобы приложение с лицензионным ключом и основное приложение взаимодействовали друг с другом?

Функциональность, которую я пытаюсь здесь получить, аналогична, например, Titanium Backup.


person Iiro Krankka    schedule 07.11.2011    source источник
comment
Если вы можете получить уникальный идентификатор устройства (например, IMEI или серийный номер устройства), вы можете использовать серийный номер, привязанный к этому значению. Это сделает серийный ключ недействительным для любого устройства, кроме того, которое вы лицензировали.   -  person Polynomial    schedule 07.11.2011
comment
Не могли бы вы объяснить немного больше, как будет работать логика в этом?   -  person Iiro Krankka    schedule 07.11.2011
comment
Допустим, у вас есть секретный ключ, например: mySecretKey. Вы получаете идентификатор устройства в виде строки, например. MyDevice. Объедините их и хешируйте результат, используя MD5 (или свою собственную схему хеширования), и используйте часть хэша в качестве ключа. Для проверки просто вычислите хэш для mySecretKey и текущего идентификатора устройства и сравните с серийным номером. Если он совпадает, серийный номер действителен для этого устройства. На другом компьютере он никогда не будет совпадать, потому что идентификатор устройства неверен.   -  person Polynomial    schedule 07.11.2011
comment
Очевидно, что это можно сломать путем обратного проектирования вашего приложения, но мы говорим здесь о тривиальном лицензировании, а не о полноценном DRM.   -  person Polynomial    schedule 07.11.2011


Ответы (2)


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

private class MyLicenseCheckerCallback implements LicenseCheckerCallback {
    public void allow() {
        Log.i("Key", "License Accepted");
        Intent i = new Intent();
        i.setAction("intent.to.call.on.success");
        i.putExtra("licenseresult", 0);
        c.sendBroadcast(i);
        mChecker.onDestroy();
    }

    public void dontAllow() {
        Log.e("Key", "License Denied");
        Intent i = new Intent();
        i.setAction("intent.to.call.on.failure");
        i.putExtra("licenseresult", 1);
        c.sendBroadcast(i);
        mChecker.onDestroy();
    }

    public void applicationError(ApplicationErrorCode errorCode) {
        Log.i("Key", "LR Error");
        Intent i = new Intent();
        i.setAction("intent.to.call.on.error");
        i.putExtra("licenseresult", 2);
        c.sendBroadcast(i);
        mChecker.onDestroy();
    }
}

Вы должны настроить широковещательные приемники в обоих приложениях, чтобы инициировать проверку лицензии и обрабатывать результат. например

public class License extends BroadcastReceiver {

@Override
public void onReceive(Context context, Intent intent) {

    if (intent.getAction().equals("intent.called.to.initiate.request")) {
                // Initiate the license request here (possibly using a service)
        return;
    }
}

} 

Вы должны ограничить доступ к намерениям, используя разрешения на основе сертификата, чтобы другие приложения не могли отправлять поддельные намерения «Успешное получение лицензии».

http://developer.android.com/reference/android/content/BroadcastReceiver.html#Permissions< /а>

Укороченная версия.

Определить разрешение в манифесте

< permission android:name="my.package.LicenseCheck" android:protectionLevel="signature"/> 

Используйте разрешение в объявлении приемника:

<receiver android:name="name.of.your.receiver" android:permission="my.package.LicenseCheck"> 
<intent-filter>
    <action android:name="name.of.intent"/>
</intent-filter>
</receiver>
person Kuffs    schedule 07.11.2011
comment
Спасибо за ваш ответ. Это было то, о чем я думал, но я не знаю, как предотвратить запуск этих намерений другими приложениями. Не могли бы вы предоставить мне некоторую информацию, как ограничить доступ (это то, что я изначально искал)? - person Iiro Krankka; 07.11.2011
comment
На самом деле я читал эту страницу прошлой ночью, но не проверял документацию по атрибуту ProtectionLevel. Спасибо. Пожалуйста, отредактируйте свой предыдущий ответ, чтобы в нем был этот комментарий, чтобы я мог отметить этот вопрос как ответ :) - person Iiro Krankka; 07.11.2011
comment
еще кое-что. Очевидно, я буду использовать проверку LVL внутри IntentService, а не BroadcastReceiver, верно? - person Iiro Krankka; 08.11.2011
comment
Вот как я это сделал. 1. Основное приложение отправляет запрос на лицензирование приложения 2. Лицензионное приложение запускает службу, которая запрашивает LVL 3. Лицензионная служба отвечает основному приложению - person Kuffs; 08.11.2011
comment
Не могли бы вы, ребята, рассказать мне, как вы справились с onDestroy? Я сам выбрал IntentService, но у меня проблемы с жизненным циклом и привязкой сервера лицензирования. - person Anthony; 10.04.2013

@MainApp

<permission android:name="myapp.permission.RESPOND" protectionLevel="signature" />

<receiver android:name=".receiver.WhichHandlesValidationResponse" android:permisssion="myapp.permission.RESPOND">
    <intent-filter>
            <action android:name="myapp.action.VALIDATION_RESPONSE" />
    </intent-filter>
</receiver>

@KeyApp

<uses-permission android:name="myapp.permission.RESPOND" />

Создайте LvlValidationHandler.class, который содержит:

Intent i = new Intent("myapp.action.VALIDATION_RESPONSE");
sendBroadcast(i);
person sancho21    schedule 05.09.2012