设备上的 Android 授权服务器
我试图弄清楚整个 Android 许可问题,但很沮丧。 在模拟器中,我在没有帐户或不在测试环境中的情况下运行应用程序,它似乎工作正常,返回未许可的响应并弹出立即购买应用程序消息。
当我尝试在实际的 Android 设备上运行它时,它每次都会返回许可,即使设备帐户不是测试环境中的帐户。 此外,即使它返回许可,“检查许可”框也永远不会消失,除非您单击“取消”。然后它就可以让您像获得许可一样使用该应用程序。 示例中主要是 C&P,但有一些更改。我删除了检查许可证按钮和状态文本框。
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mHandler = new Handler();
// Try to use more data here. ANDROID_ID is a single point of attack.
String deviceId = Secure.getString(getContentResolver(), Secure.ANDROID_ID);
// Library calls this when it's done.
mLicenseCheckerCallback = new MyLicenseCheckerCallback();
// Construct the LicenseChecker with a policy.
mChecker = new LicenseChecker(
this, new ServerManagedPolicy(this,
new AESObfuscator(SALT, getPackageName(), deviceId)),
BASE64_PUBLIC_KEY);
doCheck();
ArrayAdapter<String> booksAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, mBooks);
this.setListAdapter(booksAdapter);
}
protected Dialog onCreateDialog(int id) {
// We have only one dialog.
return new AlertDialog.Builder(this)
.setTitle(R.string.unlicensed_dialog_title)
.setMessage(R.string.unlicensed_dialog_body)
.setPositiveButton(R.string.buy_button, 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(R.string.quit_button, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
finish();
}
})
.create();
}
private void doCheck() {
setProgressBarIndeterminateVisibility(true);
alertbox("status", getString(R.string.checking_license));
mChecker.checkAccess(mLicenseCheckerCallback);
}
protected void alertbox(String title, String mymessage)
{
new AlertDialog.Builder(this)
.setMessage(mymessage)
.setTitle(title)
.setCancelable(true)
.setNeutralButton(android.R.string.cancel,
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton){}
})
.show();
}
private void displayResult(final String result) {
mHandler.post(new Runnable() {
public void run() {
alertbox("status", result);
setProgressBarIndeterminateVisibility(false);
}
});
}
private class MyLicenseCheckerCallback implements LicenseCheckerCallback {
public void allow() {
if (isFinishing()) {
// Don't update UI if Activity is finishing.
return;
}
// Should allow user access.
//displayResult(getString(R.string.allow));
}
public void dontAllow() {
if (isFinishing()) {
// Don't update UI if Activity is finishing.
return;
}
//displayResult(getString(R.string.dont_allow));
// Should not allow access. In most cases, the app should assume
// the user has access unless it encounters this. If it does,
// the app should inform the user of their unlicensed ways
// and then either shut down the app or limit the user to a
// restricted set of features.
// In this example, we show a dialog that takes the user to Market.
showDialog(0);
}
public void applicationError(ApplicationErrorCode errorCode) {
if (isFinishing()) {
// Don't update UI if Activity is finishing.
return;
}
// This is a polite way of saying the developer made a mistake
// while setting up or calling the license checker library.
// Please examine the error code and fix the error.
String result = String.format(getString(R.string.application_error), errorCode);
displayResult(result);
}
}
@Override
protected void onDestroy() {
super.onDestroy();
mChecker.onDestroy();
}
我只是不知道需要更改什么才能使其工作...或者许可证是否以某种方式缓存(即使这是我第一次在此设备上运行它)以及是否可以在不擦除的情况下取消缓存设备,因为当我在其他应用程序上进行测试时这会很有用。 另外,如何删除“检查许可证”消息,而不必单击取消按钮......我应该让它不显示吗?
I'm trying to figure out the whole Android licensing thing, and getting frustrated.
In the emulator, I run the app with no account, or one that isn't in the testing environment, and it seems to work correctly, returning the not licensed response and pops up the buy the app now message.
When I try to run it on an actual Android device, it returns licensed every time, even though the device account isn't one that is in the testing environment.
Also, even though it returns licensed, the "checking license" box never goes away, unless you click cancel. Then it just lets you use the app as if it was licensed.
It's mostly C&P from the example, with a few changes. I removed the check license button and the status text box.
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mHandler = new Handler();
// Try to use more data here. ANDROID_ID is a single point of attack.
String deviceId = Secure.getString(getContentResolver(), Secure.ANDROID_ID);
// Library calls this when it's done.
mLicenseCheckerCallback = new MyLicenseCheckerCallback();
// Construct the LicenseChecker with a policy.
mChecker = new LicenseChecker(
this, new ServerManagedPolicy(this,
new AESObfuscator(SALT, getPackageName(), deviceId)),
BASE64_PUBLIC_KEY);
doCheck();
ArrayAdapter<String> booksAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, mBooks);
this.setListAdapter(booksAdapter);
}
protected Dialog onCreateDialog(int id) {
// We have only one dialog.
return new AlertDialog.Builder(this)
.setTitle(R.string.unlicensed_dialog_title)
.setMessage(R.string.unlicensed_dialog_body)
.setPositiveButton(R.string.buy_button, 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(R.string.quit_button, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
finish();
}
})
.create();
}
private void doCheck() {
setProgressBarIndeterminateVisibility(true);
alertbox("status", getString(R.string.checking_license));
mChecker.checkAccess(mLicenseCheckerCallback);
}
protected void alertbox(String title, String mymessage)
{
new AlertDialog.Builder(this)
.setMessage(mymessage)
.setTitle(title)
.setCancelable(true)
.setNeutralButton(android.R.string.cancel,
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton){}
})
.show();
}
private void displayResult(final String result) {
mHandler.post(new Runnable() {
public void run() {
alertbox("status", result);
setProgressBarIndeterminateVisibility(false);
}
});
}
private class MyLicenseCheckerCallback implements LicenseCheckerCallback {
public void allow() {
if (isFinishing()) {
// Don't update UI if Activity is finishing.
return;
}
// Should allow user access.
//displayResult(getString(R.string.allow));
}
public void dontAllow() {
if (isFinishing()) {
// Don't update UI if Activity is finishing.
return;
}
//displayResult(getString(R.string.dont_allow));
// Should not allow access. In most cases, the app should assume
// the user has access unless it encounters this. If it does,
// the app should inform the user of their unlicensed ways
// and then either shut down the app or limit the user to a
// restricted set of features.
// In this example, we show a dialog that takes the user to Market.
showDialog(0);
}
public void applicationError(ApplicationErrorCode errorCode) {
if (isFinishing()) {
// Don't update UI if Activity is finishing.
return;
}
// This is a polite way of saying the developer made a mistake
// while setting up or calling the license checker library.
// Please examine the error code and fix the error.
String result = String.format(getString(R.string.application_error), errorCode);
displayResult(result);
}
}
@Override
protected void onDestroy() {
super.onDestroy();
mChecker.onDestroy();
}
I just don't know what I need to change to make it work... or if the license is somehow cached (even though this is the first time I've run it on this device) and if I can uncache it without wiping the device, as that'll be nice for when I do testing on other apps.
Also, how do I remove the "checking license" message without having to click the cancel button... should I just make it so that it doesn't show up?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我刚刚开始自己获得许可,所以不要将此视为福音,但有几点值得注意:
您正在使用 ServerManagedPolicy,因此批准将 被缓存和混淆。这是推荐的方法。 (我认为可以提供更好的用户体验和更好的响应时间)为了调试您的批准,您需要登录您的 市场概况并更改“测试响应”选项。您需要使用与您的发布商配置文件具有相同帐户的设备来进行测试响应,以便适用于尚未发布到市场的应用程序。
您的 MyLicenseCheckerCallback 类的 allowed() 方法中也没有代码,该类可能应该是您清除对话框的位置(在 isFinishing 条件之外)。
它看起来批准存储在 com.android.vending.licensing.ServerManagedPolicy 的首选项文件中在私人模式下。您可以使用共享首选项编辑器从其他位置清除它该应用程序。
再说一次,我还不是这方面的专业人士,所以我可能是错的,但我认为如果你配置正确,你可能能够解决你的错误。
I'm just getting into licensing myself so don't take this as gospel but a few things stick out:
You are using the ServerManagedPolicy so the approval will be cached and obfuscated. This is the recommended way to do it. ( I assume to provide a better user experience and better response time ) In order to debug your approval you need to log into your market profile and change the "Test response" option. You need to use a device that has the same account as your publisher profile for the test response to work for a app that isn't released to the market yet.
You also have no code in your allow() method for your MyLicenseCheckerCallback class which should probably be where you clear the dialog (outside the isFinishing conditional).
Based on LicenseValidator.java It looks like the approval is stored in a prefs file at com.android.vending.licensing.ServerManagedPolicy in private mode. You can use the sharedpreferences editor to clear it from another place in the app.
Again I'm not a pro on this yet so I could be wrong but I think you might be able to troubleshoot your bug if you get it configured right.