Flutter iOS:包含 * 和# 的USSD码无法在拨号界面启动(在Android上可用)

移动开发 2026-07-10

你好


Flutter iOS:USSD代码中含有 * 和#,无法在拨号界面启动(Android可用)
flutter ios ussd url-launcher tel-uri PROBLEM

我的Flutter应用用于执行用于移动支付充值的USSD代码。在2026年之前,它在iOS上工作正常,但更新应用后,USSD代码在iPhone上不再执行。

关键观察:测试后我发现:

  • 常规电话号码如0123456789 → 能正确打开拨号界面 ✅
  • 去掉 * 的USSD → 能正确打开拨号界面 ✅
  • 去掉# 的USSD → 能正确打开拨号界面 ✅
  • 完整的USSD,例如 *140*1*70000000# → 但没有任何反应 ❌

这并不是我这边的代码改动——同样的代码在之前就能工作。这个问题仅出现在iOS上(测试过的机型有iPhone 7、10、12)。Android正常工作。

我的当前代码

static Future\<void\> ussd(String ussdCode) async {  
  if (kIsAppleOS) {  
    final Uri uri = Uri(  
      scheme: 'tel',  
      path: ussdCode, // e.g. \*140\*1\*70000000#  
    );  
    await launchUrl(uri);  
  } else {  
    await DirectCallPlus.makeCall(ussdCode);  
  }  
}

环境

Flutter 3.x · url_launcher: ^6.1.7 · direct_call_plus: ^1.0.4 · iOS 15、16、17 · 设备:iPhone 7、10、12

我尝试过的

  • 将# 编码为 %23 → 仍然被阻止
  • mode: LaunchMode.externalApplication → 没有差别
  • 将Uri.parse('tel:*140%231') 代替Uri() → 仍然被阻止
  • Package ussd_launcher: ^1.5.0 → Android仅支持,iOS不支持

问题

在2025/2026年,是否有办法在Flutter应用中自动在iOS上执行USSD代码?还是被苹果完全屏蔽?如果是这样,最佳的UX回退策略是什么,以引导用户手动拨号?

解决方案

这是现在被iOS阻止的,在最近版本中这是预期行为。

在iOS(15 -> 17+)上,苹果对tel: URL方案的处理变得更严格:

  • 0123456789 → 允许
  • *140*1\*70000000# → 被阻止/忽略

由于无法实现自动执行,目标是帮助用户以最小摩擦来手动拨号。

你已经注意到这项工作:

final Uri uri = Uri(
    scheme: 'tel',
    path: '*140*1*70000000', // remove #
);
await launchUrl(uri);

然后给用户的指示:

点击呼叫,然后再输入#

这是最接近无缝体验的方式。

站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。

相关文章