package com.mycompany.app;

import android.app.Activity;

import android.content.Intent;

import android.os.Handler;

import android.util.Log;

import androidx.annotation.NonNull;

import androidx.annotation.Nullable;


 

import com.android.billingclient.api.BillingClient;

import com.android.billingclient.api.BillingClientStateListener;

import com.android.billingclient.api.BillingFlowParams;

import com.android.billingclient.api.BillingResult;

import com.android.billingclient.api.ConsumeParams;

import com.android.billingclient.api.ConsumeResponseListener;

import com.android.billingclient.api.ProductDetails;

import com.android.billingclient.api.ProductDetailsResponseListener;

import com.android.billingclient.api.Purchase;

import com.android.billingclient.api.PurchaseHistoryRecord;

import com.android.billingclient.api.PurchaseHistoryResponseListener;

import com.android.billingclient.api.PurchasesUpdatedListener;

import com.android.billingclient.api.QueryProductDetailsParams;

import com.android.billingclient.api.QueryPurchaseHistoryParams;

import com.google.android.gms.auth.api.signin.GoogleSignIn;

import com.google.android.gms.auth.api.signin.GoogleSignInAccount;

import com.google.android.gms.auth.api.signin.GoogleSignInClient;

import com.google.android.gms.auth.api.signin.GoogleSignInOptions;

import com.google.android.gms.common.api.ApiException;

import com.google.android.gms.tasks.OnCompleteListener;

import com.google.android.gms.tasks.Task;

import com.google.common.collect.ImmutableList;

import org.json.JSONException;

import org.json.JSONObject;

import java.util.List;

/**google登录支付功能封装*/

public class myGooglePlayUtil {

    private static final String TAG = "myGooglePlayUtil";

    private static  myGooglePlayUtil _myGooglePlayUtil;

    private Activity activity;

    private  GoogleSignInClient mGoogleSignInClient;

    private BillingClient mBillingclient;

    private  int RC_SIGN_IN = 101;

    private Handler handler = new Handler();

    private final int consumeImmediately = 0;

    private final int consumeDelay = 1;

    public static myGooglePlayUtil getInstance(){

        if (_myGooglePlayUtil == null) {

            _myGooglePlayUtil = new myGooglePlayUtil();

        }

        return  _myGooglePlayUtil;

    }

    //初始化

    public void initSDK(Activity _activity){

        this.activity = _activity;

        //登录

        GoogleSignInOptions gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)

                .requestEmail()

                .requestIdToken("106090399679-do5a696fi87nh1c1lv9uukg0q76qtbs0.apps.googleusercontent.com")

                .build();

        this.mGoogleSignInClient = GoogleSignIn.getClient(activity, gso);

        //支付

        mBillingclient = BillingClient.newBuilder(activity)

                .setListener(mPurchasesUpdatedListener)

                .enablePendingPurchases()

