Flutter文件下载管理插件native_flutter_downloader的使用

发布于 1周前 作者 vueper 来自 Flutter

Flutter文件下载管理插件native_flutter_downloader的使用

native_flutter_downloader 是一个用于在Flutter应用中下载文件的插件。它利用设备的原生能力来下载文件。具体来说,在Android上,它使用DownloadManager系统服务将文件直接下载到用户的“下载”文件夹中。在iOS上,它使用URLSession将文件下载到应用程序的文档文件夹中。

代码示例

以下是一个完整的示例代码,展示了如何使用 native_flutter_downloader 插件来下载文件并显示下载进度。

import 'dart:async';
import 'package:native_flutter_downloader/native_flutter_downloader.dart';
import 'package:flutter/material.dart';

void main() {
  runApp(const MyApp());
}

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

  @override
  State<MyApp> createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  final TextEditingController urlController = TextEditingController(
    text: 'https://player.vimeo.com/progressive_redirect/playback/828907811/rendition/1080p/file.mp4?loc=external&oauth2_token_id=1643955558&signature=0da5f40183c29f3c61d6ed3ac01e51732e1d6136ec63cc1513d61e2ce804027b',
  );

  int progress = 0;
  late StreamSubscription progressStream;

  @override
  void initState() {
    NativeFlutterDownloader.initialize();
    progressStream = NativeFlutterDownloader.progressStream.listen((event) {
      if (event.status == DownloadStatus.successful) {
        setState(() {
          progress = event.progress;
        });
      } else if (event.status == DownloadStatus.running) {
        debugPrint('event.progress: ${event.progress}');
        setState(() {
          progress = event.progress;
        });
      } else if (event.status == DownloadStatus.failed) {
        debugPrint('event: ${event.statusReason?.message}');
        debugPrint('Download failed');
      } else if (event.status == DownloadStatus.paused) {
        debugPrint('Download paused');
        Future.delayed(
          const Duration(milliseconds: 250),
          () => NativeFlutterDownloader.attachDownloadProgress(event.downloadId),
        );
      } else if (event.status == DownloadStatus.pending) {
        debugPrint('Download pending');
      }
    });
    super.initState();
  }

  @override
  void dispose() {
    progressStream.cancel();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      home: Scaffold(
        appBar: AppBar(
          title: const Text('Native Flutter Downloader'),
        ),
        body: Column(
          children: [
            if (progress > 0 && progress < 100)
              LinearProgressIndicator(
                value: progress / 100,
                color: Colors.orange,
              ),
            Expanded(
              child: Padding(
                padding: const EdgeInsets.all(8.0),
                child: TextField(
                  controller: urlController,
                ),
              ),
            ),
          ],
        ),
        floatingActionButton: FloatingActionButton(
          child: const Icon(Icons.file_download),
          onPressed: () async {
            final permission = await NativeFlutterDownloader.requestPermission();
            if (permission == StoragePermissionStatus.granted) {
              await NativeFlutterDownloader.download(
                urlController.text,
                fileName: 'your_filename',
                savedFilePath: '/storage/emulated/0/Download',
              );
            } else {
              debugPrint('Permission denied =(');
            }
          },
        ),
      ),
    );
  }
}

iOS 配置

默认情况下,下载的文件不会显示在用户的“文件”应用中。如果你希望用户能够在“文件”应用中看到这些文件,可以在 info.plist 文件中添加以下配置:

<key>LSSupportsOpeningDocumentsInPlace</key>
<true/>
<key>UIFileSharingEnabled</key>
<true/>

这些配置项启用了必要的权限,使应用程序能够与用户的设备共享文件并在“文件”应用中显示它们。

Android 配置

在 Android 10+ 上,不需要特殊配置。如果你的应用支持 Android 9(API 28)或更低版本,则必须在调用 download() 方法之前调用 requestPermission() 并检查权限状态。

注意:此插件期望 compileSdkVersion 是最新的 Android SDK,例如:

android {
    compileSdkVersion 34

    [...]
}

作者

维护者

发布者

希望这个示例对你有所帮助!如果有任何问题或需要进一步的帮助,请随时提问。


更多关于Flutter文件下载管理插件native_flutter_downloader的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter文件下载管理插件native_flutter_downloader的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,以下是如何在Flutter项目中使用native_flutter_downloader插件来进行文件下载管理的示例代码。这个插件允许你在后台下载文件,并在下载完成后处理各种事件。

1. 添加依赖

首先,在你的pubspec.yaml文件中添加native_flutter_downloader依赖:

