1. 程式人生 > >Google內購--封裝版

Google內購--封裝版

最近老大提出了一個需求,在應用裡面加一個內購。由於之前沒做過這塊,所以百度一番。網上都是講的使用一大堆的utils、還要加一個aidl檔案。感覺挺麻煩的。最終讓我找到了:com.android.billingclient:billing:1.0 。使用該依賴,解決了一大堆的utils。

好了,開始介紹下使用步驟:

一、程式碼部分

①、在AndroidManifest.xml中新增內購許可權。

<uses-permission android:name="com.android.vending.BILLING" />

這個是必須的。

②、加入依賴。

compile 'com.android.billingclient:billing:1.0'
//如果用到isGooglePlayServicesAvailable方法需要匯入這個包,這個方法也可以去掉。

implementation 'com.google.android.gms:play-services-basement:11.8.0'

③、程式碼封裝:

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.support.annotation.Nullable;
import android.util.Log;

import com.android.billingclient.api.BillingClient;
import com.android.billingclient.api.BillingClientStateListener;
import com.android.billingclient.api.BillingFlowParams;
import com.android.billingclient.api.ConsumeResponseListener;
import com.android.billingclient.api.Purchase;
import com.android.billingclient.api.PurchasesUpdatedListener;
import com.android.billingclient.api.SkuDetails;
import com.android.billingclient.api.SkuDetailsParams;
import com.android.billingclient.api.SkuDetailsResponseListener;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.GoogleApiAvailability;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;


/**
 
 * 對isGooglePlayServicesAvailable方法進行了說明,因為這個方法是要匯入一個包才能使用的。
 * api "com.google.android.gms:play-services-location:11.8.0"也可以不用
 
 */


@SuppressWarnings("ALL")
public class GoogleBillingUtil {

    private static final String TAG = "```GoogleBillingUtil";
    private static final boolean IS_DEBUG = true;
//googleplay應用內商品欄,新增商品後得到
    private String[] inAppSKUS = new String[]{"","",""};//內購ID,必填
    private String[] subsSKUS = new String[]{"","",""};//訂閱ID,必填

    public static final String BILLING_TYPE_INAPP = BillingClient.SkuType.INAPP;//內購
    public static final String BILLING_TYPE_SUBS = BillingClient.SkuType.SUBS;//訂閱

    private static BillingClient mBillingClient;
    private static BillingClient.Builder builder ;
    private static OnPurchaseFinishedListener mOnPurchaseFinishedListener;
    private static OnStartSetupFinishedListener mOnStartSetupFinishedListener ;
    private static OnQueryFinishedListener mOnQueryFinishedListener;

    private boolean isAutoConsumeAsync = true;//是否在購買成功後自動消耗商品

    private static final GoogleBillingUtil mGoogleBillingUtil = new GoogleBillingUtil() ;

    private GoogleBillingUtil()
    {

    }

    public static GoogleBillingUtil getInstance()
    {
        cleanListener();
        return mGoogleBillingUtil;
    }

    public GoogleBillingUtil build(Context context)
    {
        if(mBillingClient==null)
        {
            synchronized (mGoogleBillingUtil)
            {
                if(mBillingClient==null)
                {
                    if(isGooglePlayServicesAvailable(context))
                    {
                        builder = BillingClient.newBuilder(context);
                        mBillingClient = builder.setListener(mGoogleBillingUtil.new MyPurchasesUpdatedListener()).build();
                    }
                    else
                    {
                        if(IS_DEBUG)
                        {
                            log("警告:GooglePlay服務處於不可用狀態,請檢查");
                        }
                        if(mOnStartSetupFinishedListener!=null)
                        {
                            mOnStartSetupFinishedListener.onSetupError();
                        }
                    }
                }
                else
                {
                    builder.setListener(mGoogleBillingUtil.new MyPurchasesUpdatedListener());
                }
            }
        }
        else
        {
            builder.setListener(mGoogleBillingUtil.new MyPurchasesUpdatedListener());
        }
        synchronized (mGoogleBillingUtil)
        {
            if(mGoogleBillingUtil.startConnection())
            {
                mGoogleBillingUtil.queryInventoryInApp();
                mGoogleBillingUtil.queryInventorySubs();
                mGoogleBillingUtil.queryPurchasesInApp();
            }
        }
        return mGoogleBillingUtil;
    }

