1

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

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

4

1 回答 1

4

我刚刚开始给自己颁发许可,所以不要把这当作福音,但有几件事很突出:

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

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

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

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

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

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

于 2010-10-19T23:53:59.807 回答