X

Anmelden

Zur Bestätigung jetzt anmelden

Passwort vergessen?

... oder mit Facebook anmelden:

Du hast noch keinen Zugang zu AndroidPIT? Registrieren

App-Lizenzierung – How-To

Voraussetzungen

Du benutzt bereits die LVL?

Wenn Du bereits mit der Android License Verification Library arbeitest, ist die Anbindung an die AndroidPIT Licensing Library sehr einfach.

1.

Lade die AndroidPIT Licensing Bibliothek herunter und binde sie in Dein Projekt ein.

2.

Ändere folgende zwei Variablendefinitionen von

    private LicenseCheckerCallback mLicenseCheckerCallback;
    private LicenseChecker mChecker;

in

    private IAndroidPitLicenseCheckerCallback mLicenseCheckerCallback;
    private AndroidPitLicenseChecker mChecker;

3.

Ändere die Erstellung des Checkers von

    mChecker = new LicenseChecker(
            this,
            new ServerManagedPolicy(
                    this,
                    new AESObfuscator(SALT, getPackageName(), deviceId)),
            GOOGLE_PUBLIC_KEY);

in

    mChecker = new AndroidPitLicenseChecker(
            this,
            getPackageName(),
            ANDROIDPIT_PUBLIC_KEY,
            new ServerManagedPolicy(
                    this,
                    new AESObfuscator(SALT, getPackageName(), deviceId)),
            GOOGLE_PUBLIC_KEY);

4.

Ändere die Definition für Deinen Listener von (beispielsweise)

    class MyLicenseCheckerCallback implements LicenseCheckerCallback

in

    class MyLicenseCheckerCallback implements IAndroidPitLicenseCheckerCallback

5.

Ändere den Typ des errorCode-Parameter in der applicationError Methode von

    public void applicationError(ApplicationErrorCode errorCode)

in

    public void applicationError(AndroidPitLicenseCheckCode errorCode)

und erweitere die Fehlerbehandlung um die AndroidPIT-Fehlercodes (s.u.).

Das war's! Der Aufruf des Checkers sowie die allow()- und dontAllow()-Callback-Methoden-Implementierungen brauchen nicht verändert zu werden.

Auf die Schnelle

Das AndroidPIT-Lizenzierungssystem lässt sich sehr ähnlich zu dem von Google verwenden. Binde dazu sowohl die Android License Verification Library (LVL) als auch die AndroidPIT Licensing Bibliothek in Dein Projekt ein. Erzeuge Dir in der onCreate-Methode Deiner App einen AndroidPitLicenseChecker und weise ihm eine Instanz einer Klasse zu, die das Interface IAndroidPitLicenseCheckerCallback implementiert. Zusätzlich benötigst Du von uns einen Lizenzschlüssel, welchen Du in Deinem Developer-Profil bei AndroidPIT erhälst. Eine Beispiel-Activity könnte so aussehen:

import android.app.Activity;

public class LicensingTest extends Activity implements OnClickListener
{

    private final String ANDROIDPIT_PUBLIC_KEY = "rO0ABXNyABRqYX...;"

    private final Handler mHandler = new Handler();

    private IAndroidPitLicenseCheckerCallback mLicenseCheckerCallback;
    private AndroidPitLicenseChecker mChecker;

    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);

        mLicenseCheckerCallback = new MyLicenseCheckerCallback();
        mChecker = new AndroidPitLicenseChecker(
                this,
                getPackageName(),
                ANDROIDPIT_PUBLIC_KEY);

        setContentView(R.layout.main);

        mChecker.checkAccess(mLicenseCheckerCallback);
    }

    @Override
    protected void onDestroy
    {
        super.onDestroy();
        mChecker.onDestroy();
    }

    class MyLicenseCheckerCallback implements IAndroidPitLicenseCheckerCallback
    {

        @Override
        public void allow()
        {
            // TODO: Handle positive response
        }

        @Override
        public void dontAllow()
        {
            // TODO: Handle negative response
        }

        @Override
        public void applicationError(AndroidPitLicenseCheckCode errorCode)
        {
            // TODO: Handle application error
        }

    }

}

