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

Flutter与Kotlin实现前后台及终止状态自动发送SMS问题排查

后台无法发送短信的问题

我通过Telephony实现了短信的接收与发送功能,前台状态下运行正常,但后台状态下发送短信会出错,不过后台能正常接收短信。

现有权限配置

<uses-permission android:name="android.permission.SEND_SMS"/>
<uses-permission android:name="android.permission.RECEIVE_SMS"/>

发送短信的Method Channel实现

import android.telephony.SmsManager

val CHANNEL = "example.sms"

override fun configureFlutterEngine(@NonNull flutterEngine: FlutterEngine) {
    super.configureFlutterEngine(flutterEngine)
    MethodChannel(flutterEngine.dartExecutor.binaryMessenger, CHANNEL).setMethodCallHandler {
        call, result ->
        if(call.method == "sendsms") {
            val phone = call.argument<String>("phone")
            val msg = call.argument<String>("msg")
            if (phone != null && msg != null) {
                sendSms(phone, msg)
            }
        } else {
            result.notImplemented()
        }
    }
}

private fun sendSms(phoneNumber: String, message: String) {
    try {
        val smsManager = SmsManager.getDefault()
        smsManager.sendTextMessage(phoneNumber, null, message, null, null)
    } catch (e: Exception) {
        e.printStackTrace()
    }
}

问题原因及解决办法

1. 适配Android 12+权限要求

从Android 12(API 31)开始,后台发送短信需要额外申请REQUEST_SEND_SMS权限,仅SEND_SMS无法满足后台操作需求。需在AndroidManifest.xml中添加:

<uses-permission android:name="android.permission.REQUEST_SEND_SMS" />

同时要在代码中动态申请该权限,因为它属于危险权限范畴。

2. 规避后台任务限制

Android的后台调度限制会阻止非前台应用直接执行短信发送操作,建议使用WorkManager来处理后台短信发送任务,确保操作能被系统正常调度:

  • 添加WorkManager依赖到build.gradle:
implementation "androidx.work:work-runtime:2.8.1"
  • 创建短信发送Worker类:
class SmsSendWorker(context: Context, params: WorkerParameters) : Worker(context, params) {
    override fun doWork(): Result {
        val phone = inputData.getString("phone")
        val msg = inputData.getString("msg")
        return try {
            val smsManager = SmsManager.getDefault()
            smsManager.sendTextMessage(phone, null, msg, null, null)
            Result.success()
        } catch (e: Exception) {
            e.printStackTrace()
            Result.failure()
        }
    }
}
  • 修改Method Channel中的调用逻辑,替换直接发送为调度Worker:
private fun scheduleSmsSend(phoneNumber: String, message: String) {
    val data = Data.Builder()
        .putString("phone", phoneNumber)
        .putString("msg", message)
        .build()
    
    val constraints = Constraints.Builder()
        .setRequiredNetworkType(NetworkType.CONNECTED) // 可选,根据需求配置网络要求
        .build()
    
    val smsWorkRequest = OneTimeWorkRequestBuilder<SmsSendWorker>()
        .setInputData(data)
        .setConstraints(constraints)
        .build()
    
    WorkManager.getInstance(applicationContext).enqueue(smsWorkRequest)
}

之后在Method Channel回调里调用scheduleSmsSend(phone, msg)代替原sendSms方法。

3. 优化异常反馈机制

原代码仅在本地打印异常,无法将错误信息传递给Flutter端,建议修改Method Channel的回调逻辑,把异常信息返回:

if (phone != null && msg != null) {
    try {
        scheduleSmsSend(phone, msg)
        result.success("短信发送任务已调度")
    } catch (e: Exception) {
        result.error("SEND_FAILED", e.message, null)
    }
} else {
    result.error("INVALID_PARAMS", "手机号或短信内容为空", null)
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 08:25:22