1
votes

First of all I have read all of the questions with this title but non of them helps me :-(

I have to connect to a base app with my client app and using a permission. If I install client app first and then the base app I get above exception. how can I solve this? If I remove my client app and install it again the issue is solved but how can I tell this to my customers, how can I prevent them from installing client app if the base app has not installed?

at Mypackage.IssueFirstLookActivity.onCreate(IssueFirstLookActivity.java:443) is: mHelper.startSetup(new OnIabSetupFinishedListener()

at Mypackage.IabHelper.startSetup(IabHelper.java:269) is (mContext.bindService(serviceIntent, mServiceConn, Context.BIND_AUTO_CREATE);)

List<ResolveInfo> queryIntentServices = mContext.getPackageManager().queryIntentServices(serviceIntent, 0);
    if (queryIntentServices != null && !queryIntentServices.isEmpty()) {
        // service available to handle that Intent
        mContext.bindService(serviceIntent, mServiceConn, Context.BIND_AUTO_CREATE);
    }

and

mHelper = new IabHelper(this,mBase64EncodedPublicKey);

    if(myContext.getState() == MyContext.LOGIN_HAS_NOT_PURCHASED_STATE ){
        //      if(1==1){
        mHelper.startSetup(new OnIabSetupFinishedListener() {

            @Override
            public void onIabSetupFinished(IabResult result) {

                // if we were disposed of in the meantime, quit.
                if (mHelper == null) return;

                if (!result.isSuccess()) {
                    // Oh noes, there was a problem.
                    Log.d(TAG, "Problem setting up In-app Billing: " + result);

                    Toast.makeText(IssueFirstLookActivity.this, "Error " + result.toString() ,Toast.LENGTH_LONG).show();

                    // TODO user has not bazaar
                }else{
                    // Hooray, IAB is fully set up!
                    // TODO my new thing
                    //mHelper.queryInventoryAsync(mGotInventoryListener);


                }
            }
        });

Stack trace:

04-10 10:44:42.170: E/AndroidRuntime(2316): FATAL EXCEPTION: main
04-10 10:44:42.170: E/AndroidRuntime(2316): java.lang.RuntimeException: Unable to start activity ComponentInfo{Mypackage.IssueFirstLookActivity}: java.lang.SecurityException: Not allowed to bind to service 
Intent { act="Base app permission" pkg=base app package }
04-10 10:44:42.170: E/AndroidRuntime(2316):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2211)
04-10 10:44:42.170: E/AndroidRuntime(2316):     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2261)
04-10 10:44:42.170: E/AndroidRuntime(2316):     at android.app.ActivityThread.access$600(ActivityThread.java:141)
04-10 10:44:42.170: E/AndroidRuntime(2316):     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1256)
04-10 10:44:42.170: E/AndroidRuntime(2316):     at android.os.Handler.dispatchMessage(Handler.java:99)
04-10 10:44:42.170: E/AndroidRuntime(2316):     at android.os.Looper.loop(Looper.java:137)
04-10 10:44:42.170: E/AndroidRuntime(2316):     at android.app.ActivityThread.main(ActivityThread.java:5103)
04-10 10:44:42.170: E/AndroidRuntime(2316):     at java.lang.reflect.Method.invokeNative(Native Method)
04-10 10:44:42.170: E/AndroidRuntime(2316):     at java.lang.reflect.Method.invoke(Method.java:525)
04-10 10:44:42.170: E/AndroidRuntime(2316):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:737)
04-10 10:44:42.170: E/AndroidRuntime(2316):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
04-10 10:44:42.170: E/AndroidRuntime(2316):     at dalvik.system.NativeStart.main(Native Method)
04-10 10:44:42.170: E/AndroidRuntime(2316): Caused by: java.lang.SecurityException: Not allowed to bind to service Intent { act="Base app permission" pkg=base app package }
04-10 10:44:42.170: E/AndroidRuntime(2316):     at android.app.ContextImpl.bindServiceAsUser(ContextImpl.java:1478)
04-10 10:44:42.170: E/AndroidRuntime(2316):     at android.app.ContextImpl.bindService(ContextImpl.java:1448)
04-10 10:44:42.170: E/AndroidRuntime(2316):     at android.content.ContextWrapper.bindService(ContextWrapper.java:496)
04-10 10:44:42.170: E/AndroidRuntime(2316):     at Mypackage.IabHelper.startSetup(IabHelper.java:269)
04-10 10:44:42.170: E/AndroidRuntime(2316):     at Mypackage.IssueFirstLookActivity.onCreate(IssueFirstLookActivity.java:443)
04-10 10:44:42.170: E/AndroidRuntime(2316):     at android.app.Activity.performCreate(Activity.java:5133)
04-10 10:44:42.170: E/AndroidRuntime(2316):     at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1087)
04-10 10:44:42.170: E/AndroidRuntime(2316):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2175)
04-10 10:44:42.170: E/AndroidRuntime(2316):     ... 11 more
1
There is no solution to this problem. I remember reading a very good answer from Commonsware about exactly this issue. The gist of it was: regardless of what you do to try and some it there will always be a problem. The order of how you install the Apps will always matter. And there is no way to get around that. It is a consequence of how android works. If you really want to get rid of this issue them you have to rethink everything you do and implement it without using custom permissions. - Xaver Kapeller
@CommonsWare I have added, thank you. - mmlooloo
@XaverKapeller thanks for the link. - mmlooloo
and You get this exception immediately after openening or installing? - Opiatefuchs

1 Answers

2
votes

If I am interpreting your redacted Intent correctly, it at least has the package in it, which means the Android 5.0 "can't bind to an implicit Intent" problem should not matter. OTOH, I had expected something more about permissions in the error if you lacked a permission.

If the client app and the base app are both yours, particularly on Android 5.0+, you could put the <permission> element in both apps, and you should be fine. The security flaw that Xaver Kapeller pointed out in the comments is because, prior to Android 5.0, any app could try redefining your custom permission. If, however, the client app and the base app are from different authors, or otherwise have different signing keys, they cannot both attempt to declare the <permission>.

but how can I tell this to my customers,

Assuming that you cannot have both apps declare the <permission>...

Option #1: Don't have multiple apps in the first place trying to connect this way.

Option #2: Explain very very carefully in the product listing (e.g., Play Store).

Option #3: Look for your base app when your client app runs (via PackageManager) and explain to the user that the client app is really a plugin to the base app and therefore the base app needs to be installed first.

how can I prevent them from installing client app if the base app has not installed?

Only by not having two apps in the first place.