Zusätzlich zu der Lizenzüberprüfung bei AndroidPIT erlaubt die Bibliothek auch das Überprüfen einer Lizenz im Android Market. Passe dazu den Konstruktor-Ruf des AndroidPitLicenseChecker an, indem Du ihm die Google Policy und den Google Public Key übergibst. Alle weiteren Vorgehensweisen für die Lizenzprüfung im Android Market entnehme bitte der LVL Dokumentation. Die Schnittstellendefinition des entsprechenden Konstruktors sieht wie folgt aus:

/**
 * Creates the AndroidPitLicenseChecker with all data to check against the
 * AndroidPIT App Center and Google. Google is checked first. If it fails,
 * AndroidPIT App Center will be consulted.
 
 @param context
 *            the context of the application
 @param appPkgName
 *            the package id of the app
 @param androidPitPublicKey
 *            the developers public key at AndroidPIT
 @param googlePolicy
 *            policy for Google licensing - @see LVL documentation
 @param googlePublicKey
 *            public key for Google licensing - @see LVL documentation
 */
public AndroidPitLicenseChecker(
        final Context context,
        final String appPkgName,
        final String androidPitPublicKey,
        final Policy googlePolicy,
        final String googlePublicKey);

En Detail

Das AndroidPIT-Lizenzierungssystem ist ein an die Android License Verification Library (LVL) angelehnter Mechanismus, um die Gültigkeit der Installation einer Android-App, welche bei AndroidPIT gekauft wurde, zu überprüfen. Dafür ist eine Internetverbindung vom mobilen Endgerät zu einem unserer Lizenzserver notwendig. Zusätzlich muss das AndroidPIT App Center auf dem Anwendergerät installiert sein und der Endanwender benötigt einen gültigen AndroidPIT-Account.

Die Anwendung überprüft mit Hilfe der AndroidPIT Licensing Library am App Center, ob der Endnutzer für die Anwendung eine gültige Lizenz besitzt. Das App Center verbindet sich dafür mit dem Lizenzserver und validiert den Kauf der Anwendung. Die Überprüfung am Lizenzserver findet bei jedem Start der Anwendung, höchstens aber ein mal täglich statt. Zwischenzeitliche überprüfungen geben den letzten vom Lizenzserver zurückgegebenen Wert zurück (der Zeitraum kann sich ohne Ankündigung jederzeit ändern).

Schritt für Schritt

Diese Schritt für Schritt-Anleitung geht von der Verwendung des Eclipse ADT aus. Solltest Du andere Entwicklungswerkzeuge einsetzen, sind möglicherweise weitere Schritte notwendig.

Lade Dir von AndroidPIT die AndroidPIT Licensing Library und von Google die Android License Verification Library (LVL) herunter und binde sie als Android-Projekte in das ADT ein. Um die AndroidPIT-Lizenzbibliothek verwenden zu können, ist mindestens die Android API Version 4 erforderlich, welche mit Android 1.6 ausgeliefert wurde. Lege Dir mit Hilfe des ADT-Wizzards ein Projekt für Deine Android-Anwendung an und füge in den Properties unter Android die androidpit-licensing-lib hinzu. Überprüfe, ob die Bibliothek korrekt auf die Android License Verification Library (LVL) verweist.

Ich erhalte lauter unaufgelöste Symbole oder kann meine App nicht übersetzen.

Überprüfe bitte die Pfade zu der Google LVL und der AndroidPIT License Library in den Einstellungen des Android-Projekts. Die sollten mit den Orten in deinem Dateisystem übereinstimmen.

Application project settings

Die Einstellungen für die AndroidPIT Lizenzbibliothek sieht wie folgt aus:

Library project settings

Wie binde ich die Lizenzprüfung in meinen Code ein?

Um die Anwendung zur Lizenzüberprüfung an das AndroidPIT App Center zu binden, erzeuge Dir in der onCreate()-Methode der Activity eine Instanz der Klasse MyLicenseCheckerCallback. Der Konstruktor erwartet eine Instanz des Contexts, in dem er läuft, für üblich ist das die Activity, in der er erzeugt wird.

mLicenseCheckerCallback = new MyLicenseCheckerCallback();
mChecker = new AndroidPitLicenseChecker(
          this, getPackageName(), ANDROIDPIT_PUBLIC_KEY);
mChecker.checkAccess(mLicenseCheckerCallback);

