ArkUI-X 调起华为支付

1,453 阅读8分钟

前言:

各位同学大家好 很久没有跟大家见面了 具体多久我也不清楚,最近研究一下arkui-x调起华为支付功能 所以就分享给大家

作者:徐庆

团队:坚果派 公众号:“大前端之旅” 润开鸿生态技术专家,华为HDE,CSDN博客专家,CSDN超级个体,CSDN特邀嘉宾,InfoQ签约作者,OpenHarmony布道师,电子发烧友专家博客,51CTO博客专家,擅长HarmonyOS/OpenHarmony应用开发、熟悉服务卡片开发。欢迎合作。

效果图:

  • akrui-x 效果

82da7166e69bc137b4df57a92804a9d.jpg

  • 在安卓上面的效果

b139d071324fc49fb3461f8607843aa.jpg

  • 调起华为支付

f51eeebc8aa19f3808f83c10a5681e4.jpg 我们是通过AkrUi-X和安卓交互 最后就接了华为支付的Android 版本最后调起了支付

具体实现

  • ArkUI端代码实现

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

82da7166e69bc137b4df57a92804a9d.jpg

  • 导入平台桥接模块

// 导入平台桥接模块
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() {

  }

  build() {
    Row() {
      Column() {
        Text(this.helloArkUI)
          .fontSize(15)
          .margin(10)
        Button('点击华为支付')
          .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.png

官方文档地址

华为内购支付

要的依赖

//华为支付
implementation 'com.huawei.hms:iap:6.13.0.300'

image.png

plugins {
    id 'com.android.application'
    id 'com.huawei.agconnect'
}

image.png

添加 json文件

image.png 在外层的 build.gradle 里面添加如下配置

// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
    repositories {
        google()
        jcenter()
        maven {url 'https://developer.huawei.com/repo/'}
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:7.3.1'
        classpath 'com.huawei.agconnect:agcp:1.6.0.300'
        // NOTE: Do not place your application dependencies here; they belong
        // in the individual module build.gradle files
    }
}

allprojects {
    repositories {
        google()
        jcenter()
        maven {url 'https://developer.huawei.com/repo/'}
    }
}

task clean(type: Delete) {
    delete rootProject.buildDir
}

image.png

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 com.example.helloworld.huaweipay.OjjlgHuaweiPay;

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();
        //这里的 xxxxxx换城你们自己的商品id
     //   GooglePay.getInstance().toGooglePay((Activity) context,"xxxxxx");
        OjjlgHuaweiPay.getInstance().fucnxPayInApp((Activity) context,"1","testpay");
        Log.e(TAG, "onMessage: "+object.toString() );
        return "java onMessage success";
    }

    @Override
    public void onMessageResponse(Object object) {


    }
}

内购支付初始化

/**
 * @param context 链接华为服务器
 */
public void queryIsReady(Activity context) {
    this.context = context;
    mClient = Iap.getIapClient(context);
    IapRequestHelper.isEnvReady(mClient, new IapApiCallback<IsEnvReadyResult>() {
        @Override
        public void onSuccess(IsEnvReadyResult result) {
            Log.e(TAG, "onSuccess: " + "检查支付成功  --- >  ");
            //initview();
        }

        @Override
        public void onFail(Exception e) {
            Log.e(TAG, "isEnvReady fail, " + e.getMessage());
            ExceptionHandle.handle(context, e);
        }
    });
}

查询商品ID

    /**
     * @param productId
     * @param mContext  查询商品ID
     */

    public void queryProducts( Activity mContext,final String productId,String token) {
        Log.e(TAG, "queryProducts: productId -- >"+productId );
        if(mClient!=null){
            List<String> productIds = new ArrayList<String>();
            productIds.add(productId);
            IapRequestHelper.obtainProductInfo(mClient, productIds, IapClient.PriceType.IN_APP_CONSUMABLE,
                    new IapApiCallback<ProductInfoResult>() {
                        @Override
                        public void onSuccess(ProductInfoResult result) {
                            Log.i(TAG, "obtainProductInfo, success");
                            if (result == null) {
                                return;
                            }

                            Log.e(TAG, "onSuccess:result.getReturnCode() -- >   "+result.getReturnCode() );
//                            if(result.getReturnCode()==0){
                                if (result.getProductInfoList() != null&&result.getProductInfoList().size()>0) {
                                    List<ProductInfo> productInfoList=result.getProductInfoList();
                                    for(ProductInfo productInfo:productInfoList){
                                        String product_id=productInfo.getProductId(); //商品id
                                        String product_name=productInfo.getProductName();// 商品名称
                                        String product_price=productInfo.getPrice();// 商品金额
                                        String currency_code=productInfo.getCurrency();// 币种

                                        buy((Activity) mContext,productId,token);
                                    }
                                }else {
                                    Log.e(TAG, "onSuccess: " + result.getErrMsg() + result.getReturnCode());
                                    Log.e(TAG, "onSuccess: " + "商品列表为空");
                                    Toast.makeText(mContext, "商品列表为空", Toast.LENGTH_SHORT);
                                }
                        }
                        @Override
                        public void onFail(Exception e) {
                            Log.e(TAG, "obtainProductInfo: " + e.getMessage());
                        }
                    });
                 }
         }

