如何使用kotlin在android中调用startActivityForResult中的方法?

问题描述 投票:0回答:1

我正在编写一个本机模块,以便使用 kotlin 在 React Native向谷歌钱包添加通用通行证。根据Android的谷歌钱包API文档(https://developers.google.com/wallet/generic/android),我必须实现一个onActivityResult函数才能在用户点击“添加到谷歌钱包”按钮后获取结果。

根据 React Native 文档了解如何监听

onActivityResult

 (
https://reactnative.dev/docs/0.71/native-modules-android?android-language=kotlin#getting-activity-result-from-startactivityforresult )我试图调用 walletClient.savePassesJwt(jwtSignedToken, this, addToGoogleWalletRequestCode)
 方法来获取 
onActivityResult
 函数的结果。我不知道在这件事上使用什么 Intent,并且我在我的 
React Native 项目的 JavaScript 方面收到以下错误。

{"info": "{ \"nativeStackAndroid\": [ { \"lineNumber\": 2174, \"file\": \"Instrumentation.java\", \"methodName\": \"checkStartActivityResult\", \"class\": \"android.app.Instrumentation\" }, { \"lineNumber\": 1805, \"file\": \"Instrumentation.java\", \"methodName\": \"execStartActivity\", \"class\": \"android.app.Instrumentation\" }, { \"lineNumber\": 5596, \"file\": \"Activity.java\", \"methodName\": \"startActivityForResult\", \"class\": \"android.app.Activity\" }, { \"lineNumber\": 597, \"file\": \"ComponentActivity.java\", \"methodName\": \"startActivityForResult\", \"class\": \"androidx.activity.ComponentActivity\" }, { \"lineNumber\": 5554, \"file\": \"Activity.java\", \"methodName\": \"startActivityForResult\", \"class\": \"android.app.Activity\" }, { \"lineNumber\": 583, \"file\": \"ComponentActivity.java\", \"methodName\": \"startActivityForResult\", \"class\": \"androidx.activity.ComponentActivity\" }, { \"lineNumber\": 112, \"file\": \"GoogleWalletModule.kt\", \"methodName\": \"savePassToGoogleWallet\", \"class\": \"com.peaktowertech.digivcard.GoogleWalletModule\" }, { \"lineNumber\": -2, \"file\": \"Method.java\", \"methodName\": \"invoke\", \"class\": \"java.lang.reflect.Method\" }, { \"lineNumber\": 372, \"file\": \"JavaMethodWrapper.java\", \"methodName\": \"invoke\", \"class\": \"com.facebook.react.bridge.JavaMethodWrapper\" }, { \"lineNumber\": 188, \"file\": \"JavaModuleWrapper.java\", \"methodName\": \"invoke\", \"class\": \"com.facebook.react.bridge.JavaModuleWrapper\" }, { \"lineNumber\": -2, \"file\": \"NativeRunnable.java\", \"methodName\": \"run\", \"class\": \"com.facebook.jni.NativeRunnable\" }, { \"lineNumber\": 942, \"file\": \"Handler.java\", \"methodName\": \"handleCallback\", \"class\": \"android.os.Handler\" }, { \"lineNumber\": 99, \"file\": \"Handler.java\", \"methodName\": \"dispatchMessage\", \"class\": \"android.os.Handler\" }, { \"lineNumber\": 27, \"file\": \"MessageQueueThreadHandler.java\", \"methodName\": \"dispatchMessage\", \"class\": \"com.facebook.react.bridge.queue.MessageQueueThreadHandler\" }, { \"lineNumber\": 226, \"file\": \"Looper.java\", \"methodName\": \"loopOnce\", \"class\": \"android.os.Looper\" }, { \"lineNumber\": 313, \"file\": \"Looper.java\", \"methodName\": \"loop\", \"class\": \"android.os.Looper\" }, { \"lineNumber\": 228, \"file\": \"MessageQueueThreadImpl.java\", \"methodName\": \"run\", \"class\": \"com.facebook.react.bridge.queue.MessageQueueThreadImpl$4\" }, { \"lineNumber\": 1012, \"file\": \"Thread.java\", \"methodName\": \"run\", \"class\": \"java.lang.Thread\" } ], \"userInfo\": null, \"message\": \"No Activity found to handle Intent { }\", \"code\": \"E_FAILED_TO_SHOW_WALLET_FLOW\" }", "message": "Add to google wallet failed"}
我的原生 kotlin 模块:👇

package com.example.something; import android.app.Activity import android.content.Intent import android.util.Log import com.facebook.react.bridge.BaseActivityEventListener import com.facebook.react.bridge.Callback import com.facebook.react.bridge.LifecycleEventListener import com.facebook.react.bridge.NativeModule import com.facebook.react.bridge.Promise import com.facebook.react.bridge.ReactApplicationContext import com.facebook.react.bridge.ReactContext import com.facebook.react.bridge.ReactContextBaseJavaModule import com.facebook.react.bridge.ReactMethod import com.google.android.gms.pay.Pay import com.google.android.gms.pay.PayClient import com.google.android.gms.pay.PayApiAvailabilityStatus class GoogleWalletModule(reactContext: ReactApplicationContext, private var walletClient: PayClient=Pay.getClient(reactContext)) : ReactContextBaseJavaModule(reactContext) { private val addToGoogleWalletRequestCode = 1000 private var saveToWalletPromise: Promise? = null private val activityEventListener = object : BaseActivityEventListener() { override fun onActivityResult( activity: Activity?, requestCode: Int, resultCode: Int, data: Intent? ) { if (requestCode == addToGoogleWalletRequestCode) { saveToWalletPromise?.let { promise -> when (resultCode) { Activity.RESULT_OK -> { // Pass saved successfully } Activity.RESULT_CANCELED -> { // Save operation canceled promise.reject(E_ADD_TO_WALLET_CANCELLED, "Add to wallet was cancelled") } PayClient.SavePassesResult.SAVE_ERROR -> data?.let { intentData -> val errorMessage = intentData.getStringExtra(PayClient.EXTRA_API_ERROR_MESSAGE) // Handle error promise.reject(E_FAILED_TO_SAVE_PASS,errorMessage) } else -> { // Handle unexpected (non-API) exception } } } } } } init { reactContext.addActivityEventListener(activityEventListener) } override fun getName() = "GoogleWalletModule" @ReactMethod fun isGoogleWalletApiAvailable(myFailureCallback: Callback, mySuccessCallback: Callback) { walletClient .getPayApiAvailabilityStatus(PayClient.RequestType.SAVE_PASSES) .addOnSuccessListener { status -> if (status == PayApiAvailabilityStatus.AVAILABLE) { // The API is available, show the button in your UI mySuccessCallback.invoke(true) } else { // The user or device is not eligible for using the Pay API mySuccessCallback.invoke(false) } } .addOnFailureListener { // Hide the button and optionally show an error message myFailureCallback.invoke("E_WRONG") } } @ReactMethod fun savePassToGoogleWallet(jwtSignedToken: String,promise: Promise) { val activity = currentActivity if (activity == null) { promise.reject(E_ACTIVITY_DOES_NOT_EXIST, "Activity doesn't exist") return } saveToWalletPromise = promise try { val igniterIntent = Intent().apply { () -> walletClient.savePassesJwt(jwtSignedToken, activity, addToGoogleWalletRequestCode) } activity.startActivityForResult(igniterIntent,addToGoogleWalletRequestCode) } catch (t: Throwable) { saveToWalletPromise?.reject(E_FAILED_TO_SHOW_ADD_TO_WALLET, t) saveToWalletPromise = null } } companion object { const val E_ACTIVITY_DOES_NOT_EXIST = "E_ACTIVITY_DOES_NOT_EXIST" const val E_ADD_TO_WALLET_CANCELLED = "E_PICKER_CANCELLED" const val E_FAILED_TO_SHOW_ADD_TO_WALLET = "E_FAILED_TO_SHOW_WALLET_FLOW" const val E_FAILED_TO_SAVE_PASS = "E_FAILED_TO_SAVE_PASS" } }
我对android开发不熟悉。谁能帮我解决这个问题吗?

android react-native android-pay react-native-native-module native-module
1个回答
0
投票
  • 先决条件

    • GoogleWalletModule
      已添加到React包中
    • React 包已添加到
    • MainApplication.kt
      (您的主类位于 
      android/src/main/java/com/example/something
       下)
  • 对于

    startActivityForResult

     在侦听器事件中给出结果。您需要将结果发回。

    • 使用您的函数

      savePassesJwt(..)

      通过调用以下函数来发送成功和失败案例的结果

      • 成功案例

        • activity.sendResult(Activity.RESULT_OK, addToGoogleWalletRequestCode)
          
          
      • 取消案例失败

        • activity.sendResult(Activity.RESULT_CANCELED, addToGoogleWalletRequestCode)
          
          
    • addToGoogleWalletRequestCode

       内传递 
      sendResult(..)
       将有助于映射正确的请求者。

进一步阅读:

https://developer.android.com/training/basics/intents/result

© www.soinside.com 2019 - 2024. All rights reserved.