web-dev-qa-db-fra.com

Comment puis-je implémenter les licences Google Play pour une application Android?

J'ai vu la bibliothèque de licences Android-Developer stock instructions , mais l'aperçu semble omettre plusieurs étapes clés du processus et ne parvient pas à expliquer complètement comment faire fonctionner quelque chose.

Quelqu'un peut-il fournir un ensemble explicite d'opérations qui ont permis de configurer la bibliothèque de licences sur une application Android afin qu'il vérifie qu'un utilisateur a payé une application dans Google Play avant d'en autoriser l'utilisation?

39
Code_Insanity

Je travaille sur la mise en œuvre des licences dans mon application depuis un certain temps maintenant et je l'ai enfin fait fonctionner. Je voulais partager certaines des choses que j'ai trouvées utiles pour commencer et quelques problèmes et solutions que j'ai trouvés avec tout le monde. Le tutoriel Android dev que j'ai lié ci-dessous est correct, mais ce n'était pas très utile pour moi, alors j'ai décidé de faire un tutoriel. Profitez-en, et j'espère que cela vous aidera!

Lien vers la page développeur ici .

1. Pour commencer

Les choses dont vous aurez besoin.

1.1 Votre clé d'application unique Base64

Comment l'obtenir:

une. Accédez à votre console développeur. Lien.

b. Si vous n'avez pas encore créé de brouillon d'application pour votre application, faites-le maintenant.

c. Une fois que vous avez créé le brouillon, c'est une bonne idée de télécharger votre .apk En Alpha ou Beta. Laissez-le non publié.

ré. Cliquez sur Services & APIs

e. Faites défiler vers le bas et trouvez YOUR LICENSE KEY FOR THIS APPLICATION

f. Copiez la clé dans votre application comme ceci:

private static final String BASE64_PUBLIC_KEY = "YOUR LICENSE KEY FOR THIS APPLICATION"; 

Assurez-vous qu'il n'y a pas d'espace.

1,2 A de sel

une. Qu'est-ce qu'un sel?

Un sel est une donnée aléatoire qui est une entrée supplémentaire lors du hachage d'un mot de passe. Ils sont utilisés pour se défendre contre les attaques dictionnaire et Table arc-en-ciel .

b. Comment en obtenir un?

