You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android Kotlin集成Stripe Terminal时initTerminal运行时错误修复

解决Stripe Terminal初始化错误:java.lang.IllegalStateException: initTerminal must be called before attempting to get the instance

这个错误的核心原因是你在调用Terminal的任何功能方法前,未完成SDK的初始化流程。Stripe Terminal SDK强制要求:必须先调用initTerminal()完成初始化,才能通过Terminal.getInstance()获取实例并调用如discoverReaders()这类方法。

修复步骤

  1. 优先完成Terminal初始化,建议在Activity的onCreate()中、调用onDiscoverReaders()之前执行初始化逻辑。
  2. 初始化需传入包含Stripe可发布密钥、设备位置ID等参数的TerminalConfiguration。
  3. 仅在初始化成功的回调中,再调用onDiscoverReaders()方法。

完整修复代码示例

import com.stripe.stripeterminal.Terminal
import com.stripe.stripeterminal.external.models.TerminalConfiguration
import com.stripe.stripeterminal.external.models.ConnectionTokenProvider
import com.stripe.stripeterminal.external.callbacks.InitCallback
import com.stripe.stripeterminal.external.callbacks.Callback
import com.stripe.stripeterminal.external.models.DiscoveryConfiguration
import com.stripe.stripeterminal.external.models.DiscoveryMethod
import com.stripe.stripeterminal.external.models.Reader
import com.stripe.stripeterminal.external.callbacks.DiscoveryListener
import com.stripe.stripeterminal.external.models.Cancelable

class PayScreenActivity : AppCompatActivity() {
    private var discoveryCancelable: Cancelable? = null

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_pay_screen)
        
        // 先执行Terminal初始化
        initStripeTerminal()
    }

    private fun initStripeTerminal() {
        val terminalConfig = TerminalConfiguration.Builder()
            .setPublishableKey("你的Stripe可发布密钥")
            .setLocationId("xxxxxxxxxxxxxxx") // 你原代码中使用的location ID
            .build()

        Terminal.initTerminal(
            applicationContext,
            terminalConfig,
            object : ConnectionTokenProvider {
                override fun fetchConnectionToken(callback: ConnectionTokenCallback) {
                    // 此处需调用你的后端接口获取Stripe Connection Token
                    // 示例伪代码:
                    // apiService.getStripeConnectionToken()
                    //     .enqueue(object : Callback<ConnectionTokenResp> {
                    //         override fun onResponse(call: Call<ConnectionTokenResp>, resp: Response<ConnectionTokenResp>) {
                    //             resp.body()?.token?.let { callback.onSuccess(it) } 
                    //                 ?: callback.onFailure(Exception("获取Token失败"))
                    //         }
                    //         override fun onFailure(call: Call<ConnectionTokenResp>, t: Throwable) {
                    //             callback.onFailure(t)
                    //         }
                    //     })
                }
            },
            object : InitCallback {
                override fun onSuccess() {
                    // 初始化成功后再启动设备发现
                    onDiscoverReaders()
                }

                override fun onFailure(e: TerminalException) {
                    e.printStackTrace()
                    // 处理初始化失败逻辑
                }
            }
        )
    }

    fun onDiscoverReaders() {
        val config = DiscoveryConfiguration(
            timeout = 0,
            discoveryMethod = DiscoveryMethod.LOCAL_MOBILE,
            isSimulated = false,
            location = "xxxxxxxxxxxxxxx"
        )
        discoveryCancelable = Terminal.getInstance().discoverReaders(config,
            discoveryListener = object : DiscoveryListener {
                override fun onUpdateDiscoveredReaders(readers: List<Reader>) {
                    // 处理发现的设备列表
                }
            },
            object : Callback {
                override fun onSuccess() {
                    println("Finished discovering readers")
                }

                override fun onFailure(e: TerminalException) {
                    e.printStackTrace()
                }
            }
        )
    }

    override fun onDestroy() {
        super.onDestroy()
        // 取消发现任务,避免内存泄漏
        discoveryCancelable?.cancel()
    }
}

关键注意事项

  • Connection Token获取:必须通过后端服务获取,不能在客户端直接生成或硬编码,这是Stripe的安全要求。
  • 初始化时机:若多个页面需使用Terminal,建议在Application类的onCreate()中完成全局初始化,避免重复操作。
  • 权限配置:确保应用已添加Terminal所需权限(如蓝牙、位置权限等,根据使用的发现方法调整)。

内容的提问来源于stack exchange,提问作者Ajith

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.14 14:20:27