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

如何在Flutter Web中检测宿主操作系统及浏览器?

Flutter Web 实现操作系统与浏览器检测以提示添加至主屏幕

在Flutter Web场景下,client_information、device_info_plus这类原生插件无法生效,我们可以直接借助浏览器的JavaScript API来获取客户端信息,结合PWA的标准事件实现需求。

核心思路

Flutter Web运行在浏览器环境中,可通过dart:js调用浏览器的navigator对象获取userAgent字符串,解析出操作系统与浏览器类型;同时监听浏览器的beforeinstallprompt事件,判断是否支持"添加至主屏幕"功能,最终结合两者条件触发提示。

具体实现步骤

1. 解析User Agent识别OS与浏览器

创建工具函数解析navigator.userAgent,筛选出符合条件的客户端:

import 'dart:js' as js;

// 判断是否为iOS/iPadOS(排除macOS)
bool isIOSOrIPadOS() {
  final userAgent = js.context['navigator']['userAgent'] as String;
  final platform = js.context['navigator']['platform'] as String;
  return (platform == 'iPhone' || platform == 'iPad' || platform == 'iPod') ||
      (userAgent.contains('Mac') && !userAgent.contains('Intel Mac OS X') && userAgent.contains('like Mac OS X'));
}

// 判断是否为支持添加至主屏幕的浏览器
bool isSupportedBrowser() {
  final userAgent = js.context['navigator']['userAgent'] as String;
  // Safari
  if (userAgent.contains('Safari') && !userAgent.contains('Chrome') && !userAgent.contains('Firefox')) {
    return true;
  }
  // iOS 16.4+ 第三方浏览器(需检测iOS版本)
  final iosVersionMatch = RegExp(r'OS (\d+)_(\d+)').firstMatch(userAgent);
  if (iosVersionMatch != null) {
    final major = int.parse(iosVersionMatch.group(1)!);
    final minor = int.parse(iosVersionMatch.group(2)!);
    if (major > 16 || (major == 16 && minor >=4)) {
      // iOS 16.4+ 所有浏览器均支持
      return true;
    }
  }
  return false;
}

2. 监听beforeinstallprompt事件

浏览器会在支持PWA添加至主屏幕时触发beforeinstallprompt事件,我们可以保存该事件,在符合条件时触发提示:

import 'dart:html' as html;

html.BeforeInstallPromptEvent? _installPromptEvent;

void initInstallPromptListener() {
  html.window.addEventListener('beforeinstallprompt', (event) {
    // 阻止浏览器默认提示
    event.preventDefault();
    // 保存事件用于后续触发
    _installPromptEvent = event as html.BeforeInstallPromptEvent;
  });
}

// 触发添加至主屏幕提示
void showInstallPrompt() {
  if (_installPromptEvent != null && isIOSOrIPadOS() && isSupportedBrowser()) {
    _installPromptEvent!.prompt();
    // 监听用户选择结果
    _installPromptEvent!.userChoice.then((choice) {
      if (choice.outcome == 'accepted') {
        print('用户已添加应用至主屏幕');
      } else {
        print('用户拒绝添加');
      }
      _installPromptEvent = null;
    });
  }
}

3. 整合到Flutter Widget中

在Widget初始化时监听事件,并提供触发提示的入口:

class HomePage extends StatefulWidget {
  const HomePage({super.key});

  @override
  State<HomePage> createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  @override
  void initState() {
    super.initState();
    initInstallPromptListener();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('PWA 添加至主屏幕示例')),
      body: Center(
        child: ElevatedButton(
          onPressed: () {
            if (isIOSOrIPadOS() && isSupportedBrowser()) {
              showInstallPrompt();
            } else {
              // 不符合条件时提示用户
              ScaffoldMessenger.of(context).showSnackBar(
                const SnackBar(content: Text('当前设备/浏览器不支持添加至主屏幕')),
              );
            }
          },
          child: const Text('添加至主屏幕'),
        ),
      ),
    );
  }
}

注意事项

  • userAgent字符串可能随浏览器版本更新发生变化,需定期维护解析逻辑;
  • 避免自动弹出提示,建议通过用户主动点击按钮触发,提升用户体验;
  • iOS 16.4+的第三方浏览器支持beforeinstallprompt事件,需确保版本检测逻辑准确。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 06:53:14