Android billingclient API version

Hi,

When I try to upload an app with InAppPurchases to the Play Store, it gets blocked because of an old version of the billing client API. It requires a minimum version 3, while the Projucer generates a dependency to v 2.1.0.

I tried manually changing the version to 3.0.3 in the build.gradle and it seems to work fine. Also gets accepted.

But can you confirm that this is sufficient? Any other changes required?

Best wishes,

Mariano

1 Like

+1

As of November 2021, the billing lib v2.1.0 is no longer accepted by Google; the minimum is version 3 and soon will be version 4.

It would be awesome if the projucer could be updated accordingly!

BTW: running JUCE 6 in combination with the Android billing API v4 doesn’t seem to work (app crashes immediately) - likely because of API changes that need an update to some of the JUCE functions that use the API.

1 Like

It seems that if you change the billingAPI to version 3.x, any calls to InAppPurchases::getInstance()->consumePurchase() will cause the app to crash immediately.

If the JUCE team could update the Google billing APIs to support the minimum version required by the Google play store (v3) or even better, support the next version (v4) that would be highly appreciated!

1 Like

Hello !

I’m dealing with the same problem (Billing Client update).
Please help…

Thanks

Hi,

It works if I manually changing the version to 3.0.1 in the build.gradle. Purchase Ok.

Problem. After InAppPurchases::purchaseProduct, then Google Play (Store) window, and press Back button (in Navigation Bar Android), I return to my App, everything works, but after that:

  • JUCEApplicationBase::quit(); App crashing !
  • ContentSharer::getInstance()->shareFiles… App crashing !
  • URL.launchInDefaultBrowser(); App crashing !

Does anyone have a solution ?
Does anyone have an app with a inAppPurchases that works on Android?
Thanks

Hello,

I’m dealing with the same problem with my app.

Please consider providing a solution.

Thank you

I’m using v 3.0.3, seems to work fine.

