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 ファイルにプライベート モードで保存されているようです。共有設定エディターを使用して、アプリ内の別の場所から消去できます。

繰り返しますが、私はまだこれのプロではないので、間違っている可能性がありますが、正しく構成されていれば、バグをトラブルシューティングできると思います.

于 2010-10-19T23:53:59.807 に答える