Flutter应用下载完成后如何打开系统公共下载文件夹?
嘿,这个需求我之前做Flutter项目时刚好碰到过,其实就是需要通过**平台通道(Method Channel)**调用原生能力来实现,毕竟Flutter本身没有直接提供打开系统下载文件夹的API。下面给你分Android和iOS两个平台详细说下实现方案:
Android平台实现
这部分完全可以对应你提到的原生startActivity(new Intent(DownloadManager.ACTION_VIEW_DOWNLOADS))逻辑,通过MethodChannel调用原生代码即可。
Flutter端代码
首先在你的Flutter业务代码中创建MethodChannel,用来和Android原生通信:
import 'package:flutter/services.dart'; class DownloadHelper { // 定义通道名称,要和原生端保持一致 static const MethodChannel _channel = MethodChannel('download_folder_handler'); // 封装打开下载文件夹的方法 static Future<void> openSystemDownloads() async { try { await _channel.invokeMethod('launchDownloads'); } on PlatformException catch (e) { print("打开下载文件夹失败: ${e.message}"); // 这里可以添加自定义错误提示,比如Toast告知用户 } } }
下载完成后直接调用await DownloadHelper.openSystemDownloads()就可以触发原生逻辑。
Android原生代码
打开android/app/src/main/kotlin/[你的包名]/MainActivity.kt,注册MethodChannel并实现打开系统下载页面的逻辑:
import android.app.DownloadManager import android.content.Intent import io.flutter.embedding.android.FlutterActivity import io.flutter.embedding.engine.FlutterEngine import io.flutter.plugin.common.MethodChannel class MainActivity : FlutterActivity() { private val CHANNEL_NAME = "download_folder_handler" override fun configureFlutterEngine(flutterEngine: FlutterEngine) { super.configureFlutterEngine(flutterEngine) // 注册MethodChannel并处理Flutter端的调用 MethodChannel(flutterEngine.dartExecutor.binaryMessenger, CHANNEL_NAME).setMethodCallHandler { call, result -> if (call.method == "launchDownloads") { // 调用你熟悉的原生Intent打开下载页面 val intent = Intent(DownloadManager.ACTION_VIEW_DOWNLOADS) startActivity(intent) result.success(null) } else { result.notImplemented() } } } }
iOS平台实现
iOS没有像Android那样直接的系统下载页面Intent,但可以引导用户打开系统「文件」应用并定位到下载目录,同样用MethodChannel实现。
Flutter端代码
可以直接复用上面的DownloadHelper类,不需要额外修改,MethodChannel会自动适配平台。
iOS原生代码
打开ios/Runner/AppDelegate.swift(如果是SwiftUI工程则修改SceneDelegate.swift),添加MethodChannel的处理逻辑:
import UIKit import Flutter @UIApplicationMain @objc class AppDelegate: FlutterAppDelegate { private let CHANNEL_NAME = "download_folder_handler" override func application( _ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? ) -> Bool { let controller = window?.rootViewController as! FlutterViewController let channel = FlutterMethodChannel(name: CHANNEL_NAME, binaryMessenger: controller.binaryMessenger) channel.setMethodCallHandler({ [weak self] (call: FlutterMethodCall, result: FlutterResult) -> Void in guard call.method == "launchDownloads" else { result(FlutterMethodNotImplemented) return } self?.openDownloadDirectory() result(nil) }) GeneratedPluginRegistrant.register(with: self) return super.application(application, didFinishLaunchingWithOptions: launchOptions) } private func openDownloadDirectory() { // 获取系统下载目录的URL guard let downloadsUrl = FileManager.default.urls(for: .downloadsDirectory, in: .userDomainMask).first else { return } // 打开文件应用并定位到下载目录 UIApplication.shared.open(downloadsUrl, options: [:], completionHandler: nil) } }
另外需要在ios/Runner/Info.plist中添加配置,确保可以正常打开文件应用:
<key>LSApplicationQueriesSchemes</key> <array> <string>shareddocuments</string> <string>fileprovider</string> </array>
额外优化建议
可以在Flutter端先判断当前平台,再做对应处理,兼顾兼容性:
import 'dart:io' show Platform; // 调用前判断平台 if (Platform.isAndroid || Platform.isIOS) { await DownloadHelper.openSystemDownloads(); } else { // 对其他平台(比如Windows/macOS)可以提示用户手动查找下载文件夹 }
内容的提问来源于stack exchange,提问作者Precisetotal erp

