我正在使用以下实现:https://github.com/anjlab/android-inapp-billing-v3
列表中的所有内容(Android Studio,干净的项目):
uses-permission android:name="com.android.vending.BILLING"
权限_
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();
}
}
以防万一:
<?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>
我希望它能在开始时为我提供购买或在控制台上显示某种错误,而不是我得到的(如果在设备上运行):
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!
或者这个(如果在模拟器上运行):
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)
到目前为止我已经尝试并检查的内容:
编辑:提出了一些建议之后,我将onCreate更改为:
@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");
}
}
});
}
什么都没有改变。日志输出如下:
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!
答案 0 :(得分:1)
问题出在设备上。您无法在模拟器上测试帐单,而且帐单似乎在我的设备以及其他应用程序中也损坏(每次尝试付款时,它们都会发出某种“未知错误”)。
很明显,从电话设置中恢复Google Play应用或Google服务的权限后,这些权限可以正常工作。
答案 1 :(得分:0)
可能在构造函数完成之前调用onBillingInitialized()
。
通过较晚的初始化实例化BillingProcessor
基本的new BillingProcessor(...)
实际上绑定到constructor
内部的Play服务。这种情况极少会导致竞争状况,其中绑定了Play服务,并在构造函数完成之前调用onBillingInitialized()
,并可能导致NPE。为避免这种情况,我们有以下内容:
bp = BillingProcessor.newBillingProcessor(this, "YOUR LICENSE KEY FROM GOOGLE PLAY CONSOLE HERE", this); // doesn't bind
bp.initialize(); // binds
,还有在使用之前,最好检查一下应用内结算服务的可用性。在某些较旧的设备或中文设备中,可能会发生Play市场不可用或已被弃用且不支持应用内结算的情况。
只需调用静态方法BillingProcessor.isIabServiceAvailable()
,如果它为true,则继续。
有关更多详细信息,请参阅此link