当前位置: 首页 > 面试题库 >

如何为Android应用实现Google Play许可?

毛德华
2023-03-14
问题内容

我看到了库存的Android-Developer许可库说明,但是该概述似乎省略了该过程中的几个关键步骤,并且未能完全说明如何使某些功能正常运行。

有人可以提供一组明确的操作来在Android应用上设置许可库,以便它检查以确保用户在允许使用前已为Google Play中的应用付费吗?


问题答案:

我已经在我的应用程序中实现许可已有一段时间了,终于使它工作了。我想分享一些我认为对入门有用的东西,以及与大家一起发现的一些问题和解决方案。我在下面链接的android
dev教程还可以,但是对我来说并不是那么有用,所以我决定制作一个教程。享受,希望对您有所帮助!

在此处链接到开发人员页面。

1.入门

您将需要的东西。

1.1您的Base64唯一应用程序密钥

如何获得:

一个。转到您的开发者控制台。链接。

b。如果尚未为您的应用程序创建应用程序草稿,请立即执行。

C。创建草稿后,最好将您的照片上传.apk为Alpha或Beta。使其不发布。

d。请点击Services & APIs

e。向下滚动并查找YOUR LICENSE KEY FOR THIS APPLICATION

F。将密钥复制到您的应用中,如下所示:

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

确保没有空格。

1.2盐

一个。什么是盐?

甲酸盐是随机数据即附加的输入散列密码时。它们用于防御字典攻击和彩虹表攻击。

b。我如何得到一个?

这是生成随机盐的良好链接。应该 恰好有
20个随机整数,所以20要输入要生成的随机字符串的数量,每个字符串都应为2字符长(在本示例中使用,不必是)。检查数字,并检查是否允许使用相同的字符串。它们也可以是负数。尝试删除任何冗余,例如00 -> 0,为了保持一致性。

C。我在哪里放盐?

声明变量时,只需输入此代码即可,随机盐除外。

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

2.将LVL(许可)库导入Eclipse和所需的代码

2.1导入库

一个。打开Android SDK Manager

b。去Extras

C。安装Google Play Licensing Library

d。找到SDKSDK管理员顶部列出的安装路径。

e。到达那里后,导航至:<sdk>/extras/google/play_licensing

F。在Eclipse中单击file,然后import,然后Existing Android Code Into Workspace当它问你的文件路径,导航到play_licensing文件夹,点击library

G。library导入名为项目的项目后,右键单击它,然后单击properties。单击Android左侧并导航至底部Is Library,然后选择,然后单击Apply。这使eclipse知道您可以将此项目代码用作库。

H。右键单击要向其添加许可的应用程序,然后单击属性,然后单击Android。转到底部,单击library并将其添加到构建路径。这应该将库导入到Android Dependencies文件夹中。

一世。您的项目已设置为进行下一步。

2.2与您的SALT和一起声明的变量KEY

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

2.3代码

将此代码粘贴到应用程序底部附近。如果许可证无效,此实现将通知用户,并提示他们购买或退出该应用。

    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获取您的设备ID

过去曾有过关于是否使用sim串行或是否使用sim串行的争论,TelephonyManager.getDeviceId();但是通常建议您使用以下代码获取ANDROID_ID设备的sim
以获得最大兼容性。

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

2.5创建许可证检查器

一个。在致电之前,doCheck();您必须将此代码放入您的应用中,以确保正确创建了所有内容。

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