Thanks swar !!
3.0.3 not working in my app (same problems, quit(), shareFiles() and launchInDefaultBrowser() crash…
Do you have shareFiles() and launchInDefaultBrowser() in your app ?

(ps: Everything work on iOS, thanks Juce for the 6.1.5 iOS improvement)

I’m simply using InAppPurchases::getInstance()->purchaseProduct(IAP_PREMIUM_CODE, “”) in the native code.

Only difference is that the action triggering (the JNI native function) is a button in a Java dialog. I used that option because I needed to display an HTML page, and this is done more fluidly using a Java dialog.

Ok, thanks Swar

Android debug when I press Back button (in Navigation Bar Android, or X close Buttton) :
2022-02-11 13:00:19.770 30733-30733/com.toool W/ProxyBillingActivity: Activity finished with resultCode 0 and billing’s responseCode: 1

2022-02-11 13:00:19.828 30733-30733/com.toool D/ColorViewRootUtil: initSwipState, isDisplayCompatApp false

2022-02-11 13:00:19.830 30733-30733/com.toool D/ColorViewRootUtil: mScreenHeight 2400, mScreenWidth 1080

2022-02-11 13:00:19.832 30733-30733/com.toool D/ColorViewRootUtil: initSwipState, isDisplayCompatApp false

2022-02-11 13:00:19.834 30733-30733/com.toool D/ColorViewRootUtil: mScreenHeight 2400, mScreenWidth 1080

2022-02-11 13:00:19.836 30733-30733/com.toool W/BillingHelper: Couldn’t find purchase lists, trying to find single data.

2022-02-11 13:00:19.836 30733-30733/com.toool W/BillingHelper: Received a bad purchase data.

2022-02-11 13:00:19.836 30733-30733/com.toool W/BillingHelper: Couldn’t find single purchase data as well.

2022-02-11 13:00:19.938 30733-30733/com.toool I/Choreographer: Skipped 9 frames! The application may be doing too much work on its main thread.

2022-02-11 13:00:19.941 30733-30733/com.toool I/OboeAudio: openStream() OUTPUT -------- OboeVersion1.6.1 --------

2022-02-11 13:00:19.941 30733-30733/com.toool I/AAudio: AAudioStreamBuilder_openStream() called ----------------------------------------

2022-02-11 13:00:19.941 30733-30733/com.toool I/AudioStreamBuilder: rate = 48000, channels = 2, format = 5, sharing = EX, dir = OUTPUT

2022-02-11 13:00:19.941 30733-30733/com.toool I/AudioStreamBuilder: device = 0, sessionId = -1, perfMode = 12, callback: ON with frames = 0

2022-02-11 13:00:19.941 30733-30733/com.toool I/AudioStreamBuilder: usage = 1, contentType = 2, inputPreset = 6, allowedCapturePolicy = 0

2022-02-11 13:00:19.941 30733-30733/com.toool D/: PlayerBase::PlayerBase()

2022-02-11 13:00:19.948 30733-30733/com.toool D/: PlayerBase::~PlayerBase()

2022-02-11 13:00:19.948 30733-30733/com.toool D/: PlayerBase::PlayerBase()

2022-02-11 13:00:19.948 30733-30733/com.toool D/AudioStreamTrack: open(), request notificationFrames = -8, frameCount = 0

2022-02-11 13:00:19.949 30733-30733/com.toool D/mmscene: getHint applicationScene=com.toool,idx=5 none

2022-02-11 13:00:19.949 30733-30733/com.toool D/OppoSmartVolume: mEnginerringFeatureSwtich:1, mSmartVolumeAPKSwtich:-22, mSmartVolumePcmDumpSwitch:0

2022-02-11 13:00:19.949 30733-30733/com.toool D/OppoSmartVolume: mWechatDbLevel:19, mWechatUseDynamicMode:1

2022-02-11 13:00:19.949 30733-30733/com.toool D/IAtlas: IAtlas::init CallingPid 30733

2022-02-11 13:00:19.949 30733-30733/com.toool D/IAtlas: IAtlas::init this 0x7456d26ce0

2022-02-11 13:00:19.949 30733-30733/com.toool D/AudioTrack: set() streamType -1, sampleRate 48000, format 0x5, channelMask 0x3, frameCount 0, flags #104, notificationFrames -8, sessionId 0, transferType 1, uid -1, pid -1 cbf 1

2022-02-11 13:00:19.949 30733-30733/com.toool D/AudioTrack: gATLogLevel = 0

2022-02-11 13:00:19.955 30733-30733/com.toool D/AudioTrack: createTrack state 0 output.outputId=13

2022-02-11 13:00:19.956 30733-30733/com.toool I/AudioTrack: createTrack_l(0): AUDIO_OUTPUT_FLAG_FAST successful; frameCount 0 → 1536

2022-02-11 13:00:19.956 30733-30733/com.toool D/AudioTrack: setVolume left 1.000 right 1.000

2022-02-11 13:00:19.957 30733-30733/com.toool W/AudioStreamTrack: open() flags changed from 0x00000104 to 0x00000004

2022-02-11 13:00:19.959 30733-30733/com.toool I/AAudio: AAudioStreamBuilder_openStream() returns 0 = AAUDIO_OK for s#10 ----------------

2022-02-11 13:00:19.959 30733-30733/com.toool D/OboeAudio: AudioStreamAAudio.open() format=2, sampleRate=48000, capacity = 1536

2022-02-11 13:00:19.959 30733-30733/com.toool D/OboeAudio: AudioStreamAAudio.open: AAudioStream_Open() returned AAUDIO_OK

2022-02-11 13:00:19.959 30733-30733/com.toool D/AAudio: AAudioStream_requestStop(s#10) called

2022-02-11 13:00:19.959 30733-30733/com.toool D/: PlayerBase::stop() from IPlayer

2022-02-11 13:00:19.969 30733-30733/com.toool D/AAudio: AAudioStream_close(s#10) called ---------------

2022-02-11 13:00:19.969 30733-30733/com.toool D/AudioTrack: ~AudioTrack, releasing mStatus =0 session id 14145 from 30733 on behalf of 30733

2022-02-11 13:00:19.971 30733-30733/com.toool D/AAudio: AAudioStream_close(s#10) returned 0 ---------

2022-02-11 13:00:19.974 30733-30733/com.toool I/OboeAudio: openStream() OUTPUT -------- OboeVersion1.6.1 --------

2022-02-11 13:00:19.974 30733-30733/com.toool I/AAudio: AAudioStreamBuilder_openStream() called ----------------------------------------

2022-02-11 13:00:19.974 30733-30733/com.toool I/AudioStreamBuilder: rate = 48000, channels = 2, format = 5, sharing = EX, dir = OUTPUT

2022-02-11 13:00:19.974 30733-30733/com.toool I/AudioStreamBuilder: device = 0, sessionId = -1, perfMode = 12, callback: ON with frames = 0

2022-02-11 13:00:19.974 30733-30733/com.toool I/AudioStreamBuilder: usage = 1, contentType = 2, inputPreset = 6, allowedCapturePolicy = 0

2022-02-11 13:00:19.974 30733-30733/com.toool D/: PlayerBase::PlayerBase()

2022-02-11 13:00:19.980 30733-30733/com.toool D/: PlayerBase::~PlayerBase()

2022-02-11 13:00:19.980 30733-30733/com.toool D/: PlayerBase::PlayerBase()

2022-02-11 13:00:19.980 30733-30733/com.toool D/AudioStreamTrack: open(), request notificationFrames = -8, frameCount = 0

2022-02-11 13:00:19.982 30733-30733/com.toool D/mmscene: getHint applicationScene=com.toool,idx=5 none

2022-02-11 13:00:19.982 30733-30733/com.toool D/OppoSmartVolume: mEnginerringFeatureSwtich:1, mSmartVolumeAPKSwtich:-22, mSmartVolumePcmDumpSwitch:0

2022-02-11 13:00:19.982 30733-30733/com.toool D/OppoSmartVolume: mWechatDbLevel:19, mWechatUseDynamicMode:1

2022-02-11 13:00:19.982 30733-30733/com.toool D/IAtlas: IAtlas::init CallingPid 30733

2022-02-11 13:00:19.982 30733-30733/com.toool D/IAtlas: IAtlas::init this 0x7456d26c00

2022-02-11 13:00:19.982 30733-30733/com.toool D/AudioTrack: set() streamType -1, sampleRate 48000, format 0x5, channelMask 0x3, frameCount 0, flags #104, notificationFrames -8, sessionId 0, transferType 1, uid -1, pid -1 cbf 1

2022-02-11 13:00:19.982 30733-30733/com.toool D/AudioTrack: gATLogLevel = 0

2022-02-11 13:00:19.991 30733-30733/com.toool D/AudioTrack: createTrack state 0 output.outputId=13

2022-02-11 13:00:19.992 30733-30733/com.toool I/AudioTrack: createTrack_l(1342): AUDIO_OUTPUT_FLAG_FAST successful; frameCount 0 → 1536

2022-02-11 13:00:19.992 30733-30733/com.toool D/AudioTrack: setVolume left 1.000 right 1.000

2022-02-11 13:00:19.992 30733-30733/com.toool W/AudioStreamTrack: open() flags changed from 0x00000104 to 0x00000004

2022-02-11 13:00:19.994 30733-30733/com.toool I/AAudio: AAudioStreamBuilder_openStream() returns 0 = AAUDIO_OK for s#12 ----------------

2022-02-11 13:00:19.994 30733-30733/com.toool D/OboeAudio: AudioStreamAAudio.open() format=2, sampleRate=48000, capacity = 1536

2022-02-11 13:00:19.994 30733-30733/com.toool D/OboeAudio: AudioStreamAAudio.open: AAudioStream_Open() returned AAUDIO_OK

2022-02-11 13:00:19.994 30733-30733/com.toool D/AAudio: AAudioStream_requestStart(s#12) called --------------

2022-02-11 13:00:19.994 30733-30733/com.toool D/AudioTrack: start(1343): prior state:STATE_STOPPED output 13 stream 3 session 14169

2022-02-11 13:00:19.994 30733-30733/com.toool D/voice_scence_discern: add name:sample_rate, value:48000

2022-02-11 13:00:19.994 30733-30733/com.toool V/voice_scence_discern: add name:sample_rate value:48000 list:0x73fedfd5c0

2022-02-11 13:00:19.994 30733-30733/com.toool D/voice_scence_discern: add name:channels, value:2

2022-02-11 13:00:19.994 30733-30733/com.toool V/voice_scence_discern: add name:channels value:2 list:0x73fedfd5c0

2022-02-11 13:00:19.994 30733-30733/com.toool D/voice_scence_discern: get scence process pid:30733, name:com.toool

2022-02-11 13:00:19.994 30733-30733/com.toool V/voice_scence_discern: this process not in init apk. apk_list:0x746344cc00

2022-02-11 13:00:19.997 30733-30733/com.toool D/: PlayerBase::start() from IPlayer

2022-02-11 13:00:19.997 30733-30733/com.toool D/AAudio: AAudioStream_requestStart(s#12) returned 0 ---------

2022-02-11 13:00:19.999 30733-30903/com.toool D/AudioStreamLegacy: onAudioDeviceUpdate() devId 3 => 3

2022-02-11 13:00:21.121 30733-30733/com.toool W/DisplayEventDispatcher: dispatcher 0x73fedf6f80 ~ ignoring unknown event type 0x6d746f6e

2022-02-11 13:00:22.265 30733-30733/com.toool I/Choreographer: Skipped 102 frames! The application may be doing too much work on its main thread.

BillingClient debug (press X close buttton) :

2022-02-11 13:00:19.836 30733-30733/com.toool W/BillingHelper: Couldn’t find purchase lists, trying to find single data.
2022-02-11 13:00:19.836 30733-30733/com.toool W/BillingHelper: Received a bad purchase data.
2022-02-11 13:00:19.836 30733-30733/com.toool W/BillingHelper: Couldn’t find single purchase data as well.

And After that when I call launchInDefaultBrowser (or quit, or shareFiles) : Crash

2022-02-11 13:01:15.353 30733-30733/com.toool D/ColorViewRootUtil: nav bar mode ignore false downX 831 downY 1491 mScreenHeight 2400 mScreenWidth 1080 mStatusBarHeight 54 globalScale 1.125 nav mode 0 rotation 0 event MotionEvent { action=ACTION_DOWN, actionButton=0, id[0]=0, x[0]=426.88477, y[0]=1218.2109, toolType[0]=TOOL_TYPE_FINGER, buttonState=0, classification=NONE, metaState=0, flags=0x0, edgeFlags=0x0, pointerCount=1, historySize=0, eventTime=61379554, downTime=61379554, deviceId=8, source=0x1002, displayId=0 }

2022-02-11 13:01:15.487 30733-30733/com.toool A/com.toool: java_vm_ext.cc:570] JNI DETECTED ERROR IN APPLICATION: can’t call void android.content.Context.startActivity(android.content.Intent) on null object

2022-02-11 13:01:15.487 30733-30733/com.toool A/com.toool: java_vm_ext.cc:570] in call to CallVoidMethodV

2022-02-11 13:01:15.487 30733-30733/com.toool A/com.toool: java_vm_ext.cc:570] from java.lang.Object com.rmsl.juce.JuceInvocationHandler.dispatchInvoke(long, java.lang.Object, java.lang.reflect.Method, java.lang.Object)

2022-02-11 13:01:15.581 30733-30733/com.toool W/com.toool: sched_getscheduler(30804): No such process

2022-02-11 13:01:15.581 30733-30733/com.toool W/com.toool: sched_getparam(30804, &sp): No such process

2022-02-11 13:01:15.581 30733-30733/com.toool W/com.toool: sched_getscheduler(30807): No such process

2022-02-11 13:01:15.581 30733-30733/com.toool W/com.toool: sched_getparam(30807, &sp): No such process

2022-02-11 13:01:15.696 30733-30733/com.toool A/com.toool: runtime.cc:630] Runtime aborting…

2022-02-11 13:01:15.696 30733-30733/com.toool A/com.toool: runtime.cc:630] Dumping all threads without mutator lock held

2022-02-11 13:01:15.696 30733-30733/com.toool A/com.toool: runtime.cc:630] All threads:

