代码之家  ›  专栏  ›  技术社区  ›  AndyD273

设备上的Android授权服务器

  •  1
  • AndyD273  · 技术社区  · 14 年前

    在emulator中,我运行的应用程序没有帐户,或者不在测试环境中,它似乎工作正常,返回未授权的响应并弹出“立即购买应用程序”消息。

    当我尝试在实际的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();
    }
    

    另外,如何删除“正在检查许可证”消息而不必单击“取消”按钮。。。我能不能不让它出现?

    1 回复  |  直到 9 年前
        1
  •  4
  •   T. Markle    14 年前

    我只是在给自己发牌,所以不要把这当成福音,但有几件事很突出:

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

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

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

    如果我可以在不擦拭设备的情况下打开它,那么当我在其他应用程序上进行测试时

    基于LicenseValidator.java,审批似乎以私有模式存储在com.android.vending.licensing.ServerManagedPolicy的prefs文件中。你可以使用 sharedpreferences editor 从应用程序中的其他位置清除。