Flutter应用内打开网页无法下载PDF文件问题求助
解决Flutter应用内网页PDF点击无响应的问题
问题分析
你当前使用url_launcher的launchUrl方法跳转网页,虽能正常打开页面,但网页内的PDF链接点击无反应;外部浏览器打开同一URL则可正常下载PDF。由于PDF文件数量较多,无法逐个使用文件直链,因此通过flutter_inappwebview包实现应用内网页加载并处理PDF下载是最优方案。
解决方案步骤
1. 添加依赖
在pubspec.yaml中引入flutter_inappwebview包:
dependencies: flutter: sdk: flutter flutter_inappwebview: ^6.0.0 # 建议使用最新版本
执行flutter pub get完成依赖安装。
2. 修改按钮跳转逻辑
将原来的launchUrl跳转改为打开内嵌WebView页面,调整按钮的onPressed代码:
FloatingActionButton.large( backgroundColor: Color.fromRGBO(136, 221, 198, 1), onPressed: () { Navigator.push( context, MaterialPageRoute( builder: (context) => WebViewPage(url: 'https://www.agricultura.rs.gov.br/agrometeorologia'), ), ); }, child: Image( image: AssetImage("assets/book.png"), height: size.height * .1, ), ),
3. 创建WebView页面并配置PDF下载处理
新建WebViewPage组件,通过InAppWebView加载网页,并监听下载请求处理PDF文件:
import 'package:flutter/material.dart'; import 'package:flutter_inappwebview/flutter_inappwebview.dart'; import 'package:path_provider/path_provider.dart'; import 'dart:io'; class WebViewPage extends StatefulWidget { final String url; const WebViewPage({Key? key, required this.url}) : super(key: key); @override State<WebViewPage> createState() => _WebViewPageState(); } class _WebViewPageState extends State<WebViewPage> { InAppWebViewController? webViewController; final GlobalKey webViewKey = GlobalKey(); @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: const Text('Leitura Complementar')), body: InAppWebView( key: webViewKey, initialUrlRequest: URLRequest(url: Uri.parse(widget.url)), onWebViewCreated: (controller) { webViewController = controller; }, onDownloadStartRequest: (controller, downloadStartRequest) async { // 获取下载链接与文件名 final downloadUrl = downloadStartRequest.url; final fileName = downloadUrl.pathSegments.last; // 获取设备存储目录 final storageDir = await getExternalStorageDirectory(); if (storageDir == null) { ScaffoldMessenger.of(context).showSnackBar( const SnackBar(content: Text('无法获取存储目录')), ); return; } final filePath = '${storageDir.path}/$fileName'; // 触发文件下载 await controller.downloadFile( url: downloadUrl, destinationFilePath: filePath, onDownloadProgress: (progress) { // 可选:打印下载进度 print('下载进度: ${(progress.progress * 100).round()}%'); }, ); // 下载完成提示用户 ScaffoldMessenger.of(context).showSnackBar( SnackBar(content: Text('文件已下载至: $filePath')), ); }, ), ); } }
4. 配置平台权限
- Android:在
android/app/src/main/AndroidManifest.xml中添加权限:
<uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
- iOS:在
ios/Runner/Info.plist中添加配置:
<key>NSAppTransportSecurity</key> <dict> <key>NSAllowsArbitraryLoads</key> <true/> </dict> <key>LSSupportsOpeningDocumentsInPlace</key> <true/>
原理说明
flutter_inappwebview提供了完整的网页加载控制能力,通过onDownloadStartRequest回调可捕获网页内所有下载请求(包括PDF链接)。我们在回调中处理文件存储路径、下载进度提示和完成通知,解决了原生跳转无法处理内嵌网页PDF下载的问题。
内容的提问来源于stack exchange,提问作者romyyyy
相关产品推荐
相关产品推荐

