我正在尝试使用IabHelper实现inApp计费服务。我设法完成整个购买过程而没有任何问题。
//-----------------------------------------------
public void billingServiceLaunchPurchase(String item) {
//-----------------------------------------------
if (isNetworkAvailableSync(getBaseContext())) {
currBuyItem=item;
billingConsummeType=1;
mHelper.launchPurchaseFlow(BaseActivity.this, item, 10001, mPurchaseFinishedListener, "");
}
else {
onBillingServiceFailed();
}
}
//-----------------------------------------------
mPurchaseFinishedListener = new IabHelper.OnIabPurchaseFinishedListener() {
//-----------------------------------------------
public void onIabPurchaseFinished(IabResult result, Purchase purchase)
{
if (result.isFailure()) {
// Handle error
onBillingServiceFailed();
return;
}
else if (purchase.getSku().equals(currBuyItem)) {
billingServiceConsumeItem();
}
}
};
@Override
//-----------------------------------------------------------------------
protected void onActivityResult(int requestCode, int resultCode, Intent data)
//-----------------------------------------------------------------------
{
if (billingServiceConnected) {
if (!mHelper.handleActivityResult(requestCode, resultCode, data)) {
super.onActivityResult(requestCode, resultCode, data);
}
else {
// onActivityResult handled by IABUtil.
}
}
else
super.onActivityResult(requestCode, resultCode, data);
}
但是,当用户启动购买时我无法检测到该事件,但是在Google确认屏幕上按下退格键并使用“购买”按钮来中断它。
它既没有触发onIabPurchaseFinished的失败,也没有触发onActivityResult,因此我的应用程序保持中间状态。
请帮我解决问题。
答案 0 :(得分:4)
根据我所了解的问题,您正在应用结算中搜索购买取消活动。
您可以通过onActivityResult()方法触发此操作。请在onActivityResult()方法下面的代码中输入。有一个简单的RESEULT_CANCEL类型,显示用户已取消购买。
if (mHelper == null)
return;
if (requestCode == 10001) {
int responseCode = data.getIntExtra("RESPONSE_CODE", 0);
String purchaseData = data.getStringExtra("INAPP_PURCHASE_DATA");
Log.d("INAPP_PURCHASE_DATA", ">>>" + purchaseData);
String dataSignature = data.getStringExtra("INAPP_DATA_SIGNATURE");
Log.d("INAPP_DATA_SIGNATURE", ">>>" + dataSignature);
String continuationToken = data
.getStringExtra("INAPP_CONTINUATION_TOKEN");
Log.d("INAPP_CONTINUATION_TOKEN", ">>>" + continuationToken);
if (resultCode == RESULT_OK) {
try {
Log.d("purchaseData", ">>>"+purchaseData);
JSONObject jo = new JSONObject(purchaseData);
String sku = jo.getString("productId");
alert("You have bought the " + sku
+ ". Excellent choice, adventurer!");
} catch (JSONException e) {
alert("Failed to parse purchase data.");
e.printStackTrace();
}
} else if (resultCode == RESULT_CANCELED) {
Toast.makeText(AppMainTest.this,
"Sorry, you have canceled purchase Subscription.",
Toast.LENGTH_SHORT).show();
} else if (resultCode == IabHelper.BILLING_RESPONSE_RESULT_ITEM_ALREADY_OWNED) {
Toast.makeText(AppMainTest.this, "Item already owned",
Toast.LENGTH_SHORT).show();
}
}
}
或强>
您也可以使用业务逻辑手动处理。检查是否 用户取消购买产品然后把标志用户购买或 如果不是,则再次调用launchPurchaseFlow()方法。
修改强>
onDestroy() method
@Override
public void onDestroy() {
super.onDestroy();
// very important:
Log.d(TAG, "Destroying helper.");
if (mHelper != null)
mHelper.dispose();
mHelper = null;
}
如果你有按钮,那么你可以直接调用launchPurchaseFlow() 方法进入onClick事件,以便每次你的mHelper创建为 新购买。
或
如果您在onCreate方法中使用它并且没有任何按钮 点击事件购买产品然后你必须给值为null 根据我的知识。
希望它能解决你的问题。
答案 1 :(得分:2)
当用户按BACK或在对话框外按时,购买流程仍在进行中,如果用户再次按下PURCHASE按钮,则会出现异常"无法启动异步操作,因为另一个异步操作是正在进行"。
为了解决这个问题,我手动创建了一个标志,以了解是否有正在进行的购买流程。由于IABHelper没有提供处理购买流程的方法,我必须处理mHelper并重新调用initBilling()
boolean onPurchaseFlow = false;
public void purchaseItem() {
if (!onPurchaseFlow) {
mHelper.launchPurchaseFlow(mActivity, SKU_PREMIUM, RC_REQUEST, mPurchaseFinishedListener, "");
onPurchaseFlow = true;
} else {
//dispose mHelper
if (mHelper != null) {
mHelper.dispose();
mHelper = null;
}
initBilling(mActivity); // restart IABHelper, a code snippet will fire launchPurchaseFlow when onPurchaseFlow is true
}
}
另一个重要的部分是在onQueryInventoryFinished()中调用launchPurchaseFlow,以确保在所有init操作完成时调用它(在用户的第二个请求中):
public void onQueryInventoryFinished(IabResult result, Inventory inventory) {
// YOUR CODE HERE
if (onPurchaseFlow == true) {
mHelper.launchPurchaseFlow(mActivity, SKU_PREMIUM, RC_REQUEST, mPurchaseFinishedListener, "");
}
}
在onIabPurchaseFinished()
完成后,请记得重置标记onPurchaseFlow = false public void onIabPurchaseFinished(IabResult result, Purchase purchase) {
Log.d(TAG, "Purchase successful.");
if (purchase.getSku().equals(SKU_PREMIUM)) {
// bought the premium upgrade!
// YOUR CODE HERE
onPurchaseFlow = false;
}
}
答案 2 :(得分:2)
您可以通过IabResult类访问结果代码,并将其与IabHelper类中的不同结果代码进行比较,并在OnIabPurchaseFinishedListener中使用它:
IabHelper.OnIabPurchaseFinishedListener mPurchaseFinishedListener
= new IabHelper.OnIabPurchaseFinishedListener() {
public void onIabPurchaseFinished(IabResult result, Purchase purchase)
{
if (result.isFailure()) {
if (result.getResponse() == IabHelper.BILLING_RESPONSE_RESULT_USER_CANCELED || result.getResponse() == IabHelper.IABHELPER_USER_CANCELLED){
// user cancelled purchase
} else {
// any oder reasult
}
return;
}
else if (purchase.getSku().equals(SKU_SPIRIT_LEVEL)) {
// no error, purchase succeeded
}
}
};
答案 3 :(得分:0)
您可以通过此方法检测背压覆盖
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if ((keyCode == KeyEvent.KEYCODE_BACK)) {
//do what you want to avoid going back while during transaction
Log.d("bak button pressed", "ture");
}
return super.onKeyDown(keyCode, event);
}
即使检查出来,它也可以帮到你
答案 4 :(得分:0)
在IabHelper里面有一个名为handleActivityResult(...)的方法。
如果覆盖onActivityResult(Fragment或Activity)并在其中调用该方法(使用相同的参数调用它)。通过这种方式,帮助程序可以管理所有回调,并且可以在不启动任何异常的情况下重做购买流程。