Des weiteren erwartet der Konstruktor den Android-Paketnamen und einen von AndroidPIT bereitgestellten Lizenzschlüssel. Der Lizensschlüssel ist ein Base64-kodierter Public Key. Er kann jederzeit im Entwicklerprofil bei AndroidPIT unter Lizenz eingesehen werden.

Wie erhalte ich Nachricht vom Lizenz-Server?

Die Lizenzprüfung wird mit dem Ruf der Methode checkAccess() am AndroidPitLicenseChecker gestartet. Diese Methode erwartet ein Callback-Objekt, welches das Interface IAndroidPitLicenseCheckerCallback implementiert. Die Klasse ist jetzt zu implementieren. Sie enthält analog zu der Klasse im Android Market Licensing drei Methoden. Die Methode allow() wird von der AndroidPIT Licensing Library gerufen, wenn die Überprüfung der Lizenz erfolgreich war. War sie nicht erfolgreich, wird dontAllow() gerufen. Fehler werden mit der Methode applicationError() gemeldet. In den drei Methoden kannst Du nach eigenen Wünschen auf die Ereignisse reagieren.

class MyLicenseCheckerCallback implements IAndroidPitLicenseCheckerCallback
{

    @Override
    public void allow()
    {
        // TODO: Handle positive response
    }

    @Override
    public void dontAllow()
    {
        // TODO: Handle negative response
    }

    @Override
    public void applicationError(AndroidPitLicenseCheckCode errorCode)
    {
        // TODO: Handle application error
    }

}

Wie prüfe ich zusätzlich die Lizenz im Android Market?

Zusätzlich bietet unsere Bibliothek die Möglichkeit, die Lizenz bei Google zu prüfen. Dazu stellt der AndroidPitLicenseChecker einen zweiten Konstruktor bereit, welcher eine Policy und den öffentlichen Schlüssel des LVL erwartet. Beides ist ihm zu übergeben. Die Lizenzüberprüfung findet dann von der Bibliothek aus statt. Erfolgreiche Anfragen werden direkt mit dem Ruf der allow()-Methode quittiert. Fehlschläge ziehen eine Überprüfung bei AndroidPIT nach sich. Erst wenn hier die Lizenzprüfung negativ beantwortet wird, wird dontAllow() gerufen.

Das Beispiel ist an die Dokumentation in der Google API angelehnt.

mChecker = new AndroidPitLicenseChecker(
               this, 
               getPackageName()
               ANDROIDPIT_PUBLIC_KEY,
               new ServerManagedPolicy(
                   this,
                   new AESObfuscator(SALT, getPackageName(), deviceId)),
               GOOGLE_PUBLIC_KEY);

Wie kann ich verschiedene Fehlermeldungen vom Lizenzserver testen?

Zum Testen Deiner Anbindung kannst Du in Deinem Developer-Profil einen festen Antwortcode einstellen. Dies ist nützlich, um die die Behandlung der verschiedenen Fehlercodes vom Lizenzserver in der Anwendung überprüfen zu können. Stelle dazu das Drop-Down-Menü unter dem Lizenschlüssel auf den von Dir gewünschten Wert. Dann wird der Server Dir diesen Wert zurück liefern, wenn Du im App Center mit Deinem Entwickler-Account angemeldet bist.

Wie stelle ich das Caching des Ergebnisses im App Center ab?

Das App Center speichert Ergebnisse der letzten Anfrage für einen Tag aber spätestens bis zum nächsten Kontakt mit dem Lizenzserver zwischen. Um dieses Verhalten abzustellen kann der License-Checker in einen Debug-Modus versetzt werden. Dazu rufst Du an der Instanz die Methode setDebug(true) auf. Das stellt den Cache aus und alle Anfragen werden sofort an den Lizenzserver weitergeleitet. Dank daran den Debug-Modus vor der Veröffentlichung Deiner App wieder zu deaktivieren!

Was passiert, wenn der Endanwender nicht im App Center angemeldet ist?

Ist keine User-Anmeldung im App Center hinterlegt, öffnet sich in der Anwendung eine Dialogbox, welche die E-Mail-Adresse und das Passwort des Nutzers abfragt.

Wie stelle ich sicher, dass die Lizenzanfrage den Lizenzserver erreicht?

