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

RxJava2中Listener转Single及Play Services Auth短信监听代码迁移至SmsManager类

解决方案

没问题,我来帮你把这段代码封装到SmsManager类里,同时转换成RxJava2的Single类型。下面是具体的实现步骤和代码示例:

1. 创建封装的SmsManager类

我们会把短信监听的逻辑封装到独立的SmsManager类中,通过手动创建RxJava2 Single的方式,将Google Play Services的回调式Task转换成响应式流。这样既保证了代码的封装性,又能利用RxJava的优势简化线程调度和错误处理。

import android.content.Context
import com.google.android.gms.auth.api.phone.SmsRetriever
import com.google.android.gms.tasks.OnFailureListener
import com.google.android.gms.tasks.OnSuccessListener
import io.reactivex.Single
import io.reactivex.SingleEmitter
import io.reactivex.SingleOnSubscribe

class SmsManager(private val appContext: Context) {

    // 返回Single<Unit>,对应原Task的Void返回值
    fun startSmsRetriever(): Single<Unit> {
        return Single.create(SingleOnSubscribe<Unit> { emitter ->
            val smsRetrieverClient = SmsRetriever.getClient(appContext)
            val task = smsRetrieverClient.startSmsRetriever()

            // 处理Task成功回调
            task.addOnSuccessListener(OnSuccessListener<Void> {
                emitter.onSuccess(Unit)
            })

            // 处理Task失败回调
            task.addOnFailureListener(OnFailureListener { exception ->
                emitter.onError(exception)
            })
        })
    }
}

2. 使用RxJava Single处理结果

现在你可以在需要调用的地方,轻松使用这个方法,同时借助RxJava的线程调度器来控制执行线程和回调线程:

// 初始化SmsManager(注意传入ApplicationContext,避免内存泄漏)
val smsManager = SmsManager(applicationContext)

// 调用方法并订阅结果
smsManager.startSmsRetriever()
    .subscribeOn(io.reactivex.schedulers.Schedulers.io()) // 在IO线程执行请求
    .observeOn(io.reactivex.android.schedulers.AndroidSchedulers.mainThread()) // 在主线程处理回调
    .subscribe(
        {
            // 对应原代码的onSuccess逻辑,这里可以写你的业务操作
            // do something
        },
        { error ->
            // 对应原代码的onFailure逻辑,处理错误
            // Handle error
        }
    )

可选:使用官方RxJava适配库简化代码

如果你不想手动封装Task,可以使用Google官方提供的rxjava2-google-api-client库,它能直接将Google的Task转换为RxJava流。

首先在你的build.gradle(Module级别)中添加依赖:

implementation 'com.google.android.gms:play-services-auth-api-phone:18.0.1' // 请使用匹配你的Play Services版本
implementation 'com.google.rxjava:rxjava2-google-api-client:1.1.0'

然后SmsManager的方法可以简化为:

import android.content.Context
import com.google.android.gms.auth.api.phone.SmsRetriever
import com.google.android.gms.tasks.Tasks
import io.reactivex.Single

class SmsManager(private val appContext: Context) {

    fun startSmsRetriever(): Single<Unit> {
        val smsRetrieverClient = SmsRetriever.getClient(appContext)
        return Single.fromCallable {
            // 使用Tasks.await()阻塞当前线程获取结果,所以必须配合subscribeOn切换到非主线程
            Tasks.await(smsRetrieverClient.startSmsRetriever())
            Unit
        }
    }
}

重要注意事项

  • 记得在AndroidManifest.xml中添加必要的权限和广播接收器声明,否则SmsRetriever无法正常工作:
<uses-permission android:name="android.permission.RECEIVE_SMS" />
<uses-permission android:name="android.permission.READ_SMS" />

<receiver
    android:name=".your.package.SmsBroadcastReceiver" // 替换成你的广播接收器类
    android:exported="true">
    <intent-filter>
        <action android:name="com.google.android.gms.auth.api.phone.SMS_RETRIEVED" />
    </intent-filter>
</receiver>
  • 初始化SmsManager时一定要传入ApplicationContext,而不是Activity或Fragment的上下文,避免内存泄漏。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 08:42:34