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

Flutter中如何用InAppWebView的ChromeSafariBrowser在Android上打开/下载PDF

Flutter Android 应用内打开/重新下载PDF解决方案

一、理想方案:应用内直接打开PDF(无需跳转浏览器)

用内嵌PDF查看组件替代浏览器跳转,完全在应用内完成PDF查看,体验更流畅。推荐使用flutter_pdfview包,配合文件下载工具实现:

  1. 先在pubspec.yaml添加依赖:
dependencies:
  flutter_pdfview: ^1.2.7
  dio: ^5.3.2
  path_provider: ^2.1.1
  1. 修改URL拦截与处理逻辑:
shouldOverrideUrlLoading: (controller, nav) async {
  final Uri? url = nav.request.url;
  if (url != null && url.path.endsWith('.pdf')) {
    // 下载PDF到本地存储
    final String localFilePath = await _downloadPdfToLocal(url.toString());
    // 跳转到应用内的PDF查看页面
    Navigator.push(context, MaterialPageRoute(
      builder: (context) => InAppPdfViewer(filePath: localFilePath),
    ));
    return NavigationActionPolicy.CANCEL;
  }
  // 非PDF链接按原有逻辑处理
  return NavigationActionPolicy.ALLOW;
}

// 下载PDF到本地的工具方法
Future<String> _downloadPdfToLocal(String pdfUrl) async {
  final dio = Dio();
  final storageDir = await getApplicationDocumentsDirectory();
  final uniqueFileName = '${DateTime.now().millisecondsSinceEpoch}.pdf';
  final savePath = '${storageDir.path}/$uniqueFileName';
  
  await dio.download(pdfUrl, savePath);
  return savePath;
}

// 应用内PDF查看页面组件
class InAppPdfViewer extends StatelessWidget {
  final String filePath;
  const InAppPdfViewer({super.key, required this.filePath});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('PDF查看器')),
      body: PDFView(
        filePath: filePath,
        enableSwipe: true,
        swipeHorizontal: true,
        autoSpacing: false,
        pageFling: false,
      ),
    );
  }
}

二、备选方案:强制重新下载PDF(不退出应用)

如果暂时不想集成内嵌PDF组件,可通过给PDF URL添加随机参数的方式,绕过Chrome的下载缓存,实现重新下载且不退出应用:

修改你的launchInBrowserOverlay方法:

static launchInBrowserOverlay(value) async {
  Uri originalUri = Uri.parse(value);
  // 添加唯一时间戳参数,让Chrome认为是新请求
  Uri updatedUri = originalUri.replace(
    queryParameters: {
      ...originalUri.queryParameters,
      't': DateTime.now().millisecondsSinceEpoch.toString(),
    },
  );
  ChromeSafariBrowser().open(
    url: updatedUri,
    options: ChromeSafariBrowserClassOptions(
      android: AndroidChromeCustomTabsOptions(
        packageName: 'com.android.chrome',
      ),
    ),
  );
}

问题原因

当前出现“Download is pending...”是因为Chrome会缓存下载请求记录,当检测到相同URL的文件已存在时,不会重复发起下载,而是提示等待状态。上述两种方案分别从“内嵌查看”和“绕过缓存”的角度解决了问题。

内容的提问来源于stack exchange,提问作者Anna R.

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.08 02:16:18