我有一种游戏类型的应用程序。我经历了很多冲浪,但我没有得到任何满意的解决方案。在这里,用户可以多次购买硬币包。我的代码中有一些问题,所以用户只能购买一次。我已阅读有关消耗性 IAP(应用内购买)的文档,但仍然存在同样的问题。如果我进行 consumablePurchase() 调用,它会给出 BILLING_RESPONSE_RESULT_DEVELOPER_ERROR (ResponseCode 5)。
脚步 :
1) 调用 purchasePackage("android.test.iap.500coins")
public void purchasePackage(String product_id) {
try {
Log.i(TAG, "product name : " + product_id);
package_name = product_id;
Bundle buyIntentBundle = mService
.getBuyIntent(3, getPackageName(), product_id, "inapp",
"C890B68423F8EA57F3ED38C3DCC816D7E389F4Cdc4961C23540dadC866B8CFFC5");
Log.i(TAG,
"buy intent response : "
+ buyIntentBundle
.getInt("BILLING_RESPONSE_RESULT_OK"));
if (buyIntentBundle.getInt("BILLING_RESPONSE_RESULT_OK") == 0) {
Log.i(TAG, "buyIntentBundle created");
PendingIntent pendingIntent = buyIntentBundle
.getParcelable("BUY_INTENT");
Log.i(TAG, "pendingIntent created");
startIntentSenderForResult(pendingIntent.getIntentSender(),
1101, new Intent(), Integer.valueOf(0),
Integer.valueOf(0), Integer.valueOf(0));
Log.i(TAG, "startIntentSenderForResult started");
} else
Log.i(TAG, "getBuyIntent response not ok");
} catch (RemoteException e) {
// TODO: handle exception
Log.e(TAG, "RemoteException : " + e.getMessage());
} catch (Exception e) {
// TODO: handle exception
Log.e(TAG, "Error in buyStructure : " + e.getMessage());
}
}
2) 在 onActivityResult(int requestCode, int resultCode, Intent data) 中获取响应,并在获取 purchasePackage() 响应后生成 consumablePurchase()
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
// TODO Auto-generated method stub
Log.i(TAG, "requestCode : " + requestCode + " :resultCode : "
+ resultCode);
if (data != null && requestCode == 1101) {
int responseCode = data.getIntExtra("RESPONSE_CODE", -1);
String purchaseData = data.getStringExtra("INAPP_PURCHASE_DATA");
String dataSignature = data.getStringExtra("INAPP_DATA_SIGNATURE");
Log.i(TAG, "responseCode : " + responseCode);
if (resultCode == RESULT_OK) {
try {
switch (responseCode) {
case 0:
/*new Thread() {
@Override
public void run() {
mHandler.sendEmptyMessage(purchaseStart);
StartupSync purchaseSync = new StartupSync(
InAppActivity.this, mHandler);
purchaseSync.purchasePackage(package_name);
mHandler.sendEmptyMessage(purchaseComplete);
}
}.start(); */
JSONObject jo = new JSONObject(purchaseData);
String sku = jo.getString("productId");
String purchaseToken = jo.getString("purchaseToken");
Log.i(TAG, "You have bought the " + sku
+ ". Excellent choice,adventurer!");
int coins = Integer.parseInt(db.selectSettingsValue("coins"));
Log.i(TAG, "coins " + coins);
coins = coins + intIncCoins;
Log.i(TAG, "coins " + coins);
db.updateSettings("coins", coins + "");
Toast.makeText(
InAppActivity.this,
"Thank You !",
Toast.LENGTH_SHORT).show();
finish();
int response = mService.consumePurchase(3, sku, purchaseToken);
Toast.makeText(
InAppActivity.this,
"Response : " + response ,
Toast.LENGTH_LONG).show();
break;
case 1:
Log.i(TAG, "BILLING_RESPONSE_RESULT_USER_CANCELED");
Toast.makeText(InAppActivity.this,
"User pressed back or canceled a dialog",
Toast.LENGTH_SHORT).show();
break;
case 3:
Log.i(TAG,
"BILLING_RESPONSE_RESULT_BILLING_UNAVAILABLE");
Toast.makeText(
InAppActivity.this,
"Billing API version is not supported for the type requested",
Toast.LENGTH_SHORT).show();
break;
case 4:
Log.i(TAG, "BILLING_RESPONSE_RESULT_ITEM_UNAVAILABLE");
Toast.makeText(
InAppActivity.this,
"Requested product is not available for purchase",
Toast.LENGTH_SHORT).show();
break;
case 5:
Log.i(TAG, "BILLING_RESPONSE_RESULT_DEVELOPER_ERROR");
Toast.makeText(
InAppActivity.this,
"Invalid arguments provided to the API. This error can also indicate that the application was not correctly signed or properly set up for In-app Billing in Google Play, or does not have the necessary permissions in its manifest",
Toast.LENGTH_SHORT).show();
break;
case 6:
Log.i(TAG, "BILLING_RESPONSE_RESULT_ERROR");
Toast.makeText(InAppActivity.this,
"Fatal error during the API action",
Toast.LENGTH_SHORT).show();
break;
case 7:
Log.i(TAG, "BILLING_RESPONSE_RESULT_ITEM_ALREADY_OWNED");
Toast.makeText(
InAppActivity.this,
"Failure to purchase since item is already owned",
Toast.LENGTH_SHORT).show();
break;
case 8:
Log.i(TAG, "BILLING_RESPONSE_RESULT_ITEM_NOT_OWNED");
Toast.makeText(InAppActivity.this,
"Failure to consume since item is not owned",
Toast.LENGTH_SHORT).show();
break;
}
} catch (JSONException e) {
Log.i(TAG, "Failed to parse purchase data.");
e.printStackTrace();
} catch (RemoteException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} else if (resultCode == RESULT_CANCELED) {
Toast.makeText(InAppActivity.this, "Purchase Failded",
Toast.LENGTH_SHORT).show();
}
} else if (resultCode == RESULT_CANCELED) {
Toast.makeText(InAppActivity.this, "Purchase Canceled",
Toast.LENGTH_SHORT).show();
}
super.onActivityResult(requestCode, resultCode, data);
}
甚至我也尝试过另一种方法,例如获取所有购买的 IAP 的数组并使它们成为消耗品。我在启动活动中编写了代码。打印日志在这里。
为什么它一次又一次地给出同样的错误?这是 2013 年 3 月谷歌自己解决的一个错误。
任何建议/意见都可以接受!