安装

dependencies:
flutter_downloader: ^1.3.1

配置

Java:

// MyApplication.java
package com.example.flutter_demo; // 设置你的 import io.flutter.app.FlutterApplication;
import io.flutter.plugin.common.PluginRegistry;
import io.flutter.plugins.GeneratedPluginRegistrant; public class MyApplication extends FlutterApplication implements PluginRegistry.PluginRegistrantCallback {
@Override
public void registerWith(PluginRegistry registry) {
GeneratedPluginRegistrant.registerWith(registry);
}
}

Or Kotlin:

// MyApplication.kt
package com.example.flutter_demo // 设置你的 import io.flutter.app.FlutterApplication
import io.flutter.plugin.common.PluginRegistry;
import io.flutter.plugins.GeneratedPluginRegistrant internal class MyApplication : FlutterApplication(), PluginRegistry.PluginRegistrantCallback {
override fun registerWith(registry: PluginRegistry) {
GeneratedPluginRegistrant.registerWith(registry)
}
}

更新AndroidManifest.xml

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.flutter_demo"> <!-- new -->
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<!-- new --> <!-- io.flutter.app.FlutterApplication is an android.app.Application that
calls FlutterMain.startInitialization(this); in its onCreate method.
In most cases you can leave this as-is, but you if you want to provide
additional functionality it is fine to subclass or reimplement
FlutterApplication and put your custom class here. --> <!-- 更新 android:name -->
<application
android:name=".MyApplication"
android:label="flutter_demo"
android:icon="@mipmap/ic_launcher">
<activity
android:name=".MainActivity"
android:launchMode="singleTop"
android:theme="@style/LaunchTheme"
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
android:hardwareAccelerated="true"
android:windowSoftInputMode="adjustResize">
<!-- This keeps the window background of the activity showing
until Flutter renders its first frame. It can be removed if
there is no splash screen (such as the default splash screen
defined in @style/LaunchTheme). -->
<meta-data
android:name="io.flutter.app.android.SplashScreenUntilFirstFrame"
android:value="true" />
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity> <!-- flutter_downloader new-->
<provider
android:name="vn.hunghd.flutterdownloader.DownloadedFileProvider"
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> <provider
android:name="androidx.work.impl.WorkManagerInitializer"
android:authorities="${applicationId}.workmanager-init"
android:enabled="false"
android:exported="false" /> <provider
android:name="vn.hunghd.flutterdownloader.FlutterDownloaderInitializer"
android:authorities="${applicationId}.flutter-downloader-init"
android:exported="false">
<!-- changes this number to configure the maximum number of concurrent tasks -->
<meta-data
android:name="vn.hunghd.flutterdownloader.MAX_CONCURRENT_TASKS"
android:value="5" />
</provider>
<!-- new -->
</application>
</manifest>

andriod 上简单的使用