调起支付



/***
 *
 * @param productId
 * @param
 *
 *
 *
 */
public void buy(final Activity activity, String productId, String  token) {
    IapRequestHelper.createPurchaseIntent(mClient, productId, IapClient.PriceType.IN_APP_CONSUMABLE,token,
            new IapApiCallback<PurchaseIntentResult>() {
                @Override
                public void onSuccess(PurchaseIntentResult result) {
                    if (result == null) {
                        Log.e(TAG, "result is null");
                        return;
                    }
                    IapRequestHelper.startResolutionForResult(activity, result.getStatus(), REQ_CODE_BUY);
                }
                @Override
                public void onFail(Exception e) {
                    int errorCode = ExceptionHandle.handle(activity, e);
                    if (errorCode != ExceptionHandle.SOLVED) {
                        Log.i(TAG, "createPurchaseIntent, returnCode: " + errorCode);
                        // Handle error scenarios.
                        switch (errorCode) {
                            case OrderStatusCode.ORDER_PRODUCT_OWNED:
                                // queryPurchases(null);
                                break;
                            default:
                                break;
                        }
                    }
                }
            });

}

支付回调

/**
 *
 *
 * @param requestCode
 * @param resultCode
 * @param data
 * 华为内购支付回调
 */
public void onActivityResult(int requestCode, int resultCode, Intent data) {
    Log.e(TAG, "onActivityResult");
    if (requestCode == REQ_CODE_BUY) {
        if (data == null) {
            Log.e(TAG, "data is null");
            return;
        }
        PurchaseResultInfo purchaseResultInfo = Iap.getIapClient(context).parsePurchaseResultInfoFromIntent(data);
        switch(purchaseResultInfo.getReturnCode()) {
            case OrderStatusCode.ORDER_STATE_CANCEL:
                Log.e(TAG, "onActivityResult:ORDER_STATE_CANCEL  " );
                Toast.makeText(context, " ORDER_STATE_CANCEL  Order has been canceled!", Toast.LENGTH_SHORT).show();
                break;
            case OrderStatusCode.ORDER_STATE_FAILED:

                Log.e(TAG, "onActivityResult: ORDER_STATE_FAILED ");

            case OrderStatusCode.ORDER_PRODUCT_OWNED:
                Log.e(TAG, "onActivityResult: ORDER_PRODUCT_OWNED ");
                  queryPurchases(null);
                break;
            case OrderStatusCode.ORDER_STATE_SUCCESS:
                Log.e(TAG, "onActivityResult: ORDER_STATE_SUCCESS ");
                //先去服务器验签 然后再消耗
                deliverProduct(purchaseResultInfo.getInAppPurchaseData());
                break;
            default:
                break;
        }
        return;
    }
}

消耗



/**
 * Deliver the product.
 *
 * @param inAppPurchaseDataStr Includes the purchase details.
 * @param
 */
public void deliverProduct(final String inAppPurchaseDataStr) {
// final String inAppPurchaseDataSignature
    try {
        InAppPurchaseData inAppPurchaseDataBean = new InAppPurchaseData(inAppPurchaseDataStr);
        if (inAppPurchaseDataBean.getPurchaseState() != InAppPurchaseData.PurchaseState.PURCHASED) {
            return;
        }
        String purchaseToken = inAppPurchaseDataBean.getPurchaseToken();
        String productId = inAppPurchaseDataBean.getProductId();
        IapRequestHelper.consumeOwnedPurchase(mClient, purchaseToken);

    } catch (JSONException e) {
        Log.e(TAG, "delivery:" + e.getMessage());
    }

}

具体消耗逻辑

/**
 * Consume all the unconsumed purchases with priceType 0.
 * @param iapClient IapClient instance to call the consumeOwnedPurchase API.
 * @param purchaseToken which is generated by the Huawei payment server during product payment and returned to the app through InAppPurchaseData.
 */