当我执行LVL时,我读到,如果您在许可方面遇到问题,可以thismChecker = new LicenseChecker(this...to中的第一个更改为getApplicationContext(),我的似乎没有它就可以使用,但以防万一。

2.6添加权限

一个。您需要将两个权限添加到应用程序manifest文件中。

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

2.7确保您有正确的进口!

您可能已经完成了此操作,但是我认为这将是您检查的一个好地方。

2.8如何调用要检查的许可证

一个。doCheck();只要您想检查许可证,只需致电。例如,如果应用程序是首次运行,请进行检查。

3.如何在发布许可之前测试许可以确保许可有效?

3.1配置测试设备

一个。我有用于测试的个人电话。建议您仅在手机上注册一个Google帐户,从历史上看,这会使事情变得简单一些。您可以转到来检查帐户Settings -> Accounts

3.2配置开发者控制台

一个。打开开发者控制台,然后转到Settings左侧。

b。找License Testing

C。确保您的电子邮件地址列在Gmail accounts with testing access

d。现在,您可以将测试响应更改为您想要的测试目的。该应用程序应做出相应响应。请记住,如果要通过SharedPrefs保存数据,则每次测试时都需要清除应用程序数据。
请确保在更改测试响应后单击“保存”,否则将不会发生任何事情! 我多次忘记了这一点,最后以偏头痛告终,然后我看到了那个令人讨厌的保存按钮。大声笑。

4.尝试的事情

4.1有条件的许可证检查

一个。如果要将didCheck数据保存在中,可以尝试使用此代码SharedPreferences

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

4.2加密您的SharedPreferences使用SecurePreferences

一个。转到此链接。

b。将代码从中复制并粘贴SecurePreferences.java到名称完全相同的类中,并将其粘贴到您的项目中。

C。阅读ReadMe.md有关实现此功能的信息。

5.故障排除

许可问题可能是令人头疼的故障排除,仅仅是因为还有很多其他事情可能出错。例如,可能存在网络问题或服务器问题,使您想扯掉头发。使用适当的日志记录将对此有所帮助,如果出现问题,您还可以获取服务器响应代码,并将其跟踪到服务器或您的应用程序。我不得不多次这样做。

5.1我无法让我的应用从服务器返回任何内容

可能的修复:

一个。确保您的应用具有正确的KEY

b。确保您记录了进度的每个步骤

C。检查您的日志中是否有许可服务中的任何内容。这对于找出问题出在哪里很有用。

d。确保allow()dontAllow()applicationError()@Override标签

5.2我的应用程序总是说LICENSEDNOT_LICENSED不管我在测试响应中将其设置为什么

一个。我对此的最佳治疗方法就是等待。看来,如果您在短时间内进行了大量测试,它将始终向您发送服务器代码291,即重试代码。我等了一夜,第二天早上一切正常。

b。您可以清除Google Play应用和Google Play服务应用的数据(而不仅仅是缓存)。然后打开播放备份并接受所有许可证,然后重试。

C。清除您的应用数据。

5.3用于调试的服务器响应代码列表

int reason如果将它们记录下来,则应获取这些十进制值。使用此表可以引用服务器实际发送给您的应用的内容。

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还有更多空间! 他们会来!

希望对您有帮助!我尽力与大家分享我的头痛和修复方法,希望对您有所帮助!

如果我有任何错误,请务必告诉我有关它们的信息,以便尽快解决它们!



 类似资料:
  • 有人了解智能锁吗?它是如何工作的? 我想开发一个应用程序,实现在Android应用程序的密码智能锁。 我在跟踪https://developers.google.com/identity/smartlock-passwords/android/. 我已经初始化了< code>GoogleApiClient 生成的<code>凭证 要使用<code>凭据API<code>保存凭据,我使用 我的具有以

  • 问题内容: 在Android应用中实施应用内结算似乎非常复杂。我该怎么办?SDK中的示例应用程序只有一个Activity,对于像我这样的具有多个Activity的应用程序来说,这过于简化了。 问题答案: 好吧,我将尝试解释我的经历。我不认为自己是专家,但是几天我都伤透了脑筋。 对于初学者来说,我很难理解示例和应用程序的工作流程。我认为从一个简单的示例开始应该会更好,但是将代码分成几小段并且不知道是

  • 我是一个初学者,我只是找不到一个可行的解决方案。 我想做的是:用户输入用户名和密码,然后应用程序登录到一个网站。如果登录失败,则返回false和正确消息,否则返回true并继续执行下一个活动(获取另一个站点,解析html并显示内容)。 我的难题是:如何检测成功登录? 这是我的密码 LoginActivity的相关代码: 身份验证类中的方法: 由于我获得了200(OK)状态,我认为POST的代码工作

  • 我正在开发一个Android应用程序。一切都正常运转。我的应用程序已经准备好推出了。但在这里我还需要实现一个特性。我需要显示一个包含 和

  • 我想在我的LibGDX Android游戏中使用Google Play Game Services API的成就和排行榜。我所做的唯一一件事就是从游戏服务开发者网站上获取运行的示例。我已经尝试在我的项目中使用这段代码很多天了,但仍然一无所获。我也尝试过学习本教程http://helios.hud.ac.uk/u1070589/blog/?p=202但我没有“主游戏类(从ApplicationLis

  • 我们将为out项目开发一个增强现实Android应用程序。 我在YouTube上看了几个关于AR的教程,我看到他们使用、、、等。我还看了关于如何使用创建android应用程序的视频。 当他们创建他们想要的AR场景时,例如Unity&Vuforia,他们将其导出到Android设备上,然后在该设备上运行他们的项目。他们不需要使用Android Studio。当他们点击设备上的应用程序时,它会自动打开