我看到了库存的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。找到SDK
SDK管理员顶部列出的安装路径。
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时,我读到,如果您在许可方面遇到问题,可以this
将mChecker = 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我的应用程序总是说LICENSED
或NOT_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。当他们点击设备上的应用程序时,它会自动打开