【问题标题】:Android Licensing Server on a device设备上的 Android 许可服务器
【发布时间】:2010-10-18 14:53:03
【问题描述】:

我试图弄清楚整个 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();
}

我只是不知道需要更改什么才能使其正常工作...或者许可证是否以某种方式被缓存(即使这是我第一次在此设备上运行它)以及是否可以取消缓存它无需擦除设备,因为这对于我在其他应用程序上进行测试时会很好。 另外,如何在不点击取消按钮的情况下删除“检查许可证”消息...我应该让它不显示吗?

【问题讨论】:

  • 我有一个问题:如何从 MyLicenseCheckerCallback.allow() 函数中清除在 doCheck() 中调用的 alertbox() 对话框。

标签: android android-lvl


【解决方案1】:

我刚刚获得许可,所以不要把这当作信条,但有几件事很突出:

或者如果许可证以某种方式被缓存(即使这是我第一次在此设备上运行它)并且我可以在不擦除设备的情况下取消缓存它,因为这对我进行测试时会很好其他应用。

您正在使用ServerManagedPolicy,因此批准被缓存和混淆。这是推荐的方法。 (我假设提供更好的用户体验和更好的响应时间)为了调试您的批准,您需要登录到您的market profile 并更改“测试响应”选项。您需要使用与您的发布者配置文件具有相同帐户的设备,以便测试响应适用于尚未发布到市场的应用程序。

您的 MyLicenseCheckerCallback 类的 allow() 方法中也没有代码,这可能是您清除对话框的地方(在 isFinishing 条件之外)。

如果我可以在不擦除设备的情况下取消缓存,因为这对我在其他应用上进行测试时会很好

基于 LicenseValidator.java 看起来批准以私有模式存储在 com.android.vending.licensing.ServerManagedPolicy 的 prefs 文件中。您可以使用sharedpreferences editor 将其从应用中的其他位置清除。

再说一次,我还不是这方面的专家,所以我可能是错的,但我认为如果你配置正确,你可能能够解决你的错误。

【讨论】:

  • 感谢您的回复。我对此也很陌生,对一般的 java/android 编程也很陌生。示例应用程序中是否有 MyLicenseCheckerCallback 的示例?我没有看到它,以及我正在使用的几乎所有 C&P。我再看一遍,看看能找到什么。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-10-27
  • 2014-10-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多