dependencies:
  flutter:
    sdk: flutter
  native_flutter_downloader: ^x.x.x  # 请替换为最新版本号

然后运行flutter pub get来安装依赖。

2. 配置Android和iOS

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"/>

并在<application>标签内添加以下服务声明:

<service
    android:name="vn.hunghd.flutterdownloader.DownloadWorkerService"
    android:enabled="true"
    android:exported="true"
    android:permission="android.permission.BIND_JOB_SERVICE" />
<provider
    android:name="vn.hunghd.flutterdownloader.FlutterDownloaderInitializer"
    android:authorities="${applicationId}.flutter_downloader.provider"
    android:exported="false"
    android:grantUriPermissions="true">
    <meta-data
        android:name="android.support.FILE_PROVIDER_PATHS"
        android:resource="@xml/provider_paths"/>
</provider>

接着,在android/app/src/main/res/xml目录下创建一个名为provider_paths.xml的文件,并添加以下内容:

<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
    <external-path name="my_images" path="."/>
</paths>

iOS配置

在你的ios/Runner/Info.plist中添加以下权限:

<key>NSAppTransportSecurity</key>
<dict>
    <key>NSAllowsArbitraryLoads</key>
    <true/>
</dict>

然后在ios/Runner/AppDelegate.swift(或AppDelegate.m)中添加以下代码来初始化FlutterDownloader:

import UIKit
import Flutter
import native_flutter_downloader

@UIApplicationMain
@objc class AppDelegate: FlutterAppDelegate {
  override func application(
    _ application: UIApplication,
    didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
  ) -> Bool {
    GeneratedPluginRegistrant.register(with: self)
    FlutterDownloaderPlugin.setPluginRegistrantCallback { registry in
      if let flutterEngine = (UIApplication.shared.delegate as? AppDelegate)?.window??.rootViewController?.presentedViewController as? FlutterEngine {
        FlutterDownloaderPlugin.register(with: registry.toRegistrar(for: flutterEngine!))
      }
    }
    return super.application(application, didFinishLaunchingWithOptions: launchOptions)
  }
}

3. 使用FlutterDownloader进行文件下载

在你的Flutter代码中,你可以这样使用FlutterDownloader

import 'package:flutter/material.dart';
import 'package:path_provider/path_provider.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:native_flutter_downloader/native_flutter_downloader.dart';

void main() {
  WidgetsFlutterBinding.ensureInitialized();
  // 初始化FlutterDownloader
  FlutterDownloader.initialize(
      debug: true // 打开调试模式,以便在控制台中查看下载进度
  ).then((_) {
    runApp(MyApp());
  });
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('Flutter Downloader Example'),
        ),
        body: Center(
          child: ElevatedButton(
            onPressed: _startDownload,
            child: Text('Start Download'),
          ),
        ),
      ),
    );
  }

  Future<void> _requestPermissions() async {
    var status = await Permission.storage.status;
    if (!status.isGranted) {
      var result = await Permission.storage.request();
      if (!result.isGranted) {
        throw '存储权限被拒绝';
      }
    }
  }

  Future<void> _startDownload() async {
    try {
      await _requestPermissions();

      final taskId = await FlutterDownloader.enqueue(
        url: 'https://example.com/yourfile.zip',
        savedDir: (await getExternalStorageDirectory())?.path,
        fileName: 'yourfile.zip',
        showNotification: true,
        openFileFromNotification: true,
      );

      print('下载任务ID: $taskId');
    } catch (e) {
      print('下载失败: $e');
    }
  }
}

4. 处理下载事件

你可以监听下载事件,比如下载完成、进度更新等:

void _listenDownloadEvents() {
  FlutterDownloader.registerCallback((id, status, progress) {
    print("Download task ($id) is in status ($status) and process ($progress)");
    if (status == DownloadTaskStatus.complete) {
      // 下载完成后可以执行的操作,比如打开文件
      var localPath = FlutterDownloader.find(taskId: id).path;
      // 使用localPath执行相关操作,比如打开文件
    }
  });
}

main函数中调用_listenDownloadEvents来开始监听下载事件:

void main() {
  WidgetsFlutterBinding.ensureInitialized();
  FlutterDownloader.initialize(debug: true).then((_) {
    _listenDownloadEvents(); // 注册下载事件监听
    runApp(MyApp());
  });
}

这段代码展示了如何使用native_flutter_downloader插件在Flutter应用中实现文件下载管理。注意在实际项目中,你可能需要根据具体需求调整文件保存路径、文件名以及权限请求等细节。

回到顶部