In App Billing 學習 I
要學習Google的In App Billing可以從他的範例來學,也可以直接套用,即方便又不容易出錯。要學習之前我們先做一下基本的準備。在Android developer中,提供了一個車子買油的小範例
IabHelper.java
IabResult.java
IabException.java
Inventory.java
Purchase.java
Security.java
SkuDetails.java
Base64.java
Base64DecoderException.java
第一步:
先在
第二步 :
第三步:
建立商品。
點擊新增產品
不管是不是納入管理產品,其實google都有管理,所以就選納入管理吧。訂閱是指一個固定周期的付費,像是雜誌每個月的付費之類。
記得在onDestroy裡加上
服務了。
我們先來研究一下 mHelper.startSetup 作了些什麼動作。進入IabHelper.java,在startSetup 方法中可以找到
response = mService.isBillingSupported(3, packageName, ITEM_TYPE_INAPP);
response =mService.isBillingSupported(3, packageName, ITEM_TYPE_SUBS);
response=0, 代表ok!
developer上的圖的第一步(右圖),先檢查是否支援交易和SDK版本。當然startSetup還建立了連線和服務,這個不在話下。
第五步:
我們可以參考範例
IabHelper.QueryInventoryFinishedListener
IabHelper.OnIabPurchaseFinishedListener
IabHelper.OnConsumeFinishedListener
因為參考範例
完整的Code如下
IabHelper.QueryInventoryFinishedListener
IabHelper.OnIabPurchaseFinishedListener
IabHelper.OnConsumeFinishedListener 如下
到這裡算是把In App Billing 都建好了,如果想要進行購買只要
寫入某個按鈕中即可開始交易。SKU_GAS 也可以改成
我們來追蹤一下 launchPurchaseFlow 在IabHelper中的流程。我們再查閱一次流程圖
到此,大概可以了解整個使用的過程,下一篇我們追蹤一下範例中
IabHelper.QueryInventoryFinishedListener
IabHelper.OnIabPurchaseFinishedListener
IabHelper.OnConsumeFinishedListener
這三個Listener的流程。就可以自已改寫了。
TrivialDrive
。 TrivialDrive
這個範例就在 android的sdk 下的/extras/google/play_billing/sample
。我們方便些,把sample下的src的裡的java都複製到我們的project的src下吧。有如下幾個檔名:IabHelper.java
IabResult.java
IabException.java
Inventory.java
Purchase.java
Security.java
SkuDetails.java
Base64.java
Base64DecoderException.java
第一步:
先在
AndroidManifest.xml 加入
<uses-permission android:name="com.android.vending.BILLING" />
第二步 :
在src底下創建一個新的package, 名為
com.android.vending.billing,再把 IInAppBillingService.aidl(也是在
android的sdk 下的/extras/google/play_billing/ 可找到)
複製到 src目錄下的package->
com.android.vending.billing底下
。
第三步:
建立商品。
進入自已的market->應用程式內產品
點擊新增產品
產品ID只能有小寫(a-z)、數字(0-9)、底線(_)和小數點(.)。不管是不是納入管理產品,其實google都有管理,所以就選納入管理吧。訂閱是指一個固定周期的付費,像是雜誌每個月的付費之類。
第四步:
找出public key。進入自已的market
複製public key後,就存放在程式裡吧。如下在 onCreate 中
@Override
public void onCreate(Bundle savedInstanceState) {
String base64EncodedPublicKey; //market 中複製來的public key
mHelper = new IabHelper(this, base64EncodedPublicKey);
mHelper.startSetup(new IabHelper.OnIabSetupFinishedListener() {
public void onIabSetupFinished(IabResult result) {
if (!result.isSuccess()) {
// Oh noes, there was a problem.
Log.d("inAppBilling", "Problem setting up In-app Billing: " + result);
}else{
mHelper.queryInventoryAsync(mGotInventoryListener);
}
}
});
記得在onDestroy裡加上
@Override
public void onDestroy() {
super.onDestroy();
if (mHelper != null) mHelper.dispose();
mHelper = null;
}
到這裡為止,我們已經開始了In App Billing的服務了。
我們先來研究一下 mHelper.startSetup 作了些什麼動作。進入IabHelper.java,在startSetup 方法中可以找到
response = mService.isBillingSupported(3, packageName, ITEM_TYPE_INAPP);
response =mService.isBillingSupported(3, packageName, ITEM_TYPE_SUBS);
response=0, 代表ok!
developer上的圖的第一步(右圖),先檢查是否支援交易和SDK版本。當然startSetup還建立了連線和服務,這個不在話下。
第五步:
我們可以參考範例
TrivialDrive
的MainActivity.java。在onCreate()中建立物件IabHelper後。在onCreate()外,重寫了IabHelper的IabHelper.QueryInventoryFinishedListener
IabHelper.OnIabPurchaseFinishedListener
IabHelper.OnConsumeFinishedListener
因為參考範例
TrivialDrive 有三種產品
1、SKU_PREMIUM。2、SKU_INFINITE_GAS。3、SKU_GAS。
完整的Code如下
IabHelper.QueryInventoryFinishedListener
IabHelper.QueryInventoryFinishedListener mGotInventoryListener = new IabHelper.QueryInventoryFinishedListener() {
public void onQueryInventoryFinished(IabResult result, Inventory inventory) {
Log.d(TAG, "Query inventory finished.");
if (result.isFailure()) {
return;
}
Log.d(TAG, "Query inventory was successful.");
// Do we have the premium upgrade?
Purchase premiumPurchase = inventory.getPurchase(SKU_PREMIUM); //SKU_PREMIUM為內建產品的ID
mIsPremium = (premiumPurchase != null && verifyDeveloperPayload(premiumPurchase));
Log.d(TAG, "User is " + (mIsPremium ? "PREMIUM" : "NOT PREMIUM"));
// Do we have the infinite gas plan?
Purchase infiniteGasPurchase = inventory.getPurchase(SKU_INFINITE_GAS); //SKU_INFINITE_GAS為內建產品的ID
mSubscribedToInfiniteGas = (infiniteGasPurchase != null &&
verifyDeveloperPayload(infiniteGasPurchase));
Log.d(TAG, "User " + (mSubscribedToInfiniteGas ? "HAS" : "DOES NOT HAVE")
+ " infinite gas subscription.");
if (mSubscribedToInfiniteGas) mTank = TANK_MAX;
// Check for gas delivery -- if we own gas, we should fill up the tank immediately
Purchase gasPurchase = inventory.getPurchase(SKU_GAS); //SKU_GAS為內建產品的ID
if (gasPurchase != null && verifyDeveloperPayload(gasPurchase)) {
Log.d(TAG, "We have gas. Consuming it.");
mHelper.consumeAsync(inventory.getPurchase(SKU_GAS), mConsumeFinishedListener);
return;
}
updateUi();
Log.d(TAG, "Initial inventory query finished; enabling main UI.");
}
};
IabHelper.OnIabPurchaseFinishedListener
如下
IabHelper.OnIabPurchaseFinishedListener mPurchaseFinishedListener = new IabHelper.OnIabPurchaseFinishedListener() {
public void onIabPurchaseFinished(IabResult result, Purchase purchase) {
Log.d(TAG, "Purchase finished: " + result + ", purchase: " + purchase);
if (result.isFailure()) {
return;
}
Log.d(TAG, "Purchase successful.");
if (purchase.getSku().equals(SKU_GAS)) { //SKU_GAS為內建產品的ID
// bought 1/4 tank of gas. So consume it.
Log.d(TAG, "Purchase is gas. Starting gas consumption.");
mHelper.consumeAsync(purchase, mConsumeFinishedListener);
}
else if (purchase.getSku().equals(SKU_PREMIUM)) { //SKU_INFINITE_GAS為內建產品的ID
// bought the premium upgrade!
Log.d(TAG, "Purchase is premium upgrade. Congratulating user.");
alert("Thank you for upgrading to premium!");
mIsPremium = true;
updateUi();
}
else if (purchase.getSku().equals(SKU_INFINITE_GAS)) { //SKU_INFINITE_GAS為內建產品的ID
// bought the infinite gas subscription
Log.d(TAG, "Infinite gas subscription purchased.");
alert("Thank you for subscribing to infinite gas!");
mSubscribedToInfiniteGas = true;
mTank = TANK_MAX;
updateUi();
}
}
};
IabHelper.OnConsumeFinishedListener 如下
IabHelper.OnConsumeFinishedListener mConsumeFinishedListener = new IabHelper.OnConsumeFinishedListener() {
public void onConsumeFinished(Purchase purchase, IabResult result) {
Log.d(TAG, "Consumption finished. Purchase: " + purchase + ", result: " + result);
// We know this is the "gas" sku because it's the only one we consume,
// so we don't check which sku was consumed. If you have more than one
// sku, you probably should check...
if (result.isSuccess()) {
// successfully consumed, so we apply the effects of the item in our
// game world's logic, which in our case means filling the gas tank a bit
Log.d(TAG, "Consumption successful. Provisioning.");
mTank = mTank == TANK_MAX ? TANK_MAX : mTank + 1;
saveData();
alert("You filled 1/4 tank. Your tank is now " + String.valueOf(mTank) + "/4 full!");
}
else {
complain("Error while consuming: " + result);
}
updateUi();
Log.d(TAG, "End consumption flow.");
}
};
到這裡算是把In App Billing 都建好了,如果想要進行購買只要
mHelper.launchPurchaseFlow(this, SKU_GAS, RC_REQUEST, mPurchaseFinishedListener, payload);
寫入某個按鈕中即可開始交易。SKU_GAS 也可以改成
SKU_PREMIUM 或SKU_INFINITE_GAS。
我們來追蹤一下 launchPurchaseFlow 在IabHelper中的流程。我們再查閱一次流程圖
在IabHelper中我們可以找到launchPurchanseFlow的程式,裡面包含了getBuyIntent,等待google回應之後,再執行startIntentSenderForResult,如下
try {
logDebug("Constructing buy intent for " + sku + ", item type: " + itemType);
Bundle buyIntentBundle = mService.getBuyIntent(3, mContext.getPackageName(), sku, itemType, extraData);
int response = getResponseCodeFromBundle(buyIntentBundle);
if (response != BILLING_RESPONSE_RESULT_OK) {
logError("Unable to buy item, Error response: " + getResponseDesc(response));
result = new IabResult(response, "Unable to buy item");
if (listener != null) listener.onIabPurchaseFinished(result, null);
return;
}
PendingIntent pendingIntent = buyIntentBundle.getParcelable(RESPONSE_BUY_INTENT);
logDebug("Launching buy intent for " + sku + ". Request code: " + requestCode);
mRequestCode = requestCode;
mPurchaseListener = listener;
mPurchasingItemType = itemType;
act.startIntentSenderForResult(pendingIntent.getIntentSender(),
requestCode, new Intent(),
Integer.valueOf(0), Integer.valueOf(0),
Integer.valueOf(0));
}
到此,大概可以了解整個使用的過程,下一篇我們追蹤一下範例中
IabHelper.QueryInventoryFinishedListener
IabHelper.OnIabPurchaseFinishedListener
IabHelper.OnConsumeFinishedListener
這三個Listener的流程。就可以自已改寫了。
留言
張貼留言