public static void consumeOwnedPurchase(IapClient iapClient, String purchaseToken) {
    Log.i(TAG, "call consumeOwnedPurchase");
    Task<ConsumeOwnedPurchaseResult> task = iapClient.consumeOwnedPurchase(createConsumeOwnedPurchaseReq(purchaseToken));
    task.addOnSuccessListener(new OnSuccessListener<ConsumeOwnedPurchaseResult>() {
        @Override
        public void onSuccess(ConsumeOwnedPurchaseResult result) {

            Log.i(TAG, "consumeOwnedPurchase success");
        }
    }).addOnFailureListener(new OnFailureListener() {
        @Override
        public void onFailure(Exception e) {
            if (e instanceof IapApiException) {
                IapApiException apiException = (IapApiException)e;
                int returnCode = apiException.getStatusCode();
                Log.e(TAG, "consumeOwnedPurchase fail, IapApiException returnCode: " + returnCode);
            } else {
                // Other external errors
                Log.e(TAG, e.getMessage());
            }

        }
    });

}

查询未消耗逻辑(补单逻辑)

/**
 * Call the obtainOwnedPurchases API to obtain the data about consumable
 * products that the user has purchased but has not been delivered.
 * 查询未消耗的逻辑
 *
 *
 *
 */
public void queryPurchases(String continuationToken) {
    final String tag = "obtainOwnedPurchases";
    IapRequestHelper.obtainOwnedPurchases(mClient, IapClient.PriceType.IN_APP_CONSUMABLE,
            continuationToken, new IapApiCallback<OwnedPurchasesResult>() {
        @Override
        public void onSuccess(OwnedPurchasesResult result) {
            if (result == null) {
                Log.e(TAG, tag + " result is null");
                return;
            }
            Log.i(TAG, "obtainOwnedPurchases, success");
            if (result.getInAppPurchaseDataList() != null) {
                List<String> inAppPurchaseDataList = result.getInAppPurchaseDataList();
                List<String> inAppSignature= result.getInAppSignature();
                for (int i = 0; i < inAppPurchaseDataList.size(); i++) {
                    final String inAppPurchaseData = inAppPurchaseDataList.get(i);
                    final String inAppPurchaseDataSignature = inAppSignature.get(i);
                    deliverProduct(inAppPurchaseData);
                }
            }
            if (!TextUtils.isEmpty(result.getContinuationToken())) {
                queryPurchases(result.getContinuationToken());
            }
        }
        @Override
        public void onFail(Exception e) {
            Log.e(TAG, "obtainOwnedPurchases, type=" + IapClient.PriceType.IN_APP_CONSUMABLE + ", " + e.getMessage());
            ExceptionHandle.handle(context, e);
        }
    });
}

完整Android端代码

package com.example.helloworld;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import com.example.helloworld.huaweipay.OjjlgHuaWeiBilling;
import com.example.helloworld.huaweipay.OjjlgHuaweiPay;


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;

    @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);
        OjjlgHuaweiPay.getInstance().initHuaweiPay((Activity) context);
        // 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();
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent intent) {
        super.onActivityResult(requestCode, resultCode, intent);
        OjjlgHuaWeiBilling.getInstance().onActivityResult(requestCode,resultCode,intent);
    }
}

OjjlgHuaweiPay 代码

package com.example.helloworld.huaweipay;

import android.app.Activity;

/**
 * 作者:xuqing
 * 时间:2024年4月16日13:50:31
 * 邮箱:1693891473@qq.com
 * 说明:华为支付
 */
public  class OjjlgHuaweiPay    {

    private static OjjlgHuaweiPay instance=null;

    private OjjlgHuaweiPay() {
    }

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

    }
    

    public  void  initHuaweiPay(Activity  context){
        OjjlgHuaWeiBilling.getInstance().queryIsReady(context);

    }
    public void fucnxPayInApp(Activity activity, String productId,String token ){
        if(productId == null){
          //  NbzgmLog.qecrnVUnControl("clwuyPayInApp payParmas null");
            return;
        }
        if(!OjjlgHuaWeiBilling.getInstance().isReady()|| activity ==null) {
          //  NbzgmLog.qecrnVUnControl("clwuybuyInApp googleBillingUtil || mActivity  null");
            initHuaweiPay(activity);
            return;
        }
        OjjlgHuaWeiBilling.getInstance().queryProducts(activity,productId,token);
    }

}

