Android IAB: Billing service unavailable on device
Asked Answered
R

2

3

I am trying to implement IAB in my app. Each time the app starts, the start up fails with:

Problem setting up In-app Billing: IabResult: Billing service unavailable on device. (response: 3:Billing Unavailable)

I've tried literally everything:

  • Ensuring I have the com.android.vending.BILLING permission in the manifest.
  • Uploading the APK to the beta channel with both versions corresponding.
  • Using test accounts.
  • Clearing the Google Play cache.
  • Making sure I have the latest Google Play services in my build.gradle.
  • Double-checking the public encoded key.
  • Using multiple devices.

But no matter what, the error still persists. I've read all the SO questions & answers about it but I can't figure out what am I missing!

Here is my relevant code:

 public class MainActivity extends AppCompatActivity {

    IabHelper       mHelper; 

    @Override protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mHelper = new IabHelper(this, Billing.ENCODED_PUBLIC_KEY);
        mHelper.startSetup(new IabHelper.OnIabSetupFinishedListener() {
            public void onIabSetupFinished(IabResult result) {
                if (!result.isSuccess()) {
                    // Oh noes, there was a problem.
                    Log.d("LOG", "Problem setting up In-app Billing: " + result);
                }
                // Hooray, IAB is fully set up!
            }
        });
        final SharedPreferences saved_values = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
        IabHelper.QueryInventoryFinishedListener mGotInventoryListener
                = new IabHelper.QueryInventoryFinishedListener() {
            public void onQueryInventoryFinished(IabResult result, Inventory inventory) {
                if (result.isFailure()) {
                    SettingsActivity.premium = saved_values.getBoolean("premium",false);
                }
                else {
                    // does the user have the premium upgrade?
                    SettingsActivity.premium = inventory.hasPurchase(Billing.SKU_PREMIUM);
                    // update UI accordingly
                }
            }
        };
        try{
            mHelper.queryInventoryAsync(mGotInventoryListener);
        }
        catch (Exception e){
            SettingsActivity.premium = saved_values.getBoolean("premium",false);
        }
    }



    @Override public void onDestroy() {
        super.onDestroy();
       if (mHelper != null)
            mHelper.dispose();
        mHelper = null;
    }



    @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        Log.i("LOG", "onActivityResult(" + requestCode + "," + resultCode + "," + data);

        // Pass on the activity result to the helper for handling
        if (!mHelper.handleActivityResult(requestCode, resultCode, data)) {
            super.onActivityResult(requestCode, resultCode, data);
        }
        else {
            Log.i("LOG", "onActivityResult handled by IABUtil.");
        }
    }

Here is the console output:

03-11 20:35:27.896 710-710/? W/ActivityManager: Permission Denial: getCurrentUser() from pid=14441, uid=10189 requires android.permission.INTERACT_ACROSS_USERS
03-11 20:35:28.516 14441-14441/com.johan.app D/LOG: Problem setting up In-app Billing: IabResult: Billing service unavailable on device. (response: 3:Billing Unavailable)
03-11 20:35:28.516 14441-14441/com.johan.app E/IabHelper: In-app billing error: Illegal state for operation (queryInventory): IAB helper is not set up.

Note that I have code querying the inventory somewhere else, but the fact that it doesn't go beyond mHelper.startUpSetup() makes it irrelevant.

Radiance answered 11/3, 2016 at 18:55 Comment(1)
Have you activated your SKU's on Google Play Developer Console ?Break
B
4

Try this! Go to the IabHelper class, in startSetup method under onServiceConnected callback you can see an Intent. Just replace with the below code. (or just Find for BILLING_RESPONSE_RESULT_BILLING_UNAVAILABLE).

Intent serviceIntent = new Intent("com.android.vending.billing.InAppBillingService.BIND");
serviceIntent.setPackage("com.android.vending");
if (!mContext.getPackageManager().queryIntentServices(serviceIntent, 0).isEmpty()) {
    // service available to handle that Intent
    mContext.bindService(serviceIntent, mServiceConn, Context.BIND_AUTO_CREATE);
} else {
    // no service available to handle that Intent
    if (listener != null) {
        listener.onIabSetupFinished(
        new IabResult(BILLING_RESPONSE_RESULT_BILLING_UNAVAILABLE, "Billing service unavailable on device."));
    }
}
Break answered 14/3, 2016 at 16:54 Comment(1)
I solved this a whole ago and it was precisely this. Thanks.Radiance
M
-1

if you target android 31 put this in manifest :

<permission android:name="android.permission.QUERY_ALL_PACKAGES" />

<queries>
    <intent>
        <action android:name="android.intent.action.MAIN" />
    </intent>
</queries>
Mode answered 27/4, 2022 at 6:35 Comment(2)
That did not work and QUERY_ALL_PACKAGES permissions is a sensitive permission. If you use that permission. your app will be blocked from release without a justifiable cause.Dev
remove/comment for build, this is a problem only for debug/develop phase, if you pass it to the build, it will be rejected for publish, not "blocked", this is the only solution for apps targeting android 31, otherwise you have to debug your app on a deviceCerement

© 2022 - 2024 — McMap. All rights reserved.