This est un bon lien pour générer un sel aléatoire. Il devrait y avoir exactement 20 entiers aléatoires, alors mettez 20 Pour la quantité de chaînes aléatoires à générer, chaque chaîne doit être 2 Caractères de long (utilisé pour cet exemple, il ne doit pas nécessairement l'être). Vérifiez les chiffres numériques et vérifiez que les chaînes identiques sont autorisées. Ils peuvent également être des nombres négatifs. Essayez de supprimer toute redondance, par exemple 00 -> 0, Par souci de cohérence.

c. Où dois-je mettre le sel?

Lorsque vous déclarez des variables, mettez simplement ce code, sauf avec votre sel aléatoire.

private static final byte[] SALT = new byte[] {YOUR RANDOM SALT, COMMA SEPARATED, 20 INTEGERS};

2. Importer la bibliothèque LVL (Licensing) dans Eclipse et le code dont vous avez besoin

2.1 Importation de la bibliothèque

une. Ouvrez Android SDK Manager

b. Accédez à Extras

c. Installez Google Play Licensing Library

ré. Recherchez votre SDK chemin d'installation qui est répertorié en haut du gestionnaire SDK.

e. Une fois que vous y êtes, accédez à: <sdk>/extras/google/play_licensing

f. Dans Eclipse, cliquez sur file puis import, puis Existing Android Code Into Workspace Et lorsqu'il vous demande le chemin du fichier, accédez au dossier play_licensing Et cliquez sur library.

g. Une fois le projet nommé library importé, faites un clic droit dessus, puis appuyez sur properties. Cliquez sur Android sur la gauche et naviguez vers le bas et cochez Is Library, Puis appuyez sur Appliquer. Cela permet à Eclipse de savoir que vous pouvez utiliser ce code de projet comme bibliothèque.

h. Cliquez avec le bouton droit sur votre application à laquelle vous ajoutez des licences, cliquez sur Propriétés, puis appuyez sur Android. Allez en bas et cliquez sur library et ajoutez-le au chemin de génération. Cela devrait importer la bibliothèque dans le dossier Android Dependencies.

je. Votre projet est configuré pour passer à l'étape suivante.

2.2 Variables à déclarer avec vos SALT et KEY

private Handler mHandler;
private LicenseChecker mChecker;
private LicenseCheckerCallback mLicenseCheckerCallback;
boolean licensed;
boolean checkingLicense;
boolean didCheck;

2.3 Le code

Collez ce code vers le bas de votre application. Cette implémentation avertira l'utilisateur si la licence n'est pas valide et l'invitera à acheter l'application ou à la quitter.

    private void doCheck() {

        didCheck = false;
        checkingLicense = true;
        setProgressBarIndeterminateVisibility(true);

        mChecker.checkAccess(mLicenseCheckerCallback);
    }


    private class MyLicenseCheckerCallback implements LicenseCheckerCallback {

        @Override
        public void allow(int reason) {
            // TODO Auto-generated method stub
            if (isFinishing()) {
                // Don't update UI if Activity is finishing.
                return;
            }               
            Log.i("License","Accepted!");       

                //You can do other things here, like saving the licensed status to a
                //SharedPreference so the app only has to check the license once.

            licensed = true;
            checkingLicense = false;
            didCheck = true;

        }

        @SuppressWarnings("deprecation")
        @Override
        public void dontAllow(int reason) {
            // TODO Auto-generated method stub
             if (isFinishing()) {
                    // Don't update UI if Activity is finishing.
                    return;
                }
                Log.i("License","Denied!");
                Log.i("License","Reason for denial: "+reason);                                                                              

                        //You can do other things here, like saving the licensed status to a
                        //SharedPreference so the app only has to check the license once.

                licensed = false;
                checkingLicense = false;
                didCheck = true;               

                showDialog(0);

        }

        @SuppressWarnings("deprecation")
        @Override
        public void applicationError(int reason) {
            // TODO Auto-generated method stub
            Log.i("License", "Error: " + reason);
            if (isFinishing()) {
                // Don't update UI if Activity is finishing.
                return;
            }
            licensed = true;
            checkingLicense = false;
            didCheck = false;

            showDialog(0);
        }


    }

    protected Dialog onCreateDialog(int id) {
        // We have only one dialog.
        return new AlertDialog.Builder(this)
                .setTitle("UNLICENSED APPLICATION DIALOG TITLE")
                .setMessage("This application is not licensed, please buy it from the Play Store.")
                .setPositiveButton("Buy", new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int which) {
                        Intent marketIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(
                                "http://market.Android.com/details?id=" + getPackageName()));
                        startActivity(marketIntent);
                        finish();
                    }
                })
                .setNegativeButton("Exit", new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int which) {
                        finish();
                    }
                })
                .setNeutralButton("Re-Check", new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int which) {
                        doCheck();
                    }
                })

                .setCancelable(false)
                .setOnKeyListener(new DialogInterface.OnKeyListener(){
                    public boolean onKey(DialogInterface dialogInterface, int i, KeyEvent keyEvent) {
                        Log.i("License", "Key Listener");
                        finish();
                        return true;
                    }
                })
                .create();

    }

2.4 Obtenir l'identifiant de votre appareil

Il y a eu un débat à ce sujet dans le passé sur l'utilisation ou non de la série SIM ou TelephonyManager.getDeviceId(); mais il est généralement recommandé d'utiliser le code suivant pour obtenir le Android_ID De votre appareil pour compatibilité maximale.

String deviceId = Secure.getString(getContentResolver(), Secure.Android_ID);
Log.i("Device Id", deviceId);  //AN EXAMPLE OF LOGGING THAT YOU SHOULD BE DOING :)

2.5 Création du vérificateur de licence

une. Avant d'appeler doCheck();, vous devez mettre ce code dans votre application pour vous assurer que tout est correctement créé.

mHandler = new Handler();
mLicenseCheckerCallback = new MyLicenseCheckerCallback();
mChecker = new LicenseChecker(this, new ServerManagedPolicy(this, new   AESObfuscator(SALT, getPackageName(), deviceId)), BASE64_PUBLIC_KEY);

Lorsque je faisais mon implémentation de LVL, j'ai lu que si vous rencontrez des problèmes avec les licences, vous pouvez changer le premier this dans le mChecker = new LicenseChecker(this... En getApplicationContext(), le mien semblait de travailler sans, mais juste au cas où.

2.6 Ajout d'autorisations

une. Vous devez ajouter deux autorisations au fichier manifest de vos applications.

<uses-permission Android:name="Android.permission.INTERNET"/>  
<uses-permission Android:name="com.Android.vending.CHECK_LICENSE"/>        

2.7 Assurez-vous d'avoir les importations appropriées!

Vous l'avez probablement déjà fait, mais je pensais que ce serait un bon endroit pour vérifier.

2.8 Comment appeler la licence à vérifier

une. Appelez simplement doCheck(); chaque fois que vous souhaitez vérifier la licence. Par exemple, si l'application est à sa première exécution, effectuez la vérification.

3. Comment tester la licence pour m'assurer qu'elle fonctionne avant de la publier?

3.1 Configuration de l'appareil de test