Die AndroidPIT Lizenzbibliothek enthält die LizenzCheck-Klasse AndroidPitSignedLicenseChecker. Diese Klasse stellt die Möglichkeit bereit zu überprüfen, ob die Anfrage den Lizenzserver erreicht hat oder nicht. Dazu wird auf dem Server mit Hilfe des privaten Schlüssels des Entwicklers die Antwort signiert. In der Bibliothek wird die Signatur in dem AndroidPitLicenseingResponseValidator überprüft und kontrolliert, ob das Salt, welches beim Request mitgeschickt wurde, mit dem in der Antwort übereinstimmt. Zu bedenken ist, dass hier kein Caching des Lizenzstatus im AppCenter zur Verfügung steht. Jede Anfrage muss von dem Lizenzserver bearbeitet werden. Steht dem Nutzer keine Verbindung zum Internet zur Verfügung, beantwortet die Bibliothek die Anfrage abschlägig mit ERROR_NOT_CONNECTED.

Beispielhaft könnte das so aussehen:

AndroidPitSignedLicenseChecker mChecker;

[ ... ]

mChecker = new AndroidPitSignedLicenseChecker(
               this, 
               getPackageName()
               ANDROIDPIT_PUBLIC_KEY);

Kann ich meinen eigenen Lizenzvalidator benutzen? Ich möchte die Signatur selbst überprüfen.

Ja, das ist möglich. Dazu implementiere bitte das Interface ILicensingResponseValidator und übergib dem Construktor des AndroidPitSignedLicenseChecker eine Instanz der implementierenden Klasse. Die Klasse muss zwei Methoden implementieren. getSalt() muss einen Integer zurückliefern, der beim Lizenzcheck als Salt an den Server gereicht wird. Dieser Salt sollte sich von Request bis Response gemerkt werden, wenn er beim Validierungsprozess eine Rolle spielen soll. Die Methode checkResponse() sollte die Validität der Response-Daten überprüfen und im Fehlerfall AndroidPitLicenseCheckCode.NOT_LICENSED zurückliefern. Bei erfolgreicher Validierung sollte die Methode den Antwort-Code des Servers zurückgeben. Als Vorlage kann die Klasse AndroidPitLicensingResponseValidator aus der AndroidPIT Lizenzbibliothek dienen.

Mein Projekt findet die Enumeration de.androidpit.AndroidPitLicenseCheckError nicht mehr.

Die Enumeration wurde in de.androidpit.AndroidPitLicenseCheckCode umbenannt.

Wie erhalte ich aus dem Base64-String ein PublicKey-Objekt?

Wie du vielleicht schon gesehen hast, stellen wir den Public Key als Base64-Kodierten String zur Verfügung. Um die Signatur der Serverantwort zu überprüfen, benötigst du allerdings ein PublicKey-Objekt. Wie du dieses aus dem String erzeugst, zeigt folgender Code.

    /**
     * Converts the base64 encoded representation of a public key into a
     * PublicKey object.
     */
    private PublicKey createPublicKey(String pubKeyBase64)
    {

        PublicKey pubKey = null;
        try
        {
            // the pub key comes in as a Base64 coded string. Decode to the
            // byte array which contains the object stream of the public key
            ByteArrayInputStream pubKeyByteArray = new ByteArrayInputStream(
                    Base64.decode(pubKeyBase64));
            ObjectInputStream publicKeyObject = new ObjectInputStream(
                    pubKeyByteArray);
            BigInteger modulus = (BigIntegerpublicKeyObject.readObject();
            BigInteger exponent = (BigIntegerpublicKeyObject.readObject();

            RSAPublicKeySpec keySpec = new RSAPublicKeySpec(modulus, exponent);
            KeyFactory rsaKeyFactory = KeyFactory.getInstance("RSA");
            pubKey = rsaKeyFactory.generatePublic(keySpec);
        }
        catch (Exception ex)
        {
            Log.e(
                    "LicenseResponseValidator",
                    "Deserialization of public key failed.",
                    ex);
        }
        return pubKey;
    }

AndroidPIT Licensing Bibliothek

Wenn Du die alte Android Market Licensing Bibliothek (Package com.android.vending.licensing) verwendest, benutze diese Version der AndroidPIT Licensing Bibliothek:
AndroidPIT Licensing Bibliothek Version 1.3

Wenn Du die neue Google Play Bibliothek (Package com.google.android.vending.licensing) verwendest, benutze die folgende Version der AndroidPIT Licensing Bibliothek:
AndroidPIT Licensing Bibliothek Version 2.1