本主題介紹如何脫離使用Android接口定義語言(AIDL)的結算服務集成。使用AIDL訪問Google Play結算系統(tǒng)這種方式已被棄用,日后所有集成都必須使用Google Play結算庫。
注意:本主題重點介紹進行遷移需要做出的最重要變更。如需詳細了解集成步驟,請參閱本頁面中引用的鏈接以及GitHub上托管的結算服務專用示例中的代碼段。
遷移步驟
導入Google Play結算庫
首先,為Google Play結算庫添加依賴項。如果您使用的是Gradle,則可將以下內容添加到應用的build.gradle文件中:
dependencies{
def billing_version="3.0.0"
implementation"com.android.billingclient:billing:$billing_version"
}
您可以刪除任何“粘合”代碼(例如IabHelper),這些代碼可能是您從以前的參考代碼中復制的。IabHelper所提供的功能現(xiàn)在已包含在Google Play結算庫中。
移除com.android.vending.BILLING權限
Google Play結算庫在其清單中嵌入了com.android.vending.BILLING權限。因此,應用的清單中無需再明確添加此權限。
連接到Google Play結算服務
Google Play結算庫的BillingClient負責為您處理連接管理。如需進行遷移,請對您的應用做出如下更改:
創(chuàng)建BillingClient的實例。
實現(xiàn)BillingClientStateListener以接收有關服務狀態(tài)的回調。
在BillingClient實例上調用startConnection()。
移除與應用內購買相關的onActivityResult()代碼,并將其移至PurchasesUpdatedListener。
以下示例是應用在進行這些更改前后的比較:
之前
mServiceConn=new ServiceConnection(){
Override
public void onServiceDisconnected(ComponentName name){
...
}
Override
public void onServiceConnected(ComponentName name,IBinder service){
...
}
};
Intent serviceIntent=new Intent("com.android.vending.billing.InAppBillingService.BIND");
serviceIntent.setPackage("com.android.vending");
List<ResolveInfo>intentServices=mContext.getPackageManager()
.queryIntentServices(serviceIntent,0);
if(intentServices!=null&&!intentServices.isEmpty()){
mContext.bindService(serviceIntent,mServiceConn,Context.BIND_AUTO_CREATE);
}else{
//Handle errors.
...
}
...
Override
protected void onActivityResult(int requestCode,int resultCode,Intent data){
IabResult result;
if(requestCode!=mRequestCode||data==null){
//Handle errors.
...
}
int responseCode=getResponseCodeFromIntent(data);
String purchaseData=data.getStringExtra(RESPONSE_INAPP_PURCHASE_DATA);
String dataSignature=data.getStringExtra(RESPONSE_INAPP_SIGNATURE);
if(resultCode!=Activity.RESULT_OK||responseCode!=BILLING_RESPONSE_RESULT_OK){
//Handle errors.
...
}
//Process successful purchase.
...
return true;
}
之后
JAVA
public class MyBillingImpl implements PurchasesUpdatedListener{
private BillingClient billingClient;
...
public void initialize(){
billingClient=BillingClient.newBuilder(activity).setListener(this).build();
billingClient.startConnection(new BillingClientStateListener(){
Override
public void onBillingSetupFinished(BillingResult billingResult){
//Logic from ServiceConnection.onServiceConnected should be moved here.
}
Override
public void onBillingServiceDisconnected(){
//Logic from ServiceConnection.onServiceDisconnected should be moved here.
}
});
}
Override
public void onPurchasesUpdated(
BillingResponse int responseCode, Nullable List<Purchase>purchases){
//Logic from onActivityResult should be moved here.
}
}
進行購買
注意:Google Play結算庫2.0版及更高版本需要查詢SKU詳細信息。
如需啟動購買對話框,請執(zhí)行以下操作:
將SKU詳細信息Bundle轉換為SkuDetailsParams。
將mService.getSkuDetails()調用改為BillingClient.querySkuDetailsAsync()
將購買intent Bundle轉換為BillingFlowParams對象。
將mService.getBuyIntent()調用改為BillingClient.launchBillingFlow()。
從onActivityResult()移除所有與應用內購買相關的代碼,并將此代碼移至PurchasesUpdatedListener。
以下示例是應用在進行這些更改前后的比較:
之前
//Query Skus
String skuToSell="premium_upgrade";
ArrayList<String>skus=new Arraylist>>();
skus.add(skuToSell);
Bundle querySkus=new Bundle();
querySkus.putStringArrayList(GET_SKU_DETAILS_ITEM_LIST,skus);
Bundle skuDetails=mService.getSkuDetails(3,
mContext.getPackageName(),
itemType,
querySkus);
if(!skuDetails.containsKey(RESPONSE_GET_SKU_DETAILS_LIST)){
//Handle errors.
...
}
//Launch Buy Flow
Bundle buyIntentBundle=mService.getBuyIntent(3,
mContext.getPackageName(),
skuToSell,
"Inapp",
"");
int response=getResponseCodeFromBundle(buyIntentBundle);
if(response!=BILLING_RESPONSE_RESULT_OK){
//Handle errors.
...
}
PendingIntent pendingIntent=buyIntentBundle.getParcelable(RESPONSE_BUY_INTENT);
act.startIntentSenderForResult(pendingIntent.getIntentSender(),
requestCode,
new Intent(),
Integer.valueOf(0),
Integer.valueOf(0),
Integer.valueOf(0));
//Purchase is handled in onActivityResult illustrated in the previous section.
之后
JAVA
String skuToSell="premium_upgrade";
List<String>skuList=new ArrayList>>();
skuList.add(skuToSell);
SkuDetailsParams.Builder params=SkuDetailsParams.newBuilder();
params.setSkusList(skuList).setType(SkuType.INAPP);
billingClient.querySkuDetailsAsync(params.build(),
new SkuDetailsResponseListener(){
Override
public void onSkuDetailsResponse(BillingResult billingResult,
List<SkuDetails>skuDetailsList){
//Process the result.
...
}
});
//SkuDetails object obtained above.
SkuDetails skuDetails=...;
BillingFlowParams purchaseParams=
BillingFlowParams.newBuilder()
.setSkuDetails(skuDetails)
.build();
mBillingClient.launchBillingFlow(mActivity,purchaseParams);
//Purchase is handled in onPurchasesUpdated illustrated in the previous section.
消耗所購商品
如需使用Google Play結算庫消耗所購商品,請執(zhí)行以下操作:
調用BillingClient.consumeAsync(),而不是調用consumePurchase()。
實現(xiàn)ConsumeResponseListener。
以下示例是應用在進行這些更改前后的比較:
之前
Override
protected void onActivityResult(int requestCode,int resultCode,Intent data){
int responseCode=data.getIntExtra(RESPONSE_CODE);
JSONObject purchaseData=
new JSONObject(data.getStringExtra("INAPP_PURCHASE_DATA"));
String token=purchaseData.get("purchaseToken");
...
//Consume purchase
int response=mService.consumePurchase(3,mContext.getPackageName(),token);
if(response!=BILLING_RESPONSE_RESULT_OK){
//Handle errors.
...
}
//Handle successful consumption.
}
之后
JAVA
public class MyBillingImpl implements...,ConsumeResponseListener{
private BillingClient billingClient;
...
public void consumePurchase(String purchaseToken){
ConsumeParams consumeParams=
ConsumeParams.newBuilder()
.setPurchaseToken(purchaseToken)
.build();
}
Override
void onConsumeResponse(BillingResult billingResult,String purchaseToken){
//Handle consumption.
...
}
}
確認購買交易
從Google Play結算庫2.0版開始,您的應用必須消耗所有所購商品或確認所有購買交易。
如果您在三天內未消耗所購商品或確認購買交易,Google會自動撤消購買交易并向用戶退款。如需了解詳情,請參閱確認購買交易。
識別應用外購買
如需將應用外購買交易的處理遷移到Google Play結算庫,請執(zhí)行以下操作:
確保您的應用在其onResume()回調中調用BillingClient.queryPurchases()。
移除com.android.vending.billing.PURCHASES_UPDATED的廣播接收器,并將相應回調代碼移至PurchasesUpdatedListener。
以前,將Google Play結算服務與AIDL集成時,您的應用需要注冊監(jiān)聽器才能接收com.android.vending.billing.PURCHASES_UPDATED intent,用于處理應用外購買交易。
使用Google Play結算庫時,您應始終先在應用的onResume()回調中調用queryPurchases(),以確保識別出應用未運行期間完成的所有購買交易。在應用運行時,結算庫會自動監(jiān)聽應用外購買交易,并通過PurchasesUpdatedListener通知您。
處理待處理的交易
從Google Play結算庫2.0版開始,應用必須處理某些待處理的交易,這些交易需要在購買后執(zhí)行額外操作,然后才能授予使用權。例如,用戶可能會選擇使用現(xiàn)金在實體店購買您的應用內商品。也就是說,交易是在應用外部完成的。在這種情況下,只有在用戶完成交易后,您才能授予使用權。
如需了解詳情,請參閱支持待處理的交易。
開發(fā)者載荷
開發(fā)者載荷向來被用于各種不同用途,包括防欺詐以及將購買交易歸因于正確的用戶。由于Google Play結算庫現(xiàn)已支持這些用例,因此從Google Play結算庫2.2版開始,我們已棄用開發(fā)者載荷。如需了解詳情,請參閱開發(fā)者載荷。
詳細的錯誤消息
從Google Play結算庫2.0版開始,所有錯誤都包含相應的調試相關消息。這些消息可以通過調用BillingResult.getDebugMessage()獲得。