2022-02-11 13:01:15.696 30733-30733/com.toool A/com.toool: runtime.cc:630] DALVIK THREADS (32):

2022-02-11 13:01:15.696 30733-30733/com.toool A/com.toool: runtime.cc:630] “main” prio=10 tid=1 Runnable

etc…

Hi,

My app will be released in few days, after one and a half years of work. That my last bug…
I’m used to fix bug without create new topics (on Juce Forum, 1st topic), but have no idea how to fix it.
Thanks a lot for your help.

Hello @swar, which Juce version are you using ?
And which Gradle Version ? (I don’t know if it’s important…)

My app : Juce 6.1.4, Gradle 7.0.0

JUCE 6.1.2
Gradle 7.0.2

Hopefully someone from JUCE can look into your issue, as I can’t think of any other reason. I’m just a bit puzzled about your launchInDefaultBrowser calls. You are not running this InAppPurchase from a browser, right?

No…
I have just one inAppPurchase subscription (no download)

  • My Class Purchases : private InAppPurchases::Listener
void Purchases::addListenerPurchase()
{
    InAppPurchases::getInstance()->addListener (this);
}

void Purchases::getPurchasesProduct()
{
    InAppPurchases::getInstance()->restoreProductsBoughtList (true);
}

void Purchases::purchaseProduct(String identifier)
{
    if (InAppPurchases::getInstance()->isInAppPurchasesSupported()) {
        screenPanel->setScreenText("Connection...", BLUE, true);
        InAppPurchases::getInstance()->purchaseProduct (identifier);
        guiUpdater.triggerAsyncUpdate();
    }
}
void Purchases::productPurchaseFinished (const PurchaseInfo& info, bool success, const juce::String& error)
{
    if ((info.purchase.productId == SUBSCRIPTION) && success) {
        screenPanel->setScreenText("Thanks for subscription", ORANGE, true);
        proFileDirectory().replaceWithText(info.purchase.purchaseTime);
        isPro = true;
    }
    else if (success) {
        screenPanel->setScreenText("Purchase ERROR 481", ORANGE, true);
    }
    else {
        screenPanel->setScreenText(error, ORANGE, true);
    }
    guiUpdater.triggerAsyncUpdate();
}

void Purchases::purchasesListRestored (const Array<PurchaseInfo>& infos, bool success, const juce::String&)
{
    if (success) {
        if (infos.isEmpty()) {
            proFileDirectory().deleteFile();
            isPro = false;
        }
        else {
            for (auto& info : infos) {
                if (info.purchase.productId == SUBSCRIPTION) {
                    proFileDirectory().replaceWithText(info.purchase.purchaseTime);
                    isPro = true;
                    return;
                }
            }
            proFileDirectory().deleteFile();
            isPro = false;
        }
        guiUpdater.triggerAsyncUpdate();
    }
}

Etc…

JNI DETECTED ERROR IN APPLICATION: can’t call void android.content.Context.startActivity(android.content.Intent) on null object

Could it have something to do with openGL ?

No, same without OpenGLAppComponent :sweat:

My application is out now, but with this bug…
If someone has an idea I would be happy !

Someone understand this error?

Thanks