    public boolean startConnection()
    {
        if(mBillingClient==null)
        {
            log("初始化失敗:mBillingClient==null");
            return false;
        }
        if(!mBillingClient.isReady())
        {
            mBillingClient.startConnection(new BillingClientStateListener() {
                @Override
                public void onBillingSetupFinished(@BillingClient.BillingResponse int billingResponseCode) {
                    if (billingResponseCode == BillingClient.BillingResponse.OK) {
                        queryInventoryInApp();
                        queryInventorySubs();
                        queryPurchasesInApp();
                        if(mOnStartSetupFinishedListener!=null)
                        {
                            mOnStartSetupFinishedListener.onSetupSuccess();
                        }
                    }
                    else
                    {
                        log("初始化失敗:onSetupFail:code="+billingResponseCode);
                        if(mOnStartSetupFinishedListener!=null)
                        {
                            mOnStartSetupFinishedListener.onSetupFail(billingResponseCode);
                        }
                    }
                }
                @Override
                public void onBillingServiceDisconnected() {
                    if(mOnStartSetupFinishedListener!=null)
                    {
                        mOnStartSetupFinishedListener.onSetupError();
                    }
                    log("初始化失敗:onBillingServiceDisconnected");
                }
            });
            return false;
        }
        else
        {
            return true;
        }
    }

    /**
     * Google購買商品回撥介面(訂閱和內購都走這個介面)
     */
    private class MyPurchasesUpdatedListener implements PurchasesUpdatedListener
    {
        @Override
        public void onPurchasesUpdated(int responseCode, @Nullable List<Purchase> list) {
            if(mOnPurchaseFinishedListener==null)
            {
                if(IS_DEBUG)
                {
                    log("警告:接收到購買回調,但購買商品介面為Null,請設定購買介面。eg:setOnPurchaseFinishedListener()");
                }
                return ;
            }
            if(responseCode== BillingClient.BillingResponse.OK&&list!=null)
            {
                if(isAutoConsumeAsync)
                {
                    //消耗商品
                    for(Purchase purchase:list)
                    {
                        String sku = purchase.getSku();
                        if(sku!=null)
                        {
                            String skuType = getSkuType(sku);
                            if(skuType!=null)
                            {
                                if(skuType.equals(BillingClient.SkuType.INAPP))
                                {
                                    consumeAsync(purchase.getPurchaseToken());
                                }
                            }
                        }
                    }
                }
                mOnPurchaseFinishedListener.onPurchaseSuccess(list);
            }
            else
            {
                mOnPurchaseFinishedListener.onPurchaseFail(responseCode);
            }
        }
    }

    /**
     * 查詢內購商品資訊
     */
    public void queryInventoryInApp()
    {
        queryInventory(BillingClient.SkuType.INAPP);
    }

    /**
     * 查詢訂閱商品資訊
     */
    public void queryInventorySubs()
    {
        queryInventory(BillingClient.SkuType.SUBS);
    }

    private void queryInventory(final String skuType) {

        Runnable runnable = new Runnable() {
            @Override
            public void run() {
                if (mBillingClient == null)
                {
                    if(mOnQueryFinishedListener!=null)
                    {
                        mOnQueryFinishedListener.onQueryError();
                    }
                    return ;
                }
                ArrayList<String> skuList = new ArrayList<>();
                if(skuType.equals(BillingClient.SkuType.INAPP))
                {
                    Collections.addAll(skuList, inAppSKUS);
                }
                else if(skuType.equals(BillingClient.SkuType.SUBS))
                {
                    Collections.addAll(skuList, subsSKUS);
                }
                SkuDetailsParams.Builder params = SkuDetailsParams.newBuilder();
                params.setSkusList(skuList).setType(skuType);
                mBillingClient.querySkuDetailsAsync(params.build(),new MySkuDetailsResponseListener(mOnQueryFinishedListener,skuType));
            }
        };
        executeServiceRequest(runnable);
    }

    /**
     * Google查詢商品資訊回撥介面
     */
    private class MySkuDetailsResponseListener implements SkuDetailsResponseListener
    {
        private OnQueryFinishedListener mOnQueryFinishedListener ;
        private String skuType ;

        public MySkuDetailsResponseListener(OnQueryFinishedListener onQueryFinishedListener,String skuType) {
            mOnQueryFinishedListener = onQueryFinishedListener;
            this.skuType = skuType;
        }

