Search code examples
javaandroidin-app-billing

handleActivityResult: data is null when implementing inapp billing v3


I'm using this implementation: https://github.com/anjlab/android-inapp-billing-v3

Everything by the list (Android Studio, clean project):

  • added dependency to build.gradle
  • added uses-permission android:name="com.android.vending.BILLING" permission to the manifest
  • changed the main activity like this:

_

package com.example.myappnamehere;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.util.Log;

import com.anjlab.android.iab.v3.BillingProcessor;
import com.anjlab.android.iab.v3.TransactionDetails;

public class MainActivity extends Activity implements BillingProcessor.IBillingHandler {

    BillingProcessor bp;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        Log.i("MainActivity", "on Create");
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        bp = new BillingProcessor(this, "[my license key here]", this);
    }

    @Override
    public void onProductPurchased(@NonNull String productId, @Nullable TransactionDetails details) {
        Log.i("MainActivity", "Product purchased");
    }

    @Override
    public void onPurchaseHistoryRestored() {
        Log.i("MainActivity", "Purchase History Restored");

    }

    @Override
    public void onBillingError(int errorCode, @Nullable Throwable error) {
        Log.e("MainActivity", error.getMessage());

    }

    @Override
    public void onBillingInitialized() {
        Log.i("MainActivity", "Billing initialized");
        bp.purchase(MainActivity.this, "[my inapp product id here]");
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        Log.i("MainActivity", "Activity Result");
        if (!bp.handleActivityResult(requestCode, resultCode, data)) {
            super.onActivityResult(requestCode, resultCode, data);
        }
    }
    @Override
    public void onDestroy() {
        Log.i("MainActivity", "Destroy");
        if (bp != null) {
            Log.i("MainActivity", "bp release");
            bp.release();
        }
        super.onDestroy();
    }
}

Manifest just in case:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.myappnamehere">

    <uses-permission android:name="android.permission.INTERNET"/>
    <uses-permission android:name="com.android.vending.BILLING" />

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

I expect it to offer a purchase to me on start or display some kind of error to the console, instead I'm getting this (if running on device):

W/art: Failed execv(/system/bin/dex2oat --runtime-arg -classpath --runtime-arg  --instruction-set=arm64 --instruction-set-features=smp,a53 --runtime-arg -Xrelocate --boot-image=/system/framework/boot.art --non-interactive --runtime-arg -Xms64m --runtime-arg -Xmx512m --instruction-set-variant=generic --instruction-set-features=default --dex-file=/data/app/pro.yakninja.usermobi-1/split_lib_slice_9_apk.apk --oat-file=/data/dalvik-cache/arm64/data@app@com.example.myappnamehere-1@split_lib_slice_9_apk.apk@classes.dex) because non-0 exit status
...
W/System: ClassLoader referenced unknown path: /data/app/com.example.myappnamehere-1/lib/arm64
I/InstantRun: starting instant run server: is main process
I/MainActivity: on Create
D/AccessibilityManager: current package=com.example.myappnamehere, accessibility manager mIsFinalEnabled=false, mOptimizeEnabled=false, mIsUiAutomationEnabled=false, mIsInterestedPackage=false
W/System: ClassLoader referenced unknown path: /system/app/MiuiContentCatcher/lib/arm64
D/OpenGLRenderer: Use EGL_SWAP_BEHAVIOR_PRESERVED: true
I/MainActivity: Billing initialized
I/Adreno: ...
I/OpenGLRenderer: Initialized EGL, version 1.4
I/MainActivity: Activity Result
E/iabv3: handleActivityResult: data is null!

Or this (if running on an emulator):

I/InstantRun: starting instant run server: is main process
I/MainActivity: on Create
D/OpenGLRenderer: HWUI GL Pipeline
D/: HostConnection::get() New Host Connection established 0x9b3e4380, tid 9990
I/OpenGLRenderer: Initialized EGL, version 1.4
D/OpenGLRenderer: Swap behavior 1
W/OpenGLRenderer: Failed to choose config with EGL_SWAP_BEHAVIOR_PRESERVED, retrying without...
D/OpenGLRenderer: Swap behavior 0
D/EGL_emulation: eglCreateContext: 0x9b685120: maj 3 min 0 rcv 3
D/EGL_emulation: eglMakeCurrent: 0x9b685120: ver 3 0 (tinfo 0x9b683290)
D/EGL_emulation: eglMakeCurrent: 0x9b685120: ver 3 0 (tinfo 0x9b683290)

What I've tried and checked so far:

  • Rolled out the app to alpha, added testers. The tester account is different from the app owner's. Visited the opt-in link using tester accounts.
  • Actually installed the app through Play Store, in this case I don't see the console but instead just nothing happens after app is started
  • APK is signed, app key is correct, inapp product id is correct. No whitespace in license key
  • Added android.permission.INTERNET permission to the manifest as well
  • Checked the android-inapp-billing-v3 issue tracker, the problem is not listed there so I guess it's not common and I'm making some kind of a silly beginner mistake or it's related to my system only
  • I'm not very familiar with Android development so in case I have some kind of old dependency problem I've just uninstalled Android Studio and SDK from my machine and installed from scratch
  • Tried making a purchase not in onBillingInitialized but as button-onClick. Gives the same result on device and crashes on emulator as bp is null in this case
  • Tried passing null instead of real license key as it is there in the library example code

Edit: After some suggestions, I've changed the onCreate to this:

@Override
protected void onCreate(Bundle savedInstanceState) {
    Log.i("MainActivity", "on Create");
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    bp = BillingProcessor.newBillingProcessor(this, "[license key]", this); // doesn't bind
    bp.initialize(); // binds

    payButton = (Button)findViewById(R.id.payButton);
    payButton.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            Log.i("MainActivity", "button clicked");

            boolean isAvailable = BillingProcessor.isIabServiceAvailable(v.getContext());
            if(isAvailable) {
                Log.i("MainActivity", "isIabServiceAvailable");
            }
            else {
                Log.e("MainActivity", "isIabService is not Available");

            }

            boolean isOneTimePurchaseSupported = bp.isOneTimePurchaseSupported();
            if(isOneTimePurchaseSupported) {
                Log.i("MainActivity", "OneTimePurchase is supported");
                bp.purchase(MainActivity.this, "android.test.purchased");
            }
            else {
                Log.e("MainActivity", "OneTimePurchase is not supported");
            }
        }
    });
}

Nothing changed. The log output is like this:

I/MainActivity: on Create
I/MainActivity: Billing initialized
I/MainActivity: button clicked
I/MainActivity: isIabServiceAvailable
I/MainActivity: OneTimePurchase is supported
I/MainActivity: Activity Result
E/iabv3: handleActivityResult: data is null!

Solution

  • The problem was in the device. You cannot test the billing on an emulator and it seems that the billing is broken on my device, in other apps as well (they are giving out some kind of "Unknown error" every time I try to pay).

    Apparently, the permissions for the Google Play app or Google services were revoked, after bringing them back from the phone settings - permissions it works fine.