我想知道在我的Phonegap应用程序开始加载时如何在异步线程中触发Android的LVL许可证验证。如果验证结果为“无法访问”,我希望该应用关闭。 我更喜欢这种逻辑,而不是通常的一步一步设置。 LVL需要几秒钟,如果一个邪恶的未经许可的用户在关闭之前看到应用程序几秒钟,这不是问题。
问题是我对Java不大。
我的应用 我有一个在Google Play中发布的PhoneGap(Cordova)付费应用,它使用LVL验证来检查应用是否由用户付费。像魅力一样工作,除了支票大约需要五秒钟。通常情况下,即使是闪屏也不会显示几秒钟,似乎是因为这一点。
因此,用户在黑屏上停留了五秒钟,然后然后在加载Java代码时获得启动画面,最后他们看到默认的灰色主屏幕,直到Java 脚本已完成。因此,我非常积极地减少启动延迟。
我读过few comments建议使用异步方法:立即开始加载URL,并将许可证检查作为asyncTask运行。但我不知道如何将webview传递给asyncTask,以便在许可证无效时关闭webview。
我的第一次尝试由于许可证检查本身是异步过程,我尝试先设置启动画面并加载URL,然后执行许可证检查。见下面的代码。如果检查返回“不允许”,则回调应该关闭应用程序。但是,如果我尝试此设置,即使我在Google Play上设置了对“无效”或“未知”或其他任何内容的强制响应,LVL服务器总是也会返回“有效”。
我正在寻找A或B: A.一种让LVL正确响应的方法。 B.实现异步许可证检查的另一种方法。
代码以下是当前代码的抽象。 DroidGap是webview。基本上,onCreate启动许可证检查,许可证检查回调加载应用程序的HTML或关闭webview。
public class App extends DroidGap {
public void onCreate(Bundle icicle) {
super.setIntegerProperty("splashscreen", R.drawable.splash);
super.loadUrl("file:///android_asset/www/index.html");
mCheckerCallback = new LicenseCheckerCallback();
checkAccess(mCheckerCallback);
}
private class MyCheckerCallback implements LicenseCheckerCallback() {
public void Allow() {
//Do nothing
}
public void DontAllow(){
finish();
}
}
答案 0 :(得分:0)
package com.phonegap.mappingtheforest.helloworld;
import org.apache.cordova.DroidGap;
//import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.provider.Settings.Secure;
import android.util.Log;
import android.widget.Toast;
import com.android.vending.licensing.AESObfuscator;
import com.android.vending.licensing.LicenseChecker;
import com.android.vending.licensing.LicenseCheckerCallback;
import com.android.vending.licensing.ServerManagedPolicy;
//import com.phonegap.afforditfull.R;
public class App extends DroidGap {
private LicenseChecker mChecker;
private LicenseCheckerCallback mLicenseCheckerCallback;
private static final String BASE64_PUBLIC_KEY = "MyBase64PublicKey";
// Generate 20 random bytes, and put them here.
private static final byte[] SALT = new byte[] {
//[my bunch of integers]
};
private AESObfuscator mObsfuscator;
private String android_id;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
//setContentView(R.layout.main);
super.loadUrl("file:///android_asset/www/index.html",1);
//super.setStringProperty("loadingDialog", "Starting Afford-It...");
super.setIntegerProperty("splashscreen", R.drawable.splash);
android_id = Secure.getString(this.getContentResolver(), Secure.ANDROID_ID);
mObsfuscator = new AESObfuscator(SALT, getPackageName(), android_id);
ServerManagedPolicy serverPolicy = new ServerManagedPolicy(this,mObsfuscator);
mLicenseCheckerCallback = new MyLicenseCheckerCallback();
mChecker = new LicenseChecker(
this, serverPolicy,
BASE64_PUBLIC_KEY // Your public licensing key.
);
mChecker.checkAccess(mLicenseCheckerCallback);
}
private class MyLicenseCheckerCallback implements LicenseCheckerCallback {
public void allow() {
if (isFinishing()) {
// Don't update UI if Activity is finishing.
return;
}
// Should allow user access.
Log.w("LicenseChecker", "Allow");
Intent i = new Intent(App.this, DroidGap.class);
startActivity(i);
finish();
}
public void dontAllow() {
if (isFinishing()) {
// Don't update UI if Activity is finishing.
return;
}
Log.w("LicenseChecker", "Don't Allow");
// Should not allow access. An app can handle as needed,
// typically by informing the user that the app is not licensed
// and then shutting down the app or limiting the user to a
// restricted set of features.
// In this example, we show a dialog that takes the user to Market.
showDialog(0);
}
@Override
public void applicationError(ApplicationErrorCode errorCode) {
if (isFinishing()) {
// Don't update UI if Activity is finishing.
return;
}
toast("Error: " + errorCode.name());
}
}
@Override
protected Dialog onCreateDialog(int id) {
// We have only one dialog.
return new AlertDialog.Builder(this)
.setTitle("Application Not Licensed")
.setCancelable(false)
.setMessage(
"This application is not licensed. Please purchase it from Android Market")
.setPositiveButton("Buy App",
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog,
int which) {
Intent marketIntent = new Intent(
Intent.ACTION_VIEW,
Uri.parse("market://details?id=com.phonegap.mappingtheforest.afforditpaid" + getPackageName()));
startActivity(marketIntent);
finish();
}
})
.setNegativeButton("Exit",
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog,
int which) {
finish();
}
}).create();
}
public void toast(String string) {
Toast.makeText(this, string, Toast.LENGTH_SHORT).show();
}
@Override
public void onDestroy() {
super.onDestroy();
mChecker.onDestroy();
}
}