我正在编写一个本机模块,以便使用 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开发不熟悉。谁能帮我解决这个问题吗?
GoogleWalletModule
已添加到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