package com.example.helloworld.huaweipay;
import static com.example.helloworld.huaweipay.Constants.REQ_CODE_BUY;
import android.app.Activity;
import android.content.Intent;
import android.text.TextUtils;
import android.util.Log;
import android.widget.Toast;
import com.huawei.hms.iap.Iap;
import com.huawei.hms.iap.IapClient;
import com.huawei.hms.iap.entity.InAppPurchaseData;
import com.huawei.hms.iap.entity.IsEnvReadyResult;
import com.huawei.hms.iap.entity.OrderStatusCode;
import com.huawei.hms.iap.entity.OwnedPurchasesResult;
import com.huawei.hms.iap.entity.ProductInfo;
import com.huawei.hms.iap.entity.ProductInfoResult;
import com.huawei.hms.iap.entity.PurchaseIntentResult;
import com.huawei.hms.iap.entity.PurchaseResultInfo;
import org.json.JSONException;
import java.util.ArrayList;
import java.util.List;


/**
 * 作者:xuqing
 * 时间:2024年3月5日17:36:50
 * 邮箱:1693891473@qq.com
 * 说明:华为支付
 *
 *
 */
public  class OjjlgHuaWeiBilling {
    private static final String TAG = "OjjlgHuaWeiBilling";
    private IapClient mClient;
    private Activity context;
    public int retryTimes = 0;
    private static OjjlgHuaWeiBilling instance=null;
    private OjjlgHuaWeiBilling() {
    }

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

    /**
     * @param context 链接华为服务器
     */
    public void queryIsReady(Activity context) {
        this.context = context;
        mClient = Iap.getIapClient(context);
        IapRequestHelper.isEnvReady(mClient, new IapApiCallback<IsEnvReadyResult>() {
            @Override
            public void onSuccess(IsEnvReadyResult result) {
                Log.e(TAG, "onSuccess: " + "检查支付成功  --- >  ");
                //initview();
            }

            @Override
            public void onFail(Exception e) {
                Log.e(TAG, "isEnvReady fail, " + e.getMessage());
                ExceptionHandle.handle(context, e);
            }
        });
    }
    /**
     * google内购服务是否已经准备好
     *
     * @return boolean
     */
    public  boolean isReady() {
        return mClient != null;
    }

    /**
     * @param productId
     * @param mContext  查询商品ID
     */

    public void queryProducts( Activity mContext,final String productId,String token) {
        Log.e(TAG, "queryProducts: productId -- >"+productId );
        if(mClient!=null){
            List<String> productIds = new ArrayList<String>();
            productIds.add(productId);
            IapRequestHelper.obtainProductInfo(mClient, productIds, IapClient.PriceType.IN_APP_CONSUMABLE,
                    new IapApiCallback<ProductInfoResult>() {
                        @Override
                        public void onSuccess(ProductInfoResult result) {
                            Log.i(TAG, "obtainProductInfo, success");
                            if (result == null) {
                                return;
                            }

                            Log.e(TAG, "onSuccess:result.getReturnCode() -- >   "+result.getReturnCode() );
//                            if(result.getReturnCode()==0){
                                if (result.getProductInfoList() != null&&result.getProductInfoList().size()>0) {
                                    List<ProductInfo> productInfoList=result.getProductInfoList();
                                    for(ProductInfo productInfo:productInfoList){
                                        String product_id=productInfo.getProductId(); //商品id
                                        String product_name=productInfo.getProductName();// 商品名称
                                        String product_price=productInfo.getPrice();// 商品金额
                                        String currency_code=productInfo.getCurrency();// 币种

                                        buy((Activity) mContext,productId,token);
                                    }
                                }else {
                                    Log.e(TAG, "onSuccess: " + result.getErrMsg() + result.getReturnCode());
                                    Log.e(TAG, "onSuccess: " + "商品列表为空");
                                    Toast.makeText(mContext, "商品列表为空", Toast.LENGTH_SHORT);
                                }
                        }
                        @Override
                        public void onFail(Exception e) {
                            Log.e(TAG, "obtainProductInfo: " + e.getMessage());
                        }
                    });
                 }
         }





    /***
     *
     * @param productId
     * @param
     *
     *
     *
     */
    public void buy(final Activity activity, String productId, String  token) {
        IapRequestHelper.createPurchaseIntent(mClient, productId, IapClient.PriceType.IN_APP_CONSUMABLE,token,
                new IapApiCallback<PurchaseIntentResult>() {
                    @Override
                    public void onSuccess(PurchaseIntentResult result) {
                        if (result == null) {
                            Log.e(TAG, "result is null");
                            return;
                        }
                        IapRequestHelper.startResolutionForResult(activity, result.getStatus(), REQ_CODE_BUY);
                    }
                    @Override
                    public void onFail(Exception e) {
                        int errorCode = ExceptionHandle.handle(activity, e);
                        if (errorCode != ExceptionHandle.SOLVED) {
                            Log.i(TAG, "createPurchaseIntent, returnCode: " + errorCode);
                            // Handle error scenarios.
                            switch (errorCode) {
                                case OrderStatusCode.ORDER_PRODUCT_OWNED:
                                    // queryPurchases(null);
                                    break;
                                default:
                                    break;
                            }
                        }
                    }
                });

    }




