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

Flutter多会话USSD请求开发遇RangeError问题求助

问题解决方案

一、解决RangeError错误

报错的直接原因是你调用UssdAdvanced.multisessionUssd时传入的subscriptionId: 1无效。大多数单SIM卡设备的subscriptionId为0,插件内部处理该参数时尝试访问索引1的数组元素,但数组仅包含索引0的元素,导致越界。

修复方法:

  1. 单SIM设备直接传0:
String? _res = await UssdAdvanced.multisessionUssd(
    code: _requestCode, subscriptionId: 0); // 将1改为0
  1. 多SIM设备动态获取ID:
    如果需要支持多SIM卡,可先获取设备SIM卡列表,再选择对应ID:
List<SimCard> simCards = await UssdAdvanced.getSimCards();
if (simCards.isNotEmpty) {
  String? _res = await UssdAdvanced.multisessionUssd(
      code: _requestCode, subscriptionId: simCards[0].subscriptionId);
}

二、多会话USSD的正确实现逻辑

当前代码硬编码发送'0',仅适用于固定流程,无法处理动态USSD菜单。正确的多会话处理需要根据每一步的USSD响应动态交互:

核心步骤:

  1. 发起多会话请求,获取初始响应
  2. 将响应展示给用户,提供输入框让用户选择下一步指令
  3. 发送用户输入的指令,获取新响应
  4. 重复交互直到用户结束会话或流程终止
  5. 展示最终结果

修改后的代码示例:

// 在_MultiUssdState中添加变量
bool _inSession = false;
String _currentUssdResponse = "";
final TextEditingController _inputController = TextEditingController();

// 修改按钮点击逻辑
onPressed: _requestState == RequestState.ongoing || _inSession
    ? null
    : () async {
        setState(() {
          _requestState = RequestState.ongoing;
        });
        try {
          await Permission.phone.request();
          if (!await Permission.phone.isGranted) {
            throw Exception("permission missing");
          }
          // 发起多会话请求
          String initialResponse = await UssdAdvanced.multisessionUssd(
              code: _requestCode, subscriptionId: 0);
          setState(() {
            _requestState = RequestState.success;
            _currentUssdResponse = initialResponse;
            _inSession = true;
          });

          // 会话交互循环
          while (_inSession) {
            String? userInput = await showDialog<String>(
              context: context,
              builder: (context) => AlertDialog(
                title: const Text("USSD菜单"),
                content: Column(
                  mainAxisSize: MainAxisSize.min,
                  children: [
                    Text(_currentUssdResponse),
                    const SizedBox(height: 16),
                    TextField(
                      controller: _inputController,
                      decoration: const InputDecoration(hintText: "输入选项(如1、2)"),
                      keyboardType: TextInputType.number,
                    ),
                  ],
                ),
                actions: [
                  TextButton(
                    onPressed: () => Navigator.pop(context, null),
                    child: const Text("结束会话"),
                  ),
                  TextButton(
                    onPressed: () {
                      Navigator.pop(context, _inputController.text.trim());
                      _inputController.clear();
                    },
                    child: const Text("发送"),
                  ),
                ],
              ),
            );

            if (userInput == null) {
              await UssdAdvanced.cancelSession();
              setState(() {
                _inSession = false;
                _responseMessage = "会话已结束";
              });
              break;
            }

            String newResponse = await UssdAdvanced.sendMessage(userInput);
            setState(() {
              _currentUssdResponse = newResponse;
            });

            // 根据运营商返回判断是否结束会话(需自定义关键词)
            if (newResponse.contains("成功") || newResponse.contains("完成")) {
              await UssdAdvanced.cancelSession();
              setState(() {
                _inSession = false;
                _responseMessage = newResponse;
              });
              break;
            }
          }
        } on PlatformException catch (e) {
          setState(() {
            _requestState = RequestState.error;
            _responseCode = e.code;
            _responseMessage = e.message ?? '';
            _inSession = false;
          });
        }
      },

三、额外注意事项

  • 权限配置:在AndroidManifest.xml中添加READ_PHONE_STATE和CALL_PHONE权限,USSD操作依赖这些权限。
  • 运营商适配:不同运营商的USSD返回格式存在差异,需根据实际返回内容调整菜单解析逻辑。
  • 超时处理:添加会话超时机制,避免无响应导致应用卡顿。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 16:07:33