我有一个免费的应用程序,有许多付费升级应用程序,你可以为它购买.基础游戏是免费的,并且仍然是用户始终启动的应用程序,它会检测其他应用程序的存在并根据需要解锁各种升级功能.
我想使用新的许可服务来检测购买的应用程序是否获得许可,并将软件包的名称传递给许可服务以验证它是否已获得授权(并且盲目地遵循示例我愚蠢地假设将包名称传递给混淆器意味着包名称已传递给许可服务器 - oops).然而,我刚刚意识到这是多么愚蠢,无论如何我都碰壁了:"如果您已经免费发布了应用程序,那么您将无法上传包含许可的更新版本(即,一个使用相同包名并包含许可权限的应用程序)".
因此,这是一个由两部分组成的问题:是否有任何计划实施我正在寻找的内容:从免费应用程序内部检查我的其他付费已发布的应用程序是否获得许可?
如果没有,那么实现我所寻求的最佳方式是什么?我想可能会向每个已安装的升级发送一个意图,让他们执行许可检查,然后获得升级以将响应传递回我的基本应用程序.听起来有点乱 - 任何更好的想法?
谢谢你!
我的应用程序是一种袖珍指南,包含全年的一些数据.我假设用户将至少使用该程序一次访问Internet以激活许可证.或者至少这是我对Android许可系统如何工作的理解.我正在使用ServerManagedPolicy.
是否定期检查许可证?有什么办法可以控制吗?我不希望我的用户是在中间的地方,与已经和以前激活,1周,1个月,1年等之后突然应用程序启动限制了应用程序的可用性的应用程序本身,因为许可证couldn" 再次验证.我的应用程序将要和不稳定的网络访问偏僻的地方,使用的人谁就会生活在那里几个星期,也许几个月(不能想当然所有的时间).
我觉得我应该至少警告他们每隔X周就要问他们这样做.许可证制度是否是严厉的?
我知道我可以在applicationCheckerCallback的applicationError void上使用ERROR_CONTACTING_SERVER标志来处理错误."VT"响应是否始终相同(无法在测试帐户/我的帐户上测试)?我只是好奇你们如何在自己的现实应用程序中处理这种情况.我在这里错过了什么吗?出于某种原因,我感觉自己是.有没有"捕获"?
//编辑:
这是我正在尝试的代码:
// ServerManagedPolicy.java
private void setValidityTimestamp(String validityTimestamp) {
Long lValidityTimestamp;
try {
lValidityTimestamp = Long.parseLong(validityTimestamp);
} catch (NumberFormatException e) {
// No response or not parsable, expire in one minute.
Log.w(TAG, "License validity timestamp (VT) missing, caching for a minute");
lValidityTimestamp = System.currentTimeMillis() + MILLIS_PER_MINUTE;
validityTimestamp = Long.toString(lValidityTimestamp);
}
// added by me--->
private static long maxLicense = 1000 * 3600 * 24 * 30; // ~ roughly 30 days
private static …Run Code Online (Sandbox Code Playgroud) 我正在尝试使用Proguard对付我的应用程序,最终将整合LVL和应用程序内结算.我遇到的问题是Proguard在启动时不断崩溃我的应用程序,很难弄清楚什么是失败的.
我正在使用Android V4支持兼容库,它似乎正在吹走该库以及其他一些东西.
有没有人有一个proguard.cfg适用于初学者的v4 compat库的基本版本?
目前我使用的股票proguard.cfg不起作用.
-optimizationpasses 5
-dontusemixedcaseclassnames
-dontskipnonpubliclibraryclasses
-dontpreverify
-verbose
-optimizations !code/simplification/arithmetic,!field/*,!class/merging/*
-keep public class * extends android.app.Activity
-keep public class * extends android.app.Application
-keep public class * extends android.app.Service
-keep public class * extends android.content.BroadcastReceiver
-keep public class * extends android.content.ContentProvider
-keep public class * extends android.app.backup.BackupAgentHelper
-keep public class * extends android.preference.Preference
-keep public class com.android.vending.licensing.ILicensingService
-keepclasseswithmembernames class * {
native <methods>;
}
-keepclasseswithmembernames class * {
public <init>(android.content.Context, android.util.AttributeSet);
}
-keepclasseswithmembernames class * {
public …Run Code Online (Sandbox Code Playgroud) android proguard android-lvl android-fragments android-support-library
是的,所以,我知道,这不是"程序员"的问题:)但客户有时会帮助我们(开发者)使用我们的代码,所以我们(开发者)应该感激不尽.我认为回答我的问题对所有Android开发者都很有用.
用户购买了我的应用.退款期(15分钟)当然结束了.现在我想把钱还给他作为礼物,因为他帮我测试了一点.
如果我在Checkout中退还整个订单 - >订单将用户保持我的应用程序'已购买'?我的意思是他能够从GooglePlay-> MyApps再次卸载并安装它,并将app标记为"已购买"?谷歌LVL会接受他运行该应用程序吗?
我以前做过这样的退款,但后来他们称之为"Android Market",退款时间是12小时,而且没有LVL.也许有人知道使用Google Play制作小礼物的另一种方式?
我一直在研发已发布到Google Play的Android应用.对于下一次更新(versionCode = 3),我的客户希望包含LVL许可方案.
我做的第一件事是从许可服务器设置静态测试响应.我将测试响应设置为LICENSED.在文档中阅读后:
对于您上传到Google Play的应用程序,此许可证测试响应将使用[我的电子邮件地址]或上面列出的测试帐户发送给设备.>此外,此帐户(但不是测试帐户)将收到>尚未上传到Google Play的应用程序的此响应.
我想,这不是问题,因为我的开发者帐户电子邮件与我的测试设备上的Google Play帐户电子邮件相同.所以我应该在调试App时收到测试响应.
之后,我阅读了所有其他许可文档和示例代码,并将其集成到App中.我使用带有正确base64公钥的ServerManagedPolicy和20个随机生成的字节作为salt.
一旦一切看起来都很好我将其上传到设备进行测试,但是我没有收到我期望的LICENSED响应,而是一直收到NOT_LICENSED响应.我回去确认:
起初,我想也许它与缓存有关,所以我尝试使用StrictPolicy.相同的回应.由于我没有从商店购买应用程序,我的印象是许可服务器正常响应而不是发送静态测试响应.以下是我尝试的其他一些事情:
这使我相信许可证服务器始终正常响应,而不是将我设置的静态测试响应发送到我的开发人员帐户.我有一种感觉,可能是因为App已经发布了,但我不能冒险发布调试版本只是为了测试是否有效.
以前有没有人遇到这种情况?任何帮助是极大的赞赏.
我通过阅读官方说明实施了Google许可检查程序.
import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.os.IBinder;
import android.provider.Settings.Secure;
import android.widget.Toast;
import com.google.android.vending.licensing.AESObfuscator;
import com.google.android.vending.licensing.LicenseChecker;
import com.google.android.vending.licensing.LicenseCheckerCallback;
import com.google.android.vending.licensing.ServerManagedPolicy;
public class Splash extends Activity {
MyLicenseCheckerCallback mLicenseCheckerCallback;
LicenseChecker mChecker;
byte[] SALT = new byte[] { -73, 95, 70, -126, -103, -57, 14, -46, 51, 88, -5,
-60, 77, -88, -63, -13, -1, 82, -4, 9 };
//Handler mHandler;
String BASE64_PUBLIC_KEY="My base key";
Context mContext;
IBinder serviceBinder;
String deviceId; …Run Code Online (Sandbox Code Playgroud) 该应用程序已获得用户许可,但有一个更新的应用程序版本可用不同的密钥签名.
如果在不使用匹配证书的情况下签署新版本,则还需要为应用程序分配不同的包名称 - 在这种情况下,用户将新版本安装为全新的应用程序.
由于应用程序由其包名称标识,因此这似乎表示您无法更改已发布应用程序的签名密钥.(相反,您可以更改密钥和包,但随后它将被市场视为新的应用程序.)
我想不出可以收到LICENSED_OLD_KEY回复的情况.我错过了什么吗?
我想为我的应用程序添加许可证(使用LVL)并在模拟器上测试它.我是android的新手.任何人都可以帮助我,并通过简单的hello world应用程序向我解释.TIA
所以我使用 flutter 进行应用程序开发(显然,标题),这是一个付费应用程序,因此需要验证许可证。我正在使用 MedthodChannel 来实现此目的,因为我无法找到颤振本身的方法。
现在的问题是:所以在Java方面,我正在检查许可证验证,然后将结果发送到flutter。这就是方法通道的工作原理。但问题是,即使在验证完成之前,结果也会发送到 flutter,因此 flutter 部分认为许可证没有经过验证,即使是这样。
我在下面附上java端代码
包在.navkargems.diamondtools;
导入 android.os.Bundle;
导入 android.os.Handler;
导入 android.provider.Settings;
导入 android.util.Log;
导入 com.google.android.vending.licensing.LicenseChecker;
导入 com.google.android.vending.licensing.LicenseCheckerCallback;
导入 com.google.android.vending.licensing.StrictPolicy;
导入 io.flutter.app.FlutterActivity;
导入 io.flutter.plugin.common.MethodCall;
导入 io.flutter.plugin.common.MethodChannel;
导入 io.flutter.plugins.GeneratePluginRegistrant;
公共类 MainActivity 扩展 FlutterActivity {
私有静态最终字符串CHANNEL =“in.navkargems.diamondtools/verify”;
私有静态最终字符串_key_to_verify_base64 =“MIIBIjAN ...”;
私有处理程序mHandler;
私有许可证检查器 mChecker;
私有 LicenseCheckerCallback mLicenseCheckerCallback;
布尔许可;
布尔检查许可证;
布尔值 didCheck;
int 消息 = 0;
@覆盖
protected void onCreate(Bundle savingInstanceState) {
super.onCreate(savedInstanceState);
generatedPluginRegistrant.registerWith(this);
new MethodChannel(getFlutterView(), CHANNEL).setMethodCallHandler(
新的 MethodChannel.MethodCallHandler() {
@覆盖
公共无效onMethodCall(MethodCall methodCall,MethodChannel.Result结果){
if (methodCall.method.equals("verifyLicense")) {
String deviceId = … 很多年前就有很多关于将现有付费应用程序迁移到使用应用程序内购买的免费增值模式的主题的老问题和答案,但它们都只是陈述了相同的有限解决方法。
那么2019年有官方的方法可以做到这一点吗?或者至少是一种避免常见陷阱的方法,例如
对用户体验的负面影响
当用户购买新设备时最终会失败
SharedPreferences还有其他同样有缺陷的方法,甚至不值得一提。正确且简单的修复当然是对 Google Play 服务的简单 API 调用:
bool legacyPremiumUser = didUserEverPurchaseThisApp();
Run Code Online (Sandbox Code Playgroud)
今天还存在这样的事情吗?即使只是一种跨设备识别用户的方法也是可以接受的。
android in-app-purchase android-lvl google-play google-play-services
android-lvl ×10
android ×9
google-play ×3
java ×3
code-signing ×1
emulation ×1
flutter ×1
license-key ×1
licensing ×1
proguard ×1