前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >ArkUI-X和原生交互调用Google内购支付

ArkUI-X和原生交互调用Google内购支付

作者头像
徐建国
发布2024-04-11 13:38:26
1000
发布2024-04-11 13:38:26
举报
文章被收录于专栏:个人路线个人路线

前言

作者:徐庆 团队:坚果派 公众号:“大前端之旅” 专注于分享的技术包括HarmonyOS/OpenHarmony,ArkUI-X,元服务,服务卡片,华为自研语言,团队成员聚集在北京,上海,南京,深圳,广州,宁夏等地,欢迎合作。

效果图 :

image-20240401165723643

image-20240401165832114

实现方式

我们是通过AkrUi-X和安卓交互 然后在原生安卓里面加入了内购支付结算库的依赖 最后调起的Google 支付 安卓原生内购支付教程

ArkUI端代码

akrui 端我这边只写了一个按钮调用Google内购支付和接收数据

image-20240401170219038

导入平台桥接模块
代码语言:javascript
复制
// 导入平台桥接模块
import bridge from '@arkui-x.bridge';
创建平台桥接对象
代码语言:javascript
复制
  // 创建平台桥接对象
  private bridgeImpl = bridge.createBridge('Bridge');
  
代码语言:javascript
复制
// 发送数据到Android侧,并通过状态变量,将Android侧的响应数据显示在页面上
    this.nativeResponse = await this.bridgeImpl.sendMessage('Hello ArkUI-X!');

接收回传回来的数据