une. J'ai mon téléphone personnel que j'utilise également pour les tests. Il est recommandé qu'il n'y ait qu'un seul compte Google enregistré sur le téléphone, historiquement, cela rend les choses un peu plus faciles. Vous pouvez vérifier les comptes en accédant à Settings -> Accounts.

3.2 Configuration de la console développeur

une. Ouvrez votre console développeur et accédez à Settings sur le côté gauche.

b. Trouvez License Testing

c. Assurez-vous que votre adresse e-mail est répertoriée sous Gmail accounts with testing access

ré. Maintenant, vous pouvez changer la réponse du test à ce que vous voulez à des fins de test. L'application doit répondre en conséquence. N'oubliez pas que si vous enregistrez les données via SharedPrefs, vous devrez effacer les données de votre application chaque fois que vous les testez. Assurez-vous de cliquer sur Enregistrer après avoir modifié la réponse du test ou rien ne se passera! J'ai oublié cela plusieurs fois et je me suis retrouvé avec une migraine, puis J'ai vu ce bouton de sauvegarde puant. Lol.

4. Choses à essayer

4.1 Vérification conditionnelle des licences

une. Vous pouvez essayer ce code si vous enregistrez les données didCheck dans SharedPreferences.

 if(didCheck==false){
        Toast.makeText(this, "Checking application license...",     Toast.LENGTH_SHORT).show();
        doCheck();
        Log.i("Checking!", "Checking license!");
    }   

4.2 Chiffrement de votre SharedPreferences à l'aide de SecurePreferences

une. Allez à ceci lien .

b. Copiez et collez le code de SecurePreferences.Java Dans une classe portant exactement le même nom dans votre projet.

c. Lisez le ReadMe.md Pour plus d'informations sur l'implémentation de ceci.

5. Dépannage

Les licences peuvent être un véritable casse-tête à résoudre, simplement parce qu'il y a beaucoup d'autres choses qui peuvent mal tourner. Par exemple, il peut y avoir des problèmes de réseau ou des problèmes de serveur qui vous donnent envie de vous arracher les cheveux. L'utilisation d'une journalisation appropriée vous aidera à cela, vous pouvez également obtenir les codes de réponse du serveur en cas de problème et vous pouvez le suivre jusqu'au serveur ou à votre application. J'ai dû le faire à plusieurs reprises.

5.1 Je ne parviens pas à ce que mon application retourne quoi que ce soit du serveur

Corrections possibles:

une. Assurez-vous que votre application possède la bonne KEY.

b. Assurez-vous que vous enregistrez chaque étape de la progression

c. Consultez votre journal pour tout ce qui concerne le service de licence. Cela peut être utile pour déterminer où quelque chose s'est mal passé.

ré. Assurez-vous que allow() et dontAllow() et applicationError() ont des balises @Override.

5.2 Mon application dit toujours LICENSED ou NOT_LICENSED, Peu importe ce que je l'ai défini dans la réponse du test

une. Le meilleur remède que j'ai pour cela est d'attendre. Il semble que si vous effectuez de nombreux tests en peu de temps, il vous enverra toujours le code du serveur 291 Qui est le code de nouvelle tentative. J'ai attendu toute la nuit et tout a bien fonctionné le lendemain matin.

b. Vous pouvez effacer les données (pas seulement le cache) de l'application Google Play et de l'application Google Play Services. Ouvrez ensuite la sauvegarde, acceptez toutes les licences et réessayez.

c. Effacez les données de votre application.

5.3 Liste des codes de réponse du serveur pour le débogage

Vous devriez obtenir ces valeurs décimales pour int reason Si vous les enregistrez. Utilisez ce tableau pour référencer ce que le serveur envoie réellement à votre application.

LICENSED = Hex: 0x0100, Decimal: 256
NOT_LICENSED = Hex: 0x0231, Decimal: 561
RETRY = Hex: 0x0123, Decimal: 291
LICENSED_OLD_KEY = Hex: 0x2, Decimal: 2
ERROR_NOT_MARKET_MANAGED = Hex: 0x3, Decimal: 3
ERROR_SERVER_FAILURE = Hex: 0x4, Decimal: 4
ERROR_OVER_QUOTA = Hex: 0x5, Decimal: 5
ERROR_CONTACTING_SERVER = Hex: 0x101, Decimal: 257
ERROR_INVALID_PACKAGE_NAME = Hex: 0x102, Decimal: 258 
ERROR_NON_MATCHING_UID = Hex: 0x103, Decimal: 259

5.4 De la place pour plus! Ils viendront!

J'espère que cela vous aide les gars! J'ai essayé de partager mes maux de tête et mes problèmes avec vous du mieux que je peux et j'espère que cela vous aidera!

Si j'ai fait des erreurs, assurez-vous de m'en parler afin que je puisse les corriger dès que possible!

152
Code_Insanity