// main.dart
import 'dart:io';
import 'dart:isolate';
import 'dart:ui'; import 'package:flutter/material.dart';
import 'package:flutter_downloader/flutter_downloader.dart';
import 'package:path_provider/path_provider.dart';
import 'package:permission_handler/permission_handler.dart'; void main() async {
runApp(MyApp());
} class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: HomePage(),
);
}
} class HomePage extends StatefulWidget {
@override
_HomePageState createState() => _HomePageState();
} class _HomePageState extends State<HomePage> {
String downloadId;
String _link = "https://i.loli.net/2019/10/18/gE3PTycd9SF5VqY.jpg";
String _localPath; ReceivePort _port = ReceivePort(); @override
void initState() {
super.initState();
_init();
} Future<void> _init() async {
await FlutterDownloader.initialize();
IsolateNameServer.registerPortWithName(
_port.sendPort, 'downloader_send_port');
_port.listen((dynamic data) {
print('UI Isolate Callback: $data');
String id = data[0];
DownloadTaskStatus status = data[1];
int progress = data[2]; print("status: $status");
print("progress: $progress");
print("id == downloadId: ${id == downloadId}");
});
FlutterDownloader.registerCallback(downloadCallback); _localPath = (await _findLocalPath()) + '/Download';
final savedDir = Directory(_localPath);
bool hasExisted = await savedDir.exists();
if (!hasExisted) {
savedDir.create();
}
} static void downloadCallback(
String id, DownloadTaskStatus status, int progress) {
print(
'Background Isolate Callback: task ($id) is in status ($status) and process ($progress)');
final SendPort send =
IsolateNameServer.lookupPortByName('downloader_send_port');
send.send([id, status, progress]);
} Future<String> _findLocalPath() async {
final directory = await getExternalStorageDirectory();
return directory.path;
} Future<bool> _checkPermission() async {
if (Theme.of(context).platform == TargetPlatform.android) {
PermissionStatus permission = await PermissionHandler()
.checkPermissionStatus(PermissionGroup.storage);
if (permission != PermissionStatus.granted) {
Map<PermissionGroup, PermissionStatus> permissions =
await PermissionHandler()
.requestPermissions([PermissionGroup.storage]);
if (permissions[PermissionGroup.storage] == PermissionStatus.granted) {
return true;
}
} else {
return true;
}
} else {
return true;
}
return false;
} @override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Home Page'),
),
body: Center(
child: Text('home page'),
),
floatingActionButton: FloatingActionButton(
child: Icon(Icons.arrow_downward),
onPressed: () async {
if (await _checkPermission()) {
final taskId = await FlutterDownloader.enqueue(
url: _link,
savedDir: _localPath,
showNotification:
true, // show download progress in status bar (for Android)
openFileFromNotification:
true, // click on notification to open downloaded file (for Android)
);
downloadId = taskId;
}
},
),
);
}
}

中文模板res/values-b+zh+ZH/strings.xml


<resources>
<string name="flutter_downloader_notification_started">下载开始</string>
<string name="flutter_downloader_notification_in_progress">正在下载</string>
<string name="flutter_downloader_notification_canceled">下载取消</string>
<string name="flutter_downloader_notification_failed">下载错误</string>
<string name="flutter_downloader_notification_complete">下载完成</string>
<string name="flutter_downloader_notification_paused">下载暂停</string>
</resources>

最新文章

  1. 解决Asp.net Mvc中使用异步的时候HttpContext.Current为null的方法
  2. java socket 通讯
  3. java变量和方法的覆盖和隐藏(翻译自Java Tutorials)
  4. IT公司100题-25-求字符串中的最长数字串
  5. (二)、SSL证书
  6. 安装MySQL在最后的start service停住了解决方法
  7. Java中如何创建进程(转)
  8. 树莓派入门教程——使用Qt开发界面程序
  9. linux搭建php
  10. Linux中查看文本文件内容命令cat/tac/nl/more/less/head/tail/vi总结
  11. .NET Core 迁移躺坑记
  12. aspnetcore 日志 serilog-aspnetcore
  13. win7文件搜索技巧
  14. K8S学习笔记之ETCD启动失败注意事项
  15. 2018-2019-2 《网络对抗技术》Exp0 Kali安装 Week1 20165320
  16. &lt;3&gt;Cocos Creator编辑器基础
  17. centos 7上nginx+uwsgi 性能调优
  18. 笔记react router 4(二)
  19. SQL Server--疑难杂症之坑爹的Windows故障转移群集
  20. Android 应用程序之间内容分享详解(二)

热门文章

  1. Python中,单引号,双引号,三引号的使用区别与原因
  2. CF175C Geometry Horse 题解
  3. 11.15 gryz校测(题解分析报告)
  4. tricks - 实现
  5. HaspMap源码分析(JDK 1.8)
  6. Django(简介)
  7. BZOJ2882 工艺【SAM】 最小循环串
  8. HDU - 2825 Wireless Password (AC自动机+状压DP)
  9. Codeforces Round #649 (Div. 2) A. XXXXX (贪心)
  10. CF1471-C. Strange Birthday Party