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;
}
}
}
}
);
}
}