        @Override
        public void onSkuDetailsResponse(int responseCode , List<SkuDetails> list) {
            if(mOnQueryFinishedListener==null)
            {
                if(IS_DEBUG) {
                    log("警告:接收到查詢商品回撥,但查詢商品介面為Null,請設定購買介面。eg:setOnQueryFinishedListener()");
                }
                return ;
            }
            if(responseCode== BillingClient.BillingResponse.OK&&list!=null)
            {
                mOnQueryFinishedListener.onQuerySuccess(skuType,list);
            }
            else
            {
                mOnQueryFinishedListener.onQueryFail(responseCode);
            }
        }

    }

    /**
     * 發起內購
     * @param skuId
     * @return
     */
    public void purchaseInApp(Activity activity,String skuId)
    {
        purchase(activity,skuId, BillingClient.SkuType.INAPP);
    }

    /**
     * 發起訂閱
     * @param skuId
     * @return
     */
    public void purchaseSubs(Activity activity,String skuId)
    {
        purchase(activity,skuId, BillingClient.SkuType.SUBS);
    }

    private void purchase(Activity activity,final String skuId,final String skuType)
    {
        if(mBillingClient==null)
        {
            if(mOnPurchaseFinishedListener!=null)
            {
                mOnPurchaseFinishedListener.onPurchaseError();
            }
            return ;
        }
        if(startConnection())
        {
            BillingFlowParams flowParams = BillingFlowParams.newBuilder()
                    .setSku(skuId)
                    .setType(skuType)
                    .build();
            mBillingClient.launchBillingFlow(activity,flowParams);
        }
        else
        {
            if(mOnPurchaseFinishedListener!=null)
            {
                mOnPurchaseFinishedListener.onPurchaseError();
            }
        }
    }

    /**
     * 消耗商品
     * @param purchaseToken
     */
    public void consumeAsync(String purchaseToken)
    {
        if(mBillingClient==null)
        {
            return ;
        }
        mBillingClient.consumeAsync(purchaseToken, new MyConsumeResponseListener());
    }

    /**
     * Googlg消耗商品回撥
     */
    private class MyConsumeResponseListener implements ConsumeResponseListener
    {
        @Override
        public void onConsumeResponse(int responseCode, String s) {
            if (responseCode == BillingClient.BillingResponse.OK) {

            }
        }
    }


    /**
     * 獲取已經內購的商品
     * @return
     */
    public List<Purchase> queryPurchasesInApp()
    {
        return queryPurchases(BillingClient.SkuType.INAPP);
    }

    /**
     * 獲取已經訂閱的商品
     * @return
     */
    public List<Purchase> queryPurchasesSubs()
    {
        return queryPurchases(BillingClient.SkuType.SUBS);
    }

    private List<Purchase> queryPurchases(String skuType)
    {
        if(mBillingClient==null)
        {
            return null;
        }
        if(!mBillingClient.isReady())
        {
            startConnection();
        }
        else
        {
            Purchase.PurchasesResult purchasesResult = mBillingClient.queryPurchases(skuType);
            if(purchasesResult!=null)
            {
                if(purchasesResult.getResponseCode()== BillingClient.BillingResponse.OK)
                {
                    List<Purchase> purchaseList =  purchasesResult.getPurchasesList();
                    if(isAutoConsumeAsync)
                    {
                        if(purchaseList!=null)
                        {
                            for(Purchase purchase:purchaseList)
                            {
                                if(skuType.equals(BillingClient.SkuType.INAPP))
                                {
                                    consumeAsync(purchase.getPurchaseToken());
                                }
                            }
                        }
                    }
                    return purchaseList;
                }
            }

        }
        return null;
    }

    /**
     * 獲取有效訂閱的數量
     * @return -1查詢失敗,0沒有有效訂閱,>0具有有效的訂閱
     */
    public int getPurchasesSizeSubs()
    {
        List<Purchase> list = queryPurchasesSubs();
        if(list!=null)
        {
            return list.size();
        }
        return -1;
    }

    /**
     * 通過sku獲取訂閱商品序號
     * @param sku
     * @return
     */
    public int getSubsPositionBySku(String sku)
    {
        return getPositionBySku(sku, BillingClient.SkuType.SUBS);
    }

    /**
     * 通過sku獲取內購商品序號
     * @param sku
     * @return 成功返回需要 失敗返回-1
     */
    public int getInAppPositionBySku(String sku)
    {
        return getPositionBySku(sku, BillingClient.SkuType.INAPP);
    }

    private int getPositionBySku(String sku,String skuType)
    {

        if(skuType.equals(BillingClient.SkuType.INAPP))
        {
            int i = 0;
            for(String s:inAppSKUS)
            {
                if(s.equals(sku))
                {
                    return i;
                }
                i++;
            }
        }
        else if(skuType.equals(BillingClient.SkuType.SUBS))
        {
            int i = 0;
            for(String s:subsSKUS)
            {
                if(s.equals(sku))
                {
                    return i;
                }
                i++;
            }
        }
        return -1;
    }

