I'm using this implementation: https://github.com/anjlab/android-inapp-billing-v3
Everything by the list (Android Studio, clean project):
uses-permission android:name="com.android.vending.BILLING"
permission to the manifest_
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:
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!
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.