                .build();

    }

    //登录

    public   void loginGoogle(){

        Intent signInIntent = this.mGoogleSignInClient.getSignInIntent();

        this.activity.startActivityForResult(signInIntent, this.RC_SIGN_IN);

    }

    //退出

    public void logoutGoogle(){

        this.mGoogleSignInClient.signOut()

                .addOnCompleteListener(activity, new OnCompleteListener<Void>() {

                    @Override

                    public void onComplete(@NonNull Task<Void> task) {

                        Log.e(TAG, "退出登录");

                        JSONObject jsonObject = new JSONObject();

                        try {

                            jsonObject.put("code","100");

                            jsonObject.put("eventName","logout");

                        } catch (JSONException e) {

                            e.printStackTrace();

                        }

                        CoronaApplication.dispatchEvent(jsonObject.toString());

                    }

                });

    }

    //注销

    public void revokeAccessGoogle(){

     this.mGoogleSignInClient.revokeAccess()

                .addOnCompleteListener(activity, new OnCompleteListener<Void>() {

                    @Override

                    public void onComplete(@NonNull Task<Void> task) {

                        Log.e(TAG, "断开账户");

                        JSONObject jsonObject = new JSONObject();

                        try {

                            jsonObject.put("code","100");

                            jsonObject.put("eventName","revokeAccess");

                        } catch (JSONException e) {

                            e.printStackTrace();

                        }

                        CoronaApplication.dispatchEvent(jsonObject.toString());

                    }

                });

    }

    //发送登录数据给lua

    public  void SignInToLua(GoogleSignInAccount account){

        Log.e(TAG, "account--------------->>>" + account);

        Log.e(TAG, "signInResult:success name:" + account.getDisplayName());

        Log.e(TAG, "signInResult:success id:" + account.getId());

        Log.e(TAG, "signInResult:success email:" + account.getEmail());

        Log.e(TAG, "signInResult:success token:" + account.getIdToken());

        JSONObject jsonObject = new JSONObject();

        try {

            jsonObject.put("code","100");

            jsonObject.put("eventName","login");

            JSONObject jsonObject2 = new JSONObject();

            jsonObject2.put("userID",account.getId());

            jsonObject2.put("identityToken",account.getIdToken());

            jsonObject2.put("bundleIdentifier",this.activity.getPackageName());

            jsonObject.put("eventData",jsonObject2);

        } catch (JSONException e) {

            e.printStackTrace();

        }

        CoronaApplication.dispatchEvent(jsonObject.toString());

    }

    protected void onActivityResult(int requestCode, int resultCode, Intent data) {

        Log.e(TAG, "requestCode--------------->>>" + requestCode);

        if (requestCode == this.RC_SIGN_IN) {

            Task<GoogleSignInAccount> task = GoogleSignIn.getSignedInAccountFromIntent(data);

            handleSignInResult(task);

        }

    }

    private void handleSignInResult(Task<GoogleSignInAccount> completedTask) {

        try {

            GoogleSignInAccount account = completedTask.getResult(ApiException.class);

            this.SignInToLua(account);

        } catch (ApiException e) {

            // The ApiException status code indicates the detailed failure reason.

            // Please refer to the GoogleSignInStatusCodes class reference for more information.

            Log.e(TAG, "signInResult:failed code=" + e.getStatusCode());

        }

    }



 

    private PurchasesUpdatedListener mPurchasesUpdatedListener = new PurchasesUpdatedListener() {

        @Override

        public void onPurchasesUpdated(@NonNull BillingResult billingResult, @Nullable List<Purchase> list) {

            String debugMessage = billingResult.getDebugMessage();

            Log.e(TAG, "---onPurchasesUpdated---debugMessage:"+debugMessage);

            if (list != null && list.size() > 0) {

                Log.e(TAG, "---onPurchasesUpdated---list.size():"+list.size());

                Log.e(TAG, "---onPurchasesUpdated---billingResult.getResponseCode():"+billingResult.getResponseCode());

                if (billingResult.getResponseCode() == BillingClient.BillingResponseCode.OK) {

                    for (Purchase purchase : list) {

                        if(purchase == null || purchase.getPurchaseState() != Purchase.PurchaseState.PURCHASED) continue;

                        consumePurchase(purchase.getPurchaseToken(),purchase.getOrderId());

                        //通知服务器支付成功,服务端验证后,消费商品

                        //TODO客户端同步回调支付成功

                    }

                }

            } else {

                Log.e(TAG, "---onPurchasesUpdated---billingResult.getResponseCode():"+billingResult.getResponseCode());

                switch (billingResult.getResponseCode()) {

                    case BillingClient.BillingResponseCode.SERVICE_TIMEOUT: //服务连接超时

                        break;

                    case BillingClient.BillingResponseCode.FEATURE_NOT_SUPPORTED:

                        break;

                    case BillingClient.BillingResponseCode.SERVICE_DISCONNECTED: //服务未连接

                        break;

                    case BillingClient.BillingResponseCode.USER_CANCELED: //取消

                        break;

                    case BillingClient.BillingResponseCode.SERVICE_UNAVAILABLE: //服务不可用

                        break;

                    case BillingClient.BillingResponseCode.BILLING_UNAVAILABLE: //购买不可用

                        break;

                    case BillingClient.BillingResponseCode.ITEM_UNAVAILABLE: //商品不存在

                        break;

                    case BillingClient.BillingResponseCode.DEVELOPER_ERROR: //提供给 API 的无效参数

                        break;

                    case BillingClient.BillingResponseCode.ERROR: //错误

                        break;

                    case BillingClient.BillingResponseCode.ITEM_ALREADY_OWNED: //未消耗掉

                        queryPurchases();

                        break;

                    case BillingClient.BillingResponseCode.ITEM_NOT_OWNED: //不可购买

                        break;

                }

            }

        }

    };

    public boolean startConnection(final String productId){

        if(mBillingclient == null || !mBillingclient.isReady()){

            Log.e(TAG, "---startConnection---");

            //TODO客户端同步回调支付失败,原因是为链接到google或者google的支付服务不能使用

            mBillingclient.startConnection(new BillingClientStateListener() {  //重新连接

                @Override

                public void onBillingServiceDisconnected() {

                    //尝试重新启动连接的下一个请求

                    //谷歌通过调用startConnection()方法进行播放。

                    Log.e(TAG, "---onBillingServiceDisconnected---");

                    new Handler().postDelayed(()->{

                        startConnection(productId);

                    },1000);

                }

                @Override

                public void onBillingSetupFinished(@NonNull BillingResult billingResult) {

                    Log.e(TAG, "---onBillingSetupFinished---getResponseCode:"+billingResult.getResponseCode() );

                    if (billingResult.getResponseCode() ==  BillingClient.BillingResponseCode.OK) {

                        //BillingClient已经准备好。 你可以在这里查询购买情况。

                        querySkuDetailsAsync(productId);

                    }

                }

            });

            return false;

        }

        return true;

    }

    public void pay(final String productId) {

        boolean bol = startConnection(productId);

        if (bol){

            //查询商品详情

            querySkuDetailsAsync(productId);

        }

    }

    //查询商品详情

    void querySkuDetailsAsync(final String productId){

        Log.e(TAG, "querySkuDetailsAsync.productId:"+productId);

        QueryProductDetailsParams queryProductDetailsParams = QueryProductDetailsParams.newBuilder()

                .setProductList(ImmutableList.of(

                        QueryProductDetailsParams.Product.newBuilder()

                                .setProductId(productId)

                                .setProductType(BillingClient.ProductType.INAPP)

                                .build()))

                        .build();

        mBillingclient.queryProductDetailsAsync(

                queryProductDetailsParams,

                new ProductDetailsResponseListener() {

                    public void onProductDetailsResponse(BillingResult billingResult,

                                                         List<ProductDetails> productDetailsList) {

                        // check billingResult

                        // process returned productDetailsList

                        Log.e(TAG, "billingResult.getResponseCode:"+billingResult.getResponseCode());

                        if (productDetailsList != null && billingResult.getResponseCode() ==  BillingClient.BillingResponseCode.OK){

                            Log.e(TAG, "productDetailsList.length:"+productDetailsList.size());

                            Log.e(TAG, "productId:"+productId);

                            for(ProductDetails skuDetails : productDetailsList){

                                Log.e(TAG, "skuDetails.getProductId:"+skuDetails.getProductId());

                                if(productId.equals(skuDetails.getProductId())){

                                    //发起支付

                                    launchBillingFlow(skuDetails);

                                }

                            }

                        }

                    }

                }

        );

    }

    /**

     * 拉取google支付页面

     * @param productDetails

     */

    void launchBillingFlow(ProductDetails productDetails){

        Log.e(TAG, "----launchBillingFlow---");

        ImmutableList productDetailsParamsList =

                ImmutableList.of(

                        BillingFlowParams.ProductDetailsParams.newBuilder()

                                // retrieve a value for "productDetails" by calling queryProductDetailsAsync()

                                .setProductDetails(productDetails)

                                .build()

                );

        BillingFlowParams billingFlowParams = BillingFlowParams.newBuilder()

                .setProductDetailsParamsList(productDetailsParamsList)

                .build();

        BillingResult result = mBillingclient.launchBillingFlow(activity, billingFlowParams);

        Log.e(TAG,"getResponseCode:"+ result.getResponseCode());

        if(result.getResponseCode() == BillingClient.BillingResponseCode.OK) {

            Log.e("toString:", result.toString());

        }else{

            Log.e("getDebugMessage:", result.getDebugMessage());

        }

    }

    //发送支付订单数据给lua

    public  void payToLua(final String purchaseToken,final String  orderId){

        JSONObject jsonObject = new JSONObject();

        try {

            jsonObject.put("code","100");

            jsonObject.put("eventName","pay");

            JSONObject jsonObject2 = new JSONObject();

            jsonObject2.put("purchaseToken",purchaseToken);

            jsonObject2.put("orderId",orderId);

            jsonObject.put("eventData",jsonObject2);

        } catch (JSONException e) {

            e.printStackTrace();

        }

        CoronaApplication.dispatchEvent(jsonObject.toString());

    }

    public void consumePurchase(final String purchaseToken,final String  orderId){

        Log.i("Tag","消耗商品:purchaseToken:" + purchaseToken+"   orderId:"+orderId);

        ConsumeParams consumeParams = ConsumeParams.newBuilder()

                .setPurchaseToken(purchaseToken)

                .build();

        ConsumeResponseListener listener = new ConsumeResponseListener() {

            @Override

            public void onConsumeResponse(BillingResult billingResult, String purchaseToken) {

                if (billingResult.getResponseCode() == BillingClient.BillingResponseCode.ERROR) {

                    //消费失败将商品重新放入消费队列

                    Log.i("TAG", "消费失败");

                    return;

                }

                Log.i("TAG", "消费成功 purchaseToken: "+purchaseToken);

                payToLua(purchaseToken,orderId);

            }

        };

        mBillingclient.consumeAsync(consumeParams, listener);

    }

    /**

     * 补单操作 查询已支付的商品,并通知服务器后消费(google的支付里面,没有消费的商品,不能再次购买)

     */

    private void queryPurchases(){

        mBillingclient.queryPurchaseHistoryAsync(

                QueryPurchaseHistoryParams.newBuilder()

                        .setProductType(BillingClient.ProductType.INAPP)

                        .build(),

                new PurchaseHistoryResponseListener() {

                    public void onPurchaseHistoryResponse(

                            BillingResult billingResult, List<PurchaseHistoryRecord> purchasesHistoryList) {

                        if(billingResult.getResponseCode() != BillingClient.BillingResponseCode.OK && purchasesHistoryList != null){

                            for (PurchaseHistoryRecord purchaseHistoryRecord : purchasesHistoryList) {

                                //通知服务器支付成功,服务端验证后,消费商品

                                //TODO客户端同步回调支付成功

                                //purchaseHistoryRecord.getPurchaseToken()

                                consumePurchase(purchaseHistoryRecord.getPurchaseToken(),purchaseHistoryRecord.getOriginalJson());

                            }

                        }else{

                            switch (billingResult.getResponseCode()) {

                                case BillingClient.BillingResponseCode.SERVICE_TIMEOUT: //服务连接超时

                                    break;

                                case BillingClient.BillingResponseCode.FEATURE_NOT_SUPPORTED:

                                    break;

                                case BillingClient.BillingResponseCode.SERVICE_DISCONNECTED: //服务未连接

                                    break;

                                case BillingClient.BillingResponseCode.USER_CANCELED: //取消

                                    break;

                                case BillingClient.BillingResponseCode.SERVICE_UNAVAILABLE: //服务不可用

                                    break;

                                case BillingClient.BillingResponseCode.BILLING_UNAVAILABLE: //购买不可用

                                    break;

                                case BillingClient.BillingResponseCode.ITEM_UNAVAILABLE: //商品不存在

                                    break;

                                case BillingClient.BillingResponseCode.DEVELOPER_ERROR: //提供给 API 的无效参数

                                    break;

                                case BillingClient.BillingResponseCode.ERROR: //错误

                                    break;

                                case BillingClient.BillingResponseCode.ITEM_ALREADY_OWNED: //未消耗掉

                                    queryPurchases();

                                    break;

                                case BillingClient.BillingResponseCode.ITEM_NOT_OWNED: //不可购买

                                    break;

                            }

                        }


 

                    }

                }

        );

    }

}

Logo

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

更多推荐