代码语言:javascript
复制
  aboutToAppear() {
    this.getHelloArkUI();
  }

  getHelloArkUI() {
    // 调用Android侧方法
    this.bridgeImpl.callMethod('getHelloArkUI').then((result: string) => {
      // 通过状态变量,将Android侧方法的返回值显示在页面上
      this.helloArkUI = result;
    });

完整代码

代码语言:javascript
复制
// 导入平台桥接模块
import bridge from '@arkui-x.bridge';

@Entry
@Component
struct Index {
  // 创建平台桥接对象
  private bridgeImpl = bridge.createBridge('Bridge');
  @State helloArkUI: string = '';
  @State nativeResponse: string = '';

  aboutToAppear() {
    this.getHelloArkUI();
  }

  getHelloArkUI() {
    // 调用Android侧方法
    // this.bridgeImpl.callMethod('getHelloArkUI').then((result: string) => {
    //   // 通过状态变量,将Android侧方法的返回值显示在页面上
    //   this.helloArkUI = result;
    // });

/*    this.bridgeImpl?.callMethod('getHelloArkUI').then((data)=>{


    });*/

    // let resultPromise=this.bridgeImpl.callMethod('getHelloArkUI'):resultPromise.then((data)=>{
    //
    //
    //
    //   })
  }

  build() {
    Row() {
      Column() {
        Text(this.helloArkUI)
          .fontSize(15)
          .margin(10)
        Button('点击Google支付')
          .fontSize(15)
          .margin(10)
          .onClick(async () => {
            // 发送数据到Android侧,并通过状态变量,将Android侧的响应数据显示在页面上
             await this.bridgeImpl.sendMessage('Hello ArkUI-X!');
          })
        Text('Response from Native: ' + this.nativeResponse)
          .fontSize(15)
          .margin(10)
      }
      .width('100%')
    }
    .height('100%')
  }
}

安卓部分

我们编译项目 需要导入arkui-x编译之后产生的安卓原生宿主工程

image-20240401170755439

官方文档地址

Google结算库

需要的依赖

def billing_version = "6.0.0" implementation "com.android.billingclient:billing:$billing_version"

image-20240401170856828

akrui-x 和原生安卓通信交互
引用平台桥接模块
代码语言:javascript
复制
package com.example.helloworld;

/**
 * 作者:xuqing
 * 时间:2024年04月01日 15:27:31
 * 邮箱:1693891473@qq.com
 * 说明:
 */
import android.app.Activity;
import android.content.Context;
import android.util.Log;

// 引用平台桥接模块
import ohos.ace.adapter.capability.bridge.BridgePlugin;
import ohos.ace.adapter.capability.bridge.IMessageListener;

public class Bridge extends BridgePlugin implements IMessageListener {

    private static final String TAG = "Bridge";
    private Context context;
    public Bridge(Context context, String name, int id) {
        super(context, name, id);
        this.context=context;

        setMessageListener(this);
    }

    // Android侧方法,供ArkUI侧调用
    public String getHelloArkUI() {
        return "Hello ArkUI!";
    }

    // 注册回调,接收ArkUI侧发来的数据
    @Override
    public Object onMessage(Object object) {

      //  new EntryEntryAbilityActivity(). initgooglePlay();
        GooglePay.getInstance().toGooglePay((Activity) context,"com.testgame.099");

        Log.e(TAG, "onMessage: "+object.toString() );
        return "java onMessage success";
    }

    @Override
    public void onMessageResponse(Object object) {


    }
}

内购支付初始化

代码语言:javascript
复制
public  void initgooglePlay(Activity context) {
    billingClient = BillingClient.newBuilder(context)
            .setListener(purchasesUpdatedListener)
            .enablePendingPurchases()
            .build();
    if(billingClient!=null){
        billingClient.startConnection(new BillingClientStateListener() {
            @Override
            public void onBillingSetupFinished(BillingResult billingResult) {
                if (billingResult.getResponseCode() ==  BillingClient.BillingResponseCode.OK) {

                }
            }
            @Override
            public void onBillingServiceDisconnected() {

            }
        });
    }
}

调用起内购支付

代码语言:javascript
复制
public   void  toGooglePay(Activity context,String productId){
    //  String productId ="xxxx";
    List<QueryProductDetailsParams.Product> productList= new ArrayList<>();
    productList.add(QueryProductDetailsParams.Product.newBuilder()
            .setProductId(productId)
            .setProductType(BillingClient.ProductType.INAPP)
            .build());
    QueryProductDetailsParams queryProductDetailsParams = QueryProductDetailsParams.newBuilder().
            setProductList(productList)
            .build();
    if(billingClient!=null){
        billingClient.queryProductDetailsAsync(
                queryProductDetailsParams,
                new ProductDetailsResponseListener() {
                    public void onProductDetailsResponse(BillingResult billingResult,
                                                         List<ProductDetails> productDetailsList) {
                        if(productDetailsList!=null&&productDetailsList.size()>0){


                            ProductDetails productDetails=productDetailsList.get(0);
                            List<BillingFlowParams.ProductDetailsParams> productDetailsParamsList= new ArrayList<>();
                            productDetailsParamsList.add(BillingFlowParams.ProductDetailsParams.newBuilder()
                                    .setProductDetails(productDetails)
                                    .build());
                            BillingFlowParams billingFlowParams = BillingFlowParams.newBuilder()
                                    .setProductDetailsParamsList(productDetailsParamsList)
                                    .build();
                            billingClient.launchBillingFlow((Activity) context, billingFlowParams);
                        }else {
                            Toast.makeText(context,"商品ID无效",Toast.LENGTH_SHORT).show();
                        }
                    }
                }
        );
    }
}

我们在arkui-x调用安卓原生的回调方法里面去调用我们的 toGooglePay 传入我们的商品ID 即可

  • 支付回调
代码语言:javascript
复制
    private PurchasesUpdatedListener purchasesUpdatedListener = new PurchasesUpdatedListener() {
        @Override
        public void onPurchasesUpdated(BillingResult billingResult, List<Purchase> purchases) {
            if (billingResult.getResponseCode() == BillingClient.BillingResponseCode.OK
                    && purchases != null) {
                for (Purchase purchase : purchases) {
                    handlePurchase(purchase);

                    Log.e(TAG, "getPurchaseToken: "+ purchase.getPurchaseToken() );
                    Log.e(TAG, "getSignature: "+ purchase.getSignature() );
                    Log.e(TAG, "getSignature: "+ purchase.getSignature() );
                }
            } else if (billingResult.getResponseCode() == BillingClient.BillingResponseCode.USER_CANCELED) {


            } else {
            }
        }
    };

我们拿到回调里面的 getPurchaseToken getSignature getSignature 信息之后可以去自己服务端进行验签 如果验签成功了才算是真正的成功支付成功 然后再进行消耗

  • 商品消耗
代码语言:javascript
复制
public void handlePurchase(final Purchase purchase) {
    ConsumeParams consumeParams =
            ConsumeParams.newBuilder()
                    .setPurchaseToken(purchase.getPurchaseToken())
                    .build();
    ConsumeResponseListener listener = new ConsumeResponseListener() {
        @Override
        public void onConsumeResponse(BillingResult billingResult, String purchaseToken) {
            if (billingResult.getResponseCode() == BillingClient.BillingResponseCode.OK) {

                Log.e(TAG, "getPurchaseToken: "+ purchase.getPurchaseToken() );
                Log.e(TAG, "getSignature: "+ purchase.getSignature() );
                Log.e(TAG, "getSignature: "+ purchase.getSignature() );
            }
        }
    };
    if(billingClient!=null){
        billingClient.consumeAsync(consumeParams, listener);
    }
}
  • 支付完成后下次支付前查询消耗
代码语言:javascript
复制
public   void  queryPurchasesAsync(Activity context){
    if(billingClient!=null){
        if(!billingClient.isReady()){
            Toast.makeText(context,"BillingClient is not ready",Toast.LENGTH_SHORT).show();
        }
        billingClient.queryPurchasesAsync(
                QueryPurchasesParams.newBuilder().setProductType(BillingClient.ProductType.INAPP).build(),
                new PurchasesResponseListener() {
                    public void onQueryPurchasesResponse(
                            BillingResult billingResult,
                            List<Purchase> purchases) {
                        if(billingResult.getResponseCode()==BillingClient.BillingResponseCode.OK){
                            if(purchases!=null&&purchases.size()>0){
                                for (Purchase purchase:purchases){
                                    handlePurchase(purchase);
                                }
                            }
                        }
                    }
                }
        );
    }
}

请再 onResume 声明周期方法里面调用

代码语言:javascript
复制
@Override
protected void onResume() {
    super.onResume();
    GooglePay.getInstance().queryPurchasesAsync(EntryEntryAbilityActivity.this);
}

完整Android端代码

EntryEntryAbilityActivity 端代码

代码语言:javascript
复制

代码语言:javascript
复制
package com.example.helloworld;

import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.util.Log;


import com.android.billingclient.api.BillingClient;


import ohos.stage.ability.adapter.StageActivity;


/**
 * Example ace activity class, which will load ArkUI-X ability instance.
 * StageActivity is provided by ArkUI-X
 * @see <a href=
 * "https://gitee.com/arkui-crossplatform/doc/blob/master/contribute/tutorial/how-to-build-Android-app.md">
 * to build android library</a>
 */
public class EntryEntryAbilityActivity extends StageActivity {

    private static final String TAG = "MainActivity";

    private Context context=EntryEntryAbilityActivity.this;
    private BillingClient billingClient;



    @Override
    protected void onCreate(Bundle savedInstanceState) {
        Log.e("HiHelloWorld", "EntryEntryAbilityActivity");

        new Bridge(this, "Bridge", getInstanceId());
        //setInstanceName("com.example.helloworld:entry:EntryAbility:");
        setInstanceName("com.example.helloworld:entry:EntryAbility:");
        super.onCreate(savedInstanceState);
        GooglePay.getInstance().initgooglePlay(EntryEntryAbilityActivity.this);
    }


    @Override
    protected void onResume() {
        super.onResume();
        GooglePay.getInstance().queryPurchasesAsync(EntryEntryAbilityActivity.this);
    }
    @Override
    public void onStop() {
        super.onStop();
    }
    @Override
    protected void onPause() {
        super.onPause();
    }

  }

googlepay 工具类代码

代码语言:javascript
复制
package com.example.helloworld;

import android.app.Activity;
import android.content.Context;
import android.util.Log;
import android.widget.Toast;

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.PurchasesResponseListener;
import com.android.billingclient.api.PurchasesUpdatedListener;
import com.android.billingclient.api.QueryProductDetailsParams;
import com.android.billingclient.api.QueryPurchasesParams;

import java.util.ArrayList;
import java.util.List;

/**
 * 作者:xuqing
 * 时间:2024年04月01日 16:20:30
 * 邮箱:1693891473@qq.com
 * 说明:
 */
public  class GooglePay {

    private static final String TAG = "GooglePay";

    private BillingClient billingClient;

    private  static GooglePay instance=null;

    private GooglePay() {


    }

    public static GooglePay getInstance(){
        if(instance==null){
            synchronized (GooglePay.class){
                if(instance==null){
                    instance=new GooglePay();
                }
            }
        }
        return instance;
    }




    private PurchasesUpdatedListener purchasesUpdatedListener = new PurchasesUpdatedListener() {
        @Override
        public void onPurchasesUpdated(BillingResult billingResult, List<Purchase> purchases) {
            if (billingResult.getResponseCode() == BillingClient.BillingResponseCode.OK
                    && purchases != null) {
                for (Purchase purchase : purchases) {
                    handlePurchase(purchase);

                    Log.e(TAG, "getPurchaseToken: "+ purchase.getPurchaseToken() );
                    Log.e(TAG, "getSignature: "+ purchase.getSignature() );
                    Log.e(TAG, "getSignature: "+ purchase.getSignature() );
                }
            } else if (billingResult.getResponseCode() == BillingClient.BillingResponseCode.USER_CANCELED) {


            } else {
            }
        }
    };



    public void handlePurchase(final Purchase purchase) {
        ConsumeParams consumeParams =
                ConsumeParams.newBuilder()
                        .setPurchaseToken(purchase.getPurchaseToken())
                        .build();
        ConsumeResponseListener listener = new ConsumeResponseListener() {
            @Override
            public void onConsumeResponse(BillingResult billingResult, String purchaseToken) {
                if (billingResult.getResponseCode() == BillingClient.BillingResponseCode.OK) {

                    Log.e(TAG, "getPurchaseToken: "+ purchase.getPurchaseToken() );
                    Log.e(TAG, "getSignature: "+ purchase.getSignature() );
                    Log.e(TAG, "getSignature: "+ purchase.getSignature() );
                }
            }
        };
        if(billingClient!=null){
            billingClient.consumeAsync(consumeParams, listener);
        }
    }




    public  void initgooglePlay(Activity context) {
        billingClient = BillingClient.newBuilder(context)
                .setListener(purchasesUpdatedListener)
                .enablePendingPurchases()
                .build();
        if(billingClient!=null){
            billingClient.startConnection(new BillingClientStateListener() {
                @Override
                public void onBillingSetupFinished(BillingResult billingResult) {
                    if (billingResult.getResponseCode() ==  BillingClient.BillingResponseCode.OK) {

                    }
                }
                @Override
                public void onBillingServiceDisconnected() {

                }
            });
        }
    }

    public   void  toGooglePay(Activity context,String productId){
        //  String productId ="xxxx";
        List<QueryProductDetailsParams.Product> productList= new ArrayList<>();
        productList.add(QueryProductDetailsParams.Product.newBuilder()
                .setProductId(productId)
                .setProductType(BillingClient.ProductType.INAPP)
                .build());
        QueryProductDetailsParams queryProductDetailsParams = QueryProductDetailsParams.newBuilder().
                setProductList(productList)
                .build();
        if(billingClient!=null){
            billingClient.queryProductDetailsAsync(
                    queryProductDetailsParams,
                    new ProductDetailsResponseListener() {
                        public void onProductDetailsResponse(BillingResult billingResult,
                                                             List<ProductDetails> productDetailsList) {
                            if(productDetailsList!=null&&productDetailsList.size()>0){


                                ProductDetails productDetails=productDetailsList.get(0);
                                List<BillingFlowParams.ProductDetailsParams> productDetailsParamsList= new ArrayList<>();
                                productDetailsParamsList.add(BillingFlowParams.ProductDetailsParams.newBuilder()
                                        .setProductDetails(productDetails)
                                        .build());
                                BillingFlowParams billingFlowParams = BillingFlowParams.newBuilder()
                                        .setProductDetailsParamsList(productDetailsParamsList)
                                        .build();
                                billingClient.launchBillingFlow((Activity) context, billingFlowParams);
                            }else {
                                Toast.makeText(context,"商品ID无效",Toast.LENGTH_SHORT).show();
                            }
                        }
                    }
            );
        }
    }


    public   void  queryPurchasesAsync(Activity context){
        if(billingClient!=null){
            if(!billingClient.isReady()){
                Toast.makeText(context,"BillingClient is not ready",Toast.LENGTH_SHORT).show();
            }
            billingClient.queryPurchasesAsync(
                    QueryPurchasesParams.newBuilder().setProductType(BillingClient.ProductType.INAPP).build(),
                    new PurchasesResponseListener() {
                        public void onQueryPurchasesResponse(
                                BillingResult billingResult,
                                List<Purchase> purchases) {
                            if(billingResult.getResponseCode()==BillingClient.BillingResponseCode.OK){
                                if(purchases!=null&&purchases.size()>0){
                                    for (Purchase purchase:purchases){
                                        handlePurchase(purchase);
                                    }
                                }
                            }
                        }
                    }
            );
        }
    }

}

最后总结:

鸿蒙arkui-x才是刚起步希望有更多开发能加入进来一起共同建设完善好生态。也希望国产系统和框架越来越好 最后呢 希望我都文章能帮助到各位同学工作和学习 如果你觉得文章还不错麻烦给我三连 关注点赞和转发 谢谢

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2024-04-01,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 大前端之旅 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前言
  • 效果图 :
  • 实现方式
  • ArkUI端代码
    • 导入平台桥接模块
      • 创建平台桥接对象
      • 接收回传回来的数据
        • 完整代码
          • 官方文档地址
          • akrui-x 和原生安卓通信交互
      • 安卓部分
      • 需要的依赖
      • 内购支付初始化
      • 调用起内购支付
      • 请再 onResume 声明周期方法里面调用
      • 完整Android端代码
      • EntryEntryAbilityActivity 端代码
      • googlepay 工具类代码
      • 最后总结:
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档