• android google登录和支付


    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() {

                        @Override

                        public void onComplete(@NonNull Task 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() {

                        @Override

                        public void onComplete(@NonNull Task 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 task = GoogleSignIn.getSignedInAccountFromIntent(data);

                handleSignInResult(task);

            }

        }

        private void handleSignInResult(Task 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 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 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 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;

                                }

                            }


     

                        }

                    }

            );

        }

    }

  • 相关阅读:
    STM32获取最大堆栈空间
    Leetcode 数据库中等题(day 1)
    Android Studio 写一个Java调用c++ 的demo
    排序算法-基数排序法(RadixSort)
    K_A08_002 基于 STM32等单片机驱动MAX1508模块按键控制直流电机正反转加减速启停
    [mysql] 深入分析MySQL版本控制MVCC规则--实测 (mysql 8.0 innodb引擎)
    指标体系搭建-专项1
    SpringMVC(九):作用域传参
    C++中的类、结构体、指针和引用
    web安全之MySQL手工注入的原理讲解和实验分析
  • 原文地址:https://blog.csdn.net/xuyid/article/details/126061846