    private void executeServiceRequest(final Runnable runnable)
    {
        if(startConnection())
        {
            runnable.run();
        }
    }

    /**
     * 通過序號獲取訂閱sku
     * @param position
     * @return
     */
    public String getSubsSkuByPosition(int position)
    {
        if(position>=0&&position<subsSKUS.length)
        {
            return subsSKUS[position];
        }
        else {
            return null;
        }
    }

    /**
     * 通過序號獲取內購sku
     * @param position
     * @return
     */
    public String getInAppSkuByPosition(int position)
    {
        if(position>=0&&position<inAppSKUS.length)
        {
            return inAppSKUS[position];
        }
        else
        {
            return null;
        }
    }

    /**
     * 通過sku獲取商品型別(訂閱獲取內購)
     * @param sku
     * @return inapp內購,subs訂閱
     */
    private String getSkuType(String sku)
    {
        if(Arrays.asList(inAppSKUS).contains(sku))
        {
            return BillingClient.SkuType.INAPP;
        }
        else if(Arrays.asList(subsSKUS).contains(sku))
        {
            return BillingClient.SkuType.SUBS;
        }
        return null;
    }

    /**
     * 檢測GooglePlay服務是否可用(需要匯入包api "com.google.android.gms:play-services-location:11.8.0",也可以不檢查,跳過這個程式碼)
     * @param context
     * @return
     */
    public static boolean isGooglePlayServicesAvailable(Context context)
    {
        GoogleApiAvailability googleApiAvailability = GoogleApiAvailability.getInstance();
        if(googleApiAvailability!=null)
        {
            int resultCode = googleApiAvailability.isGooglePlayServicesAvailable(context);
            return resultCode == ConnectionResult.SUCCESS;
        }
        return false;
        //return true;//不檢查直接跳過
    }

    public GoogleBillingUtil setOnQueryFinishedListener(OnQueryFinishedListener onQueryFinishedListener) {
        mOnQueryFinishedListener = onQueryFinishedListener;
        return mGoogleBillingUtil;
    }

    public GoogleBillingUtil setOnPurchaseFinishedListener(OnPurchaseFinishedListener onPurchaseFinishedListener) {
        mOnPurchaseFinishedListener = onPurchaseFinishedListener;
        return mGoogleBillingUtil;
    }

    public OnStartSetupFinishedListener getOnStartSetupFinishedListener() {
        return mOnStartSetupFinishedListener;
    }

    public GoogleBillingUtil setOnStartSetupFinishedListener(OnStartSetupFinishedListener onStartSetupFinishedListener) {
        mOnStartSetupFinishedListener = onStartSetupFinishedListener;
        return mGoogleBillingUtil;
    }

    /**
     *  本工具查詢回撥介面
     */
    public interface OnQueryFinishedListener{
        //Inapp和sub都走這個介面查詢的時候一定要判斷skuType
        public void onQuerySuccess(String skuType, List<SkuDetails> list);
        public void onQueryFail(int responseCode);
        public void onQueryError();
    }

    /**
     * 本工具購買回調介面(內購與訂閱都走這介面)
     */
    public interface OnPurchaseFinishedListener{

        public void onPurchaseSuccess(List<Purchase> list);

        public void onPurchaseFail(int responseCode);

        public void onPurchaseError();

    }

    /**
     * google服務啟動介面
     */
    public interface OnStartSetupFinishedListener{
        public void onSetupSuccess();

        public void onSetupFail(int responseCode);

        public void onSetupError();
    }

    public boolean isReady() {
        return mBillingClient!=null&&mBillingClient.isReady();
    }

    public boolean isAutoConsumeAsync()
    {
        return isAutoConsumeAsync;
    }

    public void setIsAutoConsumeAsync(boolean isAutoConsumeAsync)
    {
        this.isAutoConsumeAsync= isAutoConsumeAsync;
    }

    /**
     * 清除所有監聽器,防止記憶體洩漏
     * 如果有多個頁面使用了支付,需要確保上個頁面的cleanListener在下一個頁面的GoogleBillingUtil.getInstance()前使用。
     * 所以不建議放在onDestory裡呼叫
     */
    public static void cleanListener()
    {
        mOnPurchaseFinishedListener = null;
        mOnQueryFinishedListener = null;
        mOnStartSetupFinishedListener = null;
        if(builder!=null)
        {
            builder.setListener(null);
        }
    }