    /**
     *
     *
     * @param requestCode
     * @param resultCode
     * @param data
     * 华为内购支付回调
     */
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        Log.e(TAG, "onActivityResult");
        if (requestCode == REQ_CODE_BUY) {
            if (data == null) {
                Log.e(TAG, "data is null");
                return;
            }
            PurchaseResultInfo purchaseResultInfo = Iap.getIapClient(context).parsePurchaseResultInfoFromIntent(data);
            switch(purchaseResultInfo.getReturnCode()) {
                case OrderStatusCode.ORDER_STATE_CANCEL:
                    Log.e(TAG, "onActivityResult:ORDER_STATE_CANCEL  " );
                    Toast.makeText(context, " ORDER_STATE_CANCEL  Order has been canceled!", Toast.LENGTH_SHORT).show();
                    break;
                case OrderStatusCode.ORDER_STATE_FAILED:

                    Log.e(TAG, "onActivityResult: ORDER_STATE_FAILED ");

                case OrderStatusCode.ORDER_PRODUCT_OWNED:
                    Log.e(TAG, "onActivityResult: ORDER_PRODUCT_OWNED ");
                      queryPurchases(null);
                    break;
                case OrderStatusCode.ORDER_STATE_SUCCESS:
                    Log.e(TAG, "onActivityResult: ORDER_STATE_SUCCESS ");
                    //先去服务器验签 然后再消耗
                    deliverProduct(purchaseResultInfo.getInAppPurchaseData());
                    break;
                default:
                    break;
            }
            return;
        }
    }



    /**
     * Deliver the product.
     *
     * @param inAppPurchaseDataStr Includes the purchase details.
     * @param
     */
    public void deliverProduct(final String inAppPurchaseDataStr) {
    // final String inAppPurchaseDataSignature
        try {
            InAppPurchaseData inAppPurchaseDataBean = new InAppPurchaseData(inAppPurchaseDataStr);
            if (inAppPurchaseDataBean.getPurchaseState() != InAppPurchaseData.PurchaseState.PURCHASED) {
                return;
            }
            String purchaseToken = inAppPurchaseDataBean.getPurchaseToken();
            String productId = inAppPurchaseDataBean.getProductId();
            IapRequestHelper.consumeOwnedPurchase(mClient, purchaseToken);

        } catch (JSONException e) {
            Log.e(TAG, "delivery:" + e.getMessage());
        }

    }



    /**
     * Call the obtainOwnedPurchases API to obtain the data about consumable
     * products that the user has purchased but has not been delivered.
     * 查询未消耗的逻辑
     *
     *
     *
     */
    public void queryPurchases(String continuationToken) {
        final String tag = "obtainOwnedPurchases";
        IapRequestHelper.obtainOwnedPurchases(mClient, IapClient.PriceType.IN_APP_CONSUMABLE,
                continuationToken, new IapApiCallback<OwnedPurchasesResult>() {
            @Override
            public void onSuccess(OwnedPurchasesResult result) {
                if (result == null) {
                    Log.e(TAG, tag + " result is null");
                    return;
                }
                Log.i(TAG, "obtainOwnedPurchases, success");
                if (result.getInAppPurchaseDataList() != null) {
                    List<String> inAppPurchaseDataList = result.getInAppPurchaseDataList();
                    List<String> inAppSignature= result.getInAppSignature();
                    for (int i = 0; i < inAppPurchaseDataList.size(); i++) {
                        final String inAppPurchaseData = inAppPurchaseDataList.get(i);
                        final String inAppPurchaseDataSignature = inAppSignature.get(i);
                        deliverProduct(inAppPurchaseData);
                    }
                }
                if (!TextUtils.isEmpty(result.getContinuationToken())) {
                    queryPurchases(result.getContinuationToken());
                }
            }
            @Override
            public void onFail(Exception e) {
                Log.e(TAG, "obtainOwnedPurchases, type=" + IapClient.PriceType.IN_APP_CONSUMABLE + ", " + e.getMessage());
                ExceptionHandle.handle(context, e);
            }
        });
    }

}

最后总结

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