How to do Android licensing checks from a ListActivity
<p>Our application launches ListActivity that displays two menu options with launch a football game and a baseball game.  We are trying to implement licensing and we are having troubles figuring out how to get it working.  Two things are happening here: we are failing to bind to the licensing service (Unable to start service Intent act=com.android.vending.licensing.ILicensingService in logcat) and we are unable to see any of the status messages.  Here is our Launcher code:</p>

<pre><code>public class Launcher extends ListActivity {

    private MenuAdapter mListAdapter;
    private Handler mHandler;
    private TextView mStatusText;
    // protected Button mCheckLicenseButton;

    private LicenseCheckerCallback mLicenseCheckerCallback;
    private LicenseChecker mChecker;

    private static final String BASE64_PUBLIC_KEY = "blah";
    private static final byte[] SALT = new byte[] { 15, -43, -69, 107, 104,
            -111, -105, -76, -18, -24, 62, 118, 45, 67, -89, 70, 79, 123, -3,
            13 };

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
        setContentView(R.layout.launcher_menu);

        mStatusText = (TextView) findViewById(R.id.status_text);

        mHandler = new Handler();

        String android_id = Secure.getString(this.getContentResolver(),
                Secure.ANDROID_ID);

        mLicenseCheckerCallback = new MyLicenseCheckerCallback();

        mChecker = new LicenseChecker(this, new ServerManagedPolicy(this,
                new AESObfuscator(SALT, getPackageName(), android_id)),
                BASE64_PUBLIC_KEY);
        doCheck();
        // We want to see the license check and then launch the menuadapter.
        // mListAdapter = new MenuAdapter(this);
        // this.setListAdapter(mListAdapter);

    }

    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);
                    }
                }).setNegativeButton(R.string.quit_button,
                new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int which) {
                        finish();
                    }
                }).create();
    }

    private void doCheck() {
        // mCheckLicenseButton.setEnabled(false);
        setProgressBarIndeterminateVisibility(true);
        mStatusText.setText(R.string.checking_license);
        mChecker.checkAccess(mLicenseCheckerCallback);
    }

    private void displayResult(final String result) {
        mHandler.post(new Runnable() {
            public void run() {
                mStatusText.setText(result);
                setProgressBarIndeterminateVisibility(false);
                // mCheckLicenseButton.setEnabled(true);
            }
        });
    }

    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));
            // If allowed we should display our menu options
            // mListAdapter = new MenuAdapter(this);
            // this.setListAdapter(mListAdapter);
        }

        public void dontAllow() {
            if (isFinishing()) {
                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 our case, we are failing to bind to the licensing service, so showDialog will always display.
            // Temporarily disable it till we get this working.
            // showDialog(0);
        }

        public void applicationError(ApplicationErrorCode errorCode) {
            if (isFinishing()) {
                // Don't update UI if Activity is finishing.
                return;
            }
            String result = String.format(
                    getString(R.string.application_error), errorCode);
            displayResult(result);

        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        mChecker.onDestroy();
    }

    @Override
    protected void onListItemClick(ListView lv, View v, int position, long id) {
        super.onListItemClick(lv, v, position, id);
        Activity act = (Activity) this.getListAdapter().getItem(position);
        this.startActivity(new Intent(this, act.Class));
    }

}
</code></pre>

<p>All the examples show how to work with an Activity, not a list activity, and this is what is throwing us off.  I'm thinking we need to create a MainActivity which extends Activity that does the check then call the ListActivity if the check is successful.  Does that sound like the correct approach?  </p>

<p>As for failing to bind to the licensing service, this could be network related.  We are testing on a Google API lvl 9 emulator, but we don't get the same failure to bind on the Nexus One or Galaxy Tab.  </p>
