鸿蒙征文|鸿蒙ArkUI-X和原生交互调用Google内购支付
前言 团队介绍 作者:徐庆 团队:坚果派 公众号:“大前端之旅” 润开鸿生态技术专家,华为HDE,CSDN博客专家,CSDN超级个体,CSDN特邀嘉宾,InfoQ签约作者,OpenHarmony布道师,电子发烧友专家博客,51CTO博客专家&am
前言
团队介绍
作者:徐庆
团队:坚果派 公众号:“大前端之旅” 润开鸿生态技术专家,华为HDE,CSDN博客专家,CSDN超级个体,CSDN特邀嘉宾,InfoQ签约作者,OpenHarmony布道师,电子发烧友专家博客,51CTO博客专家,擅长HarmonyOS/OpenHarmony应用开发、熟悉服务卡片开发。欢迎合作。
效果图 :
实现方式
我们是通过AkrUi-X和安卓交互 然后在原生安卓里面加入了内购支付结算库的依赖 最后调起的Google 支付 安卓原生内购支付教程
ArkUI端代码
akrui 端我这边只写了一个按钮调用Google内购支付和接收数据
导入平台桥接模块
// 导入平台桥接模块
import bridge from '@arkui-x.bridge';
创建平台桥接对象
// 创建平台桥接对象
private bridgeImpl = bridge.createBridge('Bridge');
// 发送数据到Android侧,并通过状态变量,将Android侧的响应数据显示在页面上
this.nativeResponse = await this.bridgeImpl.sendMessage('Hello ArkUI-X!');
接收回传回来的数据
aboutToAppear() {
this.getHelloArkUI();
}
getHelloArkUI() {
// 调用Android侧方法
this.bridgeImpl.callMethod('getHelloArkUI').then((result: string) => {
// 通过状态变量,将Android侧方法的返回值显示在页面上
this.helloArkUI = result;
});
完整代码
// 导入平台桥接模块
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编译之后产生的安卓原生宿主工程
官方文档地址
需要的依赖
def billing_version = "6.0.0" implementation "com.android.billingclient:billing:$billing_version"
akrui-x 和原生安卓通信交互
引用平台桥接模块
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) {
}
}
内购支付初始化
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();
}
}
}
);
}
}
我们在arkui-x调用安卓原生的回调方法里面去调用我们的 toGooglePay 传入我们的商品ID 即可
支付回调
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 信息之后可以去自己服务端进行验签 如果验签成功了才算是真正的成功支付成功 然后再进行消耗
商品消耗
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 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 声明周期方法里面调用
@Override
protected void onResume() {
super.onResume();
GooglePay.getInstance().queryPurchasesAsync(EntryEntryAbilityActivity.this);
}
完整Android端代码
EntryEntryAbilityActivity 端代码
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 工具类代码
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才是刚起步希望有更多开发能加入进来一起共同建设完善好生态。也希望国产系统和框架越来越好 最后呢 希望我都文章能帮助到各位同学工作和学习 如果你觉得文章还不错麻烦给我三连 关注点赞和转发 谢谢
更多推荐
所有评论(0)