    /**
     * 斷開連線google服務
     * 注意!!!一般情況不建議呼叫該方法,讓google保留連線是最好的選擇。
     */
    public static void endConnection()
    {
        //注意!!!一般情況不建議呼叫該方法,讓google保留連線是最好的選擇。
        if(mBillingClient!=null)
        {
            if(mBillingClient.isReady())
            {
                mBillingClient.endConnection();
                mBillingClient = null;
            }
        }
    }

    private static void log(String msg)
    {
        if(IS_DEBUG)
        {
            Log.e(TAG,msg);
        }
    }
    /**
     * 是否支援內購
     */
    public  boolean isIabServiceAvailable(Context context)
    {
        final PackageManager packageManager = context.getPackageManager();
        List<ResolveInfo> list = packageManager.queryIntentServices(getBindServiceIntent(), 0);
        return list != null && list.size() > 0;
    }
    private  Intent getBindServiceIntent()
    {
        Intent intent = new Intent("com.android.vending.billing.InAppBillingService.BIND");
        intent.setPackage("com.android.vending");
        return intent;
    }
}

程式碼可以直接拿去用的,不需要填入key值。

④、程式碼示例:

private GoogleBillingUtil googleBillingUtil = null;
private MyOnPurchaseFinishedListener mOnPurchaseFinishedListener = new MyOnPurchaseFinishedListener();//購買回調介面
private MyOnQueryFinishedListener mOnQueryFinishedListener = new MyOnQueryFinishedListener();//查詢回撥介面
private MyOnStartSetupFinishedListener mOnStartSetupFinishedListener = new OnStartSetupFinishedListener();//啟動結果回撥介面

4.1:建立示例,需要在build之前設定回撥介面,介面可以選擇性設定

@Override
protected void onStart() {
    super.onStart();
	/*
	建議放在onStart裡面初始化,因為你可能在別的頁面與谷歌服務斷開了連線或者設定了介面,所以當一個頁面開啟的時候,
	你應該重新檢測連線是否正常(如果斷開則重新連線)並重新設定介面
	*/
	googleBillingUtil = GoogleBillingUtil.getInstance()
                .setOnPurchaseFinishedListener(mOnPurchaseFinishedListener)
                .setOnQueryFinishedListener(mOnQueryFinishedListener)
                .setOnStartSetupFinishedListener(mOnStartSetupFinishedListener)
                .build();
}

4.2:發起內購或者訂閱

public void queryInventoryInApp() 查詢內購商品資訊列表
public void queryInventorySubs() 查詢訂閱商品資訊列表
public void purchaseInApp(Activity activity,String skuId) 發起內購
public void purchaseSubs(Activity activity,String skuId) 發起訂閱

4.3:清除監聽

//如果下個頁面或者上個頁面沒有使用到googleBuillingUtil.getInstance(),那麼就需要在finish或者startActivity之前呼叫cleanListener()方法,來清除介面。
//可以嘗試這樣
@Override
    public void onBackPressed() {
        GoogleBillingUtil.cleanListener();
        super.onBackPressed();
    }
//返回鍵點選
public void onBackClick()
    {
        GoogleBillingUtil.cleanListener();
        this.finish();
    }


//如果只使用一次googleBuillingUtil,可以選擇使用endConnection()方法斷開google服務的連線,下次使用重新連線。

4.4:介面說明

//查詢商品資訊回撥介面
private class MyOnQueryFinishedListener implements GoogleBillingUtil.OnQueryFinishedListener
{
  @Override
  public void onQuerySuccess(String skuType,List<SkuDetails> list) {
      //查詢成功,返回商品列表,
      //skuDetails.getPrice()獲得價格(文字)
      //skuDetails.getType()獲得型別 sub或者inapp,因為sub和inapp的查詢結果都走這裡,所以需要判斷。
      //googleBillingUtil.getSubsPositionBySku(skuDetails.getSku())獲得當前subs sku的序號
      //googleBillingUtil.getInAppPositionBySku(skuDetails.getSku())獲得當前inapp suk的序號
  }
  @Override
  public void onQueryFail(int responseCode) {
      //查詢失敗
  }

  @Override
  public void onQueryError() {
      //查詢錯誤
  }
}
//服務初始化結果回撥介面
private class MyOnStartSetupFinishedListener implements GoogleBillingUtil.OnStartSetupFinishedListener
{
//...;
}
//購買商品回撥介面
private class MyOnPurchaseFinishedListener implements GoogleBillingUtil.OnPurchaseFinishedListener
{
     @Override
        public void onPurchaseSuccess(List<Purchase> list) {
            //內購或者訂閱成功,可以通過purchase.getSku()獲取suk進而來判斷是哪個商品
        }

        @Override
        public void onPurchaseFail(int responseCode) {
            
        }


        @Override
        public void onPurchError() {
            
        }
}

4.5:api說明:

//初始化
1、public static GoogleBillingUtil getInstance() 獲取單例項
2、public GoogleBillingUtil build() 
	建立內購例項,連線谷歌支付服務(如果未建立、未連線),並查詢商品資訊列表。
	如果預設自動消耗已內購但未被消耗的商品,可以通過設定isAutoConsumeAsync改變。
3、public void startConnection() 
	連線谷歌支付服務(一般情況下不需要手動呼叫,build的時候已經呼叫了)
	

//查詢、購買與消耗
4、public void queryInventoryInApp() 查詢內購商品資訊列表
5、public void queryInventorySubs() 查詢訂閱商品資訊列表
6、public void purchaseInApp(Activity activity,String skuId) 發起內購
7、public void purchaseSubs(Activity activity,String skuId) 發起訂閱
8、public void consumeAsync(String purchaseToken) 消耗商品(一般情況下不需要手動呼叫,內購的時候自動呼叫了)

//購買歷史、有效訂閱數
9、public List<Purchase> queryPurchasesInApp() 獲取已經內購的商品列表
10、public List<Purchase> queryPurchasesSubs() 獲取已經訂閱的商品列表
11、public int getPurchasesSizeSubs() 獲取有效訂閱的數量(-1查詢失敗,0沒有有效訂閱,>0具有有效的訂閱)

//便捷工具
12、public int getSubsPositionBySku(String sku) 通過sku獲取訂閱商品序號
13、public int getInAppPositionBySku(String sku) 通過sku獲取內購商品序號
14、public String getSubsSkuByPosition(int position) 通過序號獲取訂閱sku
15、public String getInAppSkuByPosition(int position) 通過序號獲取內購sku
16、private String getSkuType(String sku) 通過sku獲取商品型別(訂閱獲取內購)inapp內購,subs訂閱

//介面設定
17、public GoogleBillingUtil setOnPurchaseFinishedListener(OnPurchaseFinishedListener onPurchaseFinishedListener) 購買回調介面
18、public GoogleBillingUtil setOnQueryFinishedListener(OnQueryFinishedListener onQueryFinishedListener) 商品資訊查詢介面
19、public GoogleBillingUtil setOnStartSetupFinishedListener(OnStartSetupFinishedListener onStartSetupFinishedListener) 服務初始化結果回撥介面 

//其他、記憶體
20、public void setIsAutoConsumeAsync(boolean isAutoConsumeAsync) 設定是否自動消耗商品
21、public static void cleanListener() 清除所有監聽器,避免記憶體洩漏,回撥錯亂等問題。
22、public static void endConnection() 斷開連線google服務(一般情況不建議呼叫該方法,讓google保留連線是最好的選擇。)

二、googleplay操作部分:

當你把程式碼新增完成後,可以在程式碼中新增一個skuid :(由字母和數字組成,例如weather_54).private String[] inAppSKUS = new String[]{"weather_54","",""},這個要與googlePlay應用內商品欄的新增商品一欄對應。然後打包apk.

①、翻牆上傳應用,應用上傳部分這裡不做詳細講解。可以先上傳一個內部測試版本。內部測試版本支付不會扣除金額。如下圖所示:

我這裡上傳的是alpha測試版本,可以新增測試人員。當完成apk上傳之後,會生成一個測試版本的googleplay下載地址。

②、應用內商品

當你的應用存在需要google登入或者其他使用到簽名的位置的話,記住:千萬不要選擇應用簽名!千萬不要選擇應用簽名!千萬不要選擇應用簽名!。它會覆蓋你的簽名。而且不可逆操作。

需要你填寫一些資訊,例如銀行卡之類的。這裡公司已經填好了。

③、新增商品:

還記得那個skuid麼,對。就是這個Id名稱。

④、開始填寫定價內容:

紅框裡面的內容可以更改。

好了。儲存更改後。就可以進行測試了。如果你的程式碼以及googleplay應用都ok的話。點選支付,就可以看到如下圖所示:

文章就到這裡了。有疑問隨時可以@我~~~~thanks