我在尝试在我已经完成的应用程序上实现应用程序内购买时遇到了一些严重的问题。我有一个类 BaseActivity,它是我所有其他类的扩展。这是设置工具栏、抽屉导航和 IabHelper 的地方。
基础 Activity .java:
public abstract class BaseActivity extends AppCompatActivity implements IabBroadcastReceiver.IabBroadcastListener{
public boolean m30paid = false;
public boolean m31paid = false;
public boolean m32paid = false;
public boolean m37paid = false;
static final String ITEM_SKU = "android.test.purchased";
IabHelper mHelper;
IabBroadcastReceiver mBroadcastReceiver;
private final String LOG = BaseActivity.class.getSimpleName();
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
String base64EncodedPublicKey = "********KEY HERE*********";
mHelper = new IabHelper(this, base64EncodedPublicKey);
mHelper.startSetup(new IabHelper.OnIabSetupFinishedListener() {
public void onIabSetupFinished(IabResult result) {
if (!result.isSuccess()) {
Log.d(LOG, "Problem setting up in app billing: " + result);
}
else Log.d(LOG, "set up correctly!");
if (mHelper == null) return;
}
});
mBroadcastReceiver = new IabBroadcastReceiver(this);
IntentFilter broadcastFilter = new IntentFilter(IabBroadcastReceiver.ACTION);
registerReceiver(mBroadcastReceiver, broadcastFilter);
//IAB fully set up, query inventory
}
@Override
protected void onActivityResult(int requestCode, int resultCode,
Intent data)
{
if (!mHelper.handleActivityResult(requestCode,
resultCode, data)) {
super.onActivityResult(requestCode, resultCode, data);
}
}
@Override
public void onDestroy() {
super.onDestroy();
// very important:
if (mBroadcastReceiver != null) {
unregisterReceiver(mBroadcastReceiver);
}
// very important:
Log.d(LOG, "Destroying helper.");
if (mHelper != null) {
mHelper.disposeWhenFinished();
mHelper = null;
}
}
@Override
public void receivedBroadcast() {
}
IabHelper.QueryInventoryFinishedListener mGotInventoryListener = new IabHelper.QueryInventoryFinishedListener() {
public void onQueryInventoryFinished(IabResult result, Inventory inventory) {
Log.d(LOG, "Query inventory finished.");
// Have we been disposed of in the meantime? If so, quit.
if (mHelper == null) return;
// Is it a failure?
if (result.isFailure()) {
complain("Failed to query inventory: " + result);
return;
}
Log.d(LOG, "Query inventory was successful.");
/*
* Check for items we own. Notice that for each purchase, we check
* the developer payload to see if it's correct! See
* verifyDeveloperPayload().
*/
}};
IabHelper.OnIabPurchaseFinishedListener mPurchaseFinishedListener = new IabHelper.OnIabPurchaseFinishedListener() {
public void onIabPurchaseFinished(IabResult result, Purchase purchase) {
Log.d(LOG, "Purchase finished: " + result + ", purchase: " + purchase);
// if we were disposed of in the meantime, quit.
if (mHelper == null) return;
if (result.isFailure()) {
complain("Error purchasing: " + result);
return;
} else if (purchase.getSku().equalsIgnoreCase("workout_30")) {
m30paid = true;
}
Log.d(LOG, "Purchase successful.");
}
};
void alert(String message) {
AlertDialog.Builder bld = new AlertDialog.Builder(this);
bld.setMessage(message);
bld.setNeutralButton("OK", null);
Log.d(LOG, "Showing alert dialog: " + message);
bld.create().show();
}
public void complain(String message) {
Log.e(LOG, "**** TrivialDrive Error: "+ message);
alert("Error: " + message);
}
从那里,我尝试在另一个类中设置 launchPurchaseFlow on button click。
采购.java:
public class purchases extends BaseActivity {
IabHelper mHelper;
static final String ITEM_SKU = "android.test.purchased";
IabBroadcastReceiver mBroadcastReceiver;
Context mContext;
Activity mActivity = this;
static final int RC_REQUEST = 10001;
private Button btn30;
static final String SKU_W30 = "workout_30";
String payload = "";
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.purchases);
mToolBar = activateToolbar();
setUpNavigationDrawer();
getSupportActionBar().setTitle("Purchases");
btn30 = (Button) findViewById(R.id.btn30);
Button btn31 = (Button) findViewById(R.id.btn31);
Button btn32 = (Button) findViewById(R.id.btn32);
Button btn37 = (Button) findViewById(R.id.btn37);
btn30.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
try {
mHelper.launchPurchaseFlow(purchases.this, SKU_W30, RC_REQUEST, mPurchaseFinishedListener, payload);
} catch (IabHelper.IabAsyncInProgressException e) {
complain("Error");
}
}
});
}
}
单击按钮时出现的错误是:
FATAL EXCEPTION: main
Process: com.bestworkouts.sheikoworkout, PID: 4118
java.lang.NullPointerException: Attempt to invoke virtual method 'void com.bestworkouts.sheikoworkout.util.IabHelper.launchPurchaseFlow(android.app.Activity, java.lang.String, int, com.bestworkouts.sheikoworkout.util.IabHelper$OnIabPurchaseFinishedListener, java.lang.String)' on a null object reference
at com.bestworkouts.sheikoworkout.purchases$1.onClick(purchases.java:41)
at android.view.View.performClick(View.java:5697)
at android.widget.TextView.performClick(TextView.java:10814)
at android.view.View$PerformClick.run(View.java:22526)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:158)
at android.app.ActivityThread.main(ActivityThread.java:7229)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1230)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1120)
基本上我想要它做的是在 onIabPurchaseFinished 中,将 bool 值更改为 true。我的 expLV 上有一个 if 语句,所以如果 bool 值是假的,它说你需要购买这个,如果它是真的,它会提供访问权限。到目前为止,这部分工作正常,但我似乎无法克服此错误以查看它是否正确更改 bool 值并解锁数据。
我不确定我遗漏了什么,我已经弄乱了它并处理了 2 天的多个错误。非常感谢任何帮助!
最佳答案
子类变量 mHelper
未初始化。尝试从扩展 BaseActivity
的 purchase
类中删除 IabHelper mHelper;
,其中初始化了 mHelper
。
在子类中声明mHelper
将隐藏父类(super class)mHelper
变量。
关于Android 应用内购买问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38978235/