1. 需要在google play console后台注册开发者账号,配置相关内购的商品等这是属于运营来做

2. 在项目build.gradle文件添加

  implementation 'com.google.android.gms:play-services-wallet:18.1.3'
  implementation 'com.android.billingclient:billing:3.0.3'

3.新建一个工具类 

public class GoogleBillingUtil {

  private static final String TAG = "```GoogleBillingUtil";
  private static final boolean IS_DEBUG = true;
  private static String[] inAppSKUS;
  private String[] subsSKUS = new String[]{"6"};//订阅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(String productId)
  {
    //googleplay应用内商品栏,添加商品后得到
  inAppSKUS = new String[]{productId};//内购ID,必填
    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()).enablePendingPurchases().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(@NonNull BillingResult billingResult) {
          if (billingResult.getResponseCode() == BillingClient.BillingResponseCode.OK) {
            queryInventoryInApp();
//            queryInventorySubs();
            queryPurchasesInApp();
            if(mOnStartSetupFinishedListener!=null)
            {
              mOnStartSetupFinishedListener.onSetupSuccess();
            }
          }
          else
          {
            log("初始化失败:onSetupFail:code="+billingResult.getResponseCode());
            if(mOnStartSetupFinishedListener!=null)
            {
              mOnStartSetupFinishedListener.onSetupFail(billingResult.getResponseCode());
            }
          }
        }

        @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(@NonNull BillingResult billingResult, @Nullable List<Purchase> list) {
      if(mOnPurchaseFinishedListener==null)
      {
        if(IS_DEBUG)
        {
          log("警告:接收到购买回调,但购买商品接口为Null,请设置购买接口。eg:setOnPurchaseFinishedListener()");
        }
        return ;
      }
      if(billingResult.getResponseCode()== BillingClient.BillingResponseCode.OK&&list!=null)
      {
        if(isAutoConsumeAsync)
        {
          //消耗商品
          for(Purchase purchase:list)
          {
//            ArrayList<String> sku = purchase.getSkus();
            String sku = purchase.getSku();
            if(sku!=null)
            {
//              String skuType = getSkuType(sku.get(0));
              String skuType = getSkuType(sku);

              if(skuType!=null)
              {
                if(skuType.equals(BillingClient.SkuType.INAPP))
                {
                  consumeAsync(purchase.getPurchaseToken());
                }
              }
            }
          }
        }
        mOnPurchaseFinishedListener.onPurchaseSuccess(list);
      }
      else
      {
        mOnPurchaseFinishedListener.onPurchaseFail(billingResult.getResponseCode());
      }
    }
  }

  /**
   * 查询内购商品信息
   */
  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 ;
    private List<SkuDetails> list=new ArrayList<>();

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


    @Override
    public void onSkuDetailsResponse(@NonNull BillingResult billingResult, @Nullable List<SkuDetails> list) {
      this.list=list;
      if(mOnQueryFinishedListener==null)
      {
        if(IS_DEBUG) {
          log("警告:接收到查询商品回调,但查询商品接口为Null,请设置购买接口。eg:setOnQueryFinishedListener()");
        }
        return ;
      }
      if(billingResult.getResponseCode()== BillingClient.BillingResponseCode.OK&&list!=null)
      {
        mOnQueryFinishedListener.onQuerySuccess(skuType,list);
      }
      else
      {
        mOnQueryFinishedListener.onQueryFail(billingResult.getResponseCode());
      }
    }
  }

  /**
   * 发起内购
   * @param skuId
   * @return
   */
  public void purchaseInApp(Activity activity,SkuDetails skuId)
  {
    purchase(activity,skuId, BillingClient.SkuType.INAPP);
  }

  /**
   * 发起订阅
   * @param skuId
   * @return
   */
  public void purchaseSubs(Activity activity,SkuDetails skuId)
  {
    purchase(activity,skuId, BillingClient.SkuType.SUBS);
  }

  private void purchase(Activity activity,final SkuDetails skuId,final String skuType)
  {
    if(mBillingClient==null)
    {
      if(mOnPurchaseFinishedListener!=null)
      {
        mOnPurchaseFinishedListener.onPurchaseError();
      }
      return ;
    }
    if(startConnection())
    {

      BillingFlowParams flowParams = BillingFlowParams.newBuilder()
              .setSkuDetails(skuId)
              .build();
      mBillingClient.launchBillingFlow(activity,flowParams);
    }
    else
    {
      if(mOnPurchaseFinishedListener!=null)
      {
        mOnPurchaseFinishedListener.onPurchaseError();
      }
    }
  }

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

    ConsumeParams consumeParams =
            ConsumeParams.newBuilder()
                    .setPurchaseToken(purchaseToken)
                    .build();
    mBillingClient.consumeAsync(consumeParams, new MyConsumeResponseListener());
  }

  /**
   * Googlg消耗商品回调
   */
  private class MyConsumeResponseListener implements ConsumeResponseListener
  {

    @Override
    public void onConsumeResponse(@NonNull BillingResult billingResult, @NonNull String s) {
      if (billingResult.getResponseCode() == BillingClient.BillingResponseCode.OK) {
          Log.e("googlePayWay","消耗成功");
      }
    }
  }


  /**
   * 获取已经内购的商品
   * @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.BillingResponseCode.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;
  }
}

4.如何使用

首先需要定义三个类来实现购买回调接口,查询商品回调接口,服务初始化结果回调接口

 //服务初始化结果回调接口
    private class MyOnStartSetupFinishedListener implements GoogleBillingUtil.OnStartSetupFinishedListener
    {
        @Override
        public void onSetupSuccess() {
            Log.e("googlePay","初始化成功");
        }

        @Override
        public void onSetupFail(int responseCode) {
            
            Log.e("googlePay","初始化失败="+responseCode);
          

        }

        @Override
        public void onSetupError() {
           
            Log.e("googlePayWay","初始化错误");
        
        }
//...;
    }


    //购买商品回调接口
    private class MyOnPurchaseFinishedListener implements GoogleBillingUtil.OnPurchaseFinishedListener
    {
        @RequiresApi(api = Build.VERSION_CODES.O)
        @Override
        public void onPurchaseSuccess(List<Purchase> list) {
           
            //内购或者订阅成功,可以通过purchase.getSku()获取suk进而来判断是哪个商品
           
        }

        @Override
        public void onPurchaseFail(int responseCode) {
          
            Log.e("googlePayWay","购买失败码="+responseCode);
           
        }

        @Override
        public void onPurchaseError() {
         
            Log.e("googlePayWay","购买错误码=");
           
        }
    }

//查询商品信息回调接口
    private class MyOnQueryFinishedListener implements GoogleBillingUtil.OnQueryFinishedListener
    {
        @Override
        public void onQuerySuccess(String skuType,List<SkuDetails> list) {
            //查询成功,返回商品列表,
           
        }
        @Override
        public void onQueryFail(int responseCode) {
      
            //查询失败
            Log.e("googlePayWay","查询失败="+responseCode);
           
        }
        @Override
        public void onQueryError() {
            //查询错误
       
            Log.e("googlePayWay","查询错误");
          
        }
    }

 然后在需要的地方加入以下代码

private MyOnPurchaseFinishedListener mOnPurchaseFinishedListener = new MyOnPurchaseFinishedListener();//购买回调接口
private MyOnQueryFinishedListener mOnQueryFinishedListener = new MyOnQueryFinishedListener();//查询回调接口
private MyOnStartSetupFinishedListener mOnStartSetupFinishedListener = new MyOnStartSetupFinishedListener();//服务初始化结果回调接口
GoogleBillingUtil  googleBillingUtil = GoogleBillingUtil.getInstance(id)//这个id是google play console后台配置的商品id
                .setOnPurchaseFinishedListener(mOnPurchaseFinishedListener)//购买回调接口
                .setOnQueryFinishedListener(mOnQueryFinishedListener)//查询商品回调接口
                .setOnStartSetupFinishedListener(mOnStartSetupFinishedListener)//服务初始化结果回调接口
.build(context); googleBillingUtil.setIsAutoConsumeAsync(true);//购买成功之后是否消耗商品

就此完成 

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