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

点击Flutter Web应用URL时,如何提示用户选择打开Chrome或Flutter移动端应用?

实现Flutter Web链接唤起App或选择Chrome打开的方案

要实现用户点击Flutter Web里的URL时,弹出选择框让用户选“打开已安装的Flutter移动端App”或是“用Chrome打开”,得从移动端Deep Link配置和Web端交互逻辑两部分入手,具体步骤如下:

只有配置了Deep Link,Web端的链接才能唤起你的App,Android和iOS的配置方式不同:

Android端配置

打开android/app/src/main/AndroidManifest.xml,给主Activity添加intent-filter,示例如下:

<intent-filter>
    <action android:name="android.intent.action.VIEW" />
    <category android:name="android.intent.category.DEFAULT" />
    <category android:name="android.intent.category.BROWSABLE" />
    <!-- 替换成你的自定义Scheme,比如myapp:// -->
    <data android:scheme="myapp" />
    <!-- 可选:配置HTTPS域名关联,比如https://yourdomain.com/app -->
    <data android:host="yourdomain.com" android:pathPrefix="/app" />
</intent-filter>

之后在Flutter代码里,用app_links或uni_links插件监听Deep Link,处理传入的跳转参数。

iOS端配置

打开ios/Runner/Info.plist,添加以下配置:

<key>LSApplicationQueriesSchemes</key>
<array>
    <string>myapp</string> <!-- 填你的自定义Scheme -->
</array>
<key>CFBundleURLTypes</key>
<array>
    <dict>
        <key>CFBundleURLSchemes</key>
        <array>
            <string>myapp</string>
        </array>
    </dict>
</array>

同样用插件监听Deep Link,处理App内的跳转逻辑。

2. Web端实现选择提示与跳转逻辑

在Flutter Web里,你需要做一个弹窗提示用户选择打开方式,同时处理“唤起App失败”的 fallback 逻辑(比如用户没装App时自动引导到Chrome)。

核心交互逻辑

  • 用户点击链接后,弹出选择对话框;
  • 选“打开App”时,用自定义Scheme唤起App,同时设一个超时定时器——如果超时后页面还处于激活状态,说明唤起失败,自动引导到Chrome打开;
  • 选“用Chrome打开”时,直接调用Chrome的唤起逻辑或打开目标URL。

Flutter Web代码示例

import 'dart:js' as js;
import 'dart:async';
import 'package:flutter/material.dart';

void showOpenOptionDialog(BuildContext context, String targetUrl) {
  showDialog(
    context: context,
    builder: (ctx) => AlertDialog(
      title: const Text('选择打开方式'),
      content: const Text('请选择用已安装的App打开,还是用Chrome浏览器打开'),
      actions: [
        TextButton(
          onPressed: () async {
            Navigator.pop(ctx);
            // 拼接唤起App的链接,把目标URL作为参数传递
            final appLaunchUrl = 'myapp://open?url=${Uri.encodeComponent(targetUrl)}';
            // 尝试唤起App
            js.context.callMethod('open', [appLaunchUrl]);
            
            // 3秒后检查是否唤起成功——如果页面还没被切走,说明没唤起
            Timer(const Duration(seconds: 3), () {
              if (!js.context['document']['hidden']) {
                ScaffoldMessenger.of(context).showSnackBar(
                  const SnackBar(content: Text('未检测到App,将在Chrome中打开')),
                );
                openInChrome(targetUrl);
              }
            });
          },
          child: const Text('打开App'),
        ),
        TextButton(
          onPressed: () {
            Navigator.pop(ctx);
            openInChrome(targetUrl);
          },
          child: const Text('用Chrome打开'),
        ),
      ],
    ),
  );
}

void openInChrome(String url) {
  final userAgent = js.context['navigator']['userAgent'].toString();
  if (userAgent.contains('Android')) {
    // Android用intent协议直接唤起Chrome
    js.context.callMethod('open', ['intent:$url#Intent;package=com.android.chrome;end']);
  } else if (userAgent.contains('iPhone') || userAgent.contains('iPad')) {
    // iOS无法直接唤起Chrome,先打开链接再提示用户切换
    js.context.callMethod('open', [url]);
    ScaffoldMessenger.of(context).showSnackBar(
      const SnackBar(content: Text('请切换到Chrome浏览器打开该链接')),
    );
  } else {
    // 桌面端直接开新窗口
    js.context.callMethod('open', [url, '_blank']);
  }
}

3. 关键注意点

  • 唤起失败的判断:浏览器不允许直接检测App是否安装,只能通过“页面是否保持激活”的方式间接判断,超时时间可以根据实际情况调2-5秒;
  • 浏览器拦截问题:部分浏览器会拦截自定义Scheme的唤起,这种情况下可以加个提示,让用户手动打开App;
  • HTTPS关联优化:如果用Android App Links或iOS Universal Links(基于HTTPS域名),唤起App时不会弹出确认框,体验更好,但需要做域名验证配置;
  • Chrome唤起限制:iOS系统限制了直接唤起其他浏览器,只能提示用户手动切换,Android则可以通过intent协议指定Chrome包名直接唤起。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.07 13:30:15