有人使用 flutter_downloader 包实现了文件下载。我对此有一些问题。 该文件第一次下载到我的应用程序目录。但在通知栏中它显示失败,在控制台中也显示失败。还有其他人成功实施过吗?
我将在下面附上我的代码和其他信息
这是我使用的软件包
flutter_downloader: ^1.11.6
permission_handler: ^11.0.1
path_provider: ^2.1.2
以下是完整代码
import 'dart:developer';
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';
@pragma('vm:entry-point')
void callback(String id, int status, int progress) {
log('cal ack----------id=$id--stauus=$status---progress=$progress');
if (status == DownloadTaskStatus.complete.index) {
final SendPort? send =
IsolateNameServer.lookupPortByName('downloader_send_port');
send?.send([id, status, progress]);
}
else{
log('this is $status');
}
}
Future main() async {
WidgetsFlutterBinding.ensureInitialized();
await FlutterDownloader.initialize(debug: true,ignoreSsl: true);
await FlutterDownloader.registerCallback(callback);
runApp(const MainApp());
}
class MainApp extends StatefulWidget {
const MainApp({super.key});
@override
State<MainApp> createState() => _MainAppState();
}
class _MainAppState extends State<MainApp> {
final ReceivePort _port = ReceivePort();
@override
void initState() {
super.initState();
IsolateNameServer.registerPortWithName(
_port.sendPort, 'downloader_send_port');
_port.listen((message) {
log(message);
String id = message[0];
Future.delayed(const Duration(seconds: 1), () {
FlutterDownloader.loadTasksWithRawQuery(
query: "SELECT * FROM task WHERE task_id='$id'")
.then((tasks) {
if (tasks == null || tasks.isEmpty) return;
final task = tasks.first;
final taskId = task.taskId;
final filename = task.filename;
final path = task.savedDir;
// TODO: check here the file path and filename of the task
// these aren't the correct ones, when saveInPublicStorage is true
// furthermore the file is renamed, when existing to 'filename.pdf (1)', filename.pdf (2), and so on
// perhaps a renaming before the file extension would be better: 'filename (1).pdf' instead of 'filename.pdf (1)'
log('Task: $taskId, status: $path, progress: $filename');
FlutterDownloader.open(taskId: id)
.then((value) => {debugPrint('Open file: $value')});
});
});
});
}
@override
void dispose() {
IsolateNameServer.removePortNameMapping('downloader_send_port');
super.dispose();
}
Future _tryDeleteExistingFile(String? path, String filename) async {
try {
File file = File('$path/$filename');
if (await file.exists()) {
await file.delete();
}
} catch (err, stack) {
debugPrint("Cannot delete existing file");
}
}
_downloadFile() async {
var status = await Permission.storage.status;
if (!status.isGranted) {
await Permission.storage.request();
}
debugPrint('Download file');
const urlString =
'https://www.w3.org/WAI/ER/tests/xhtml/testfiles/resources/pdf/dummy.pdf';
try {
final path = (await getExternalStorageDirectory())!.path;
log('path==$path');
// this one is needed for duplicate downloads into the externalStorageDirectory
// await _tryDeleteExistingFile(path, 'dummy.pdf');
final taskId = await FlutterDownloader.enqueue(
url: urlString,
savedDir:
path, // here we could also use the 'await getDownloadsDirectory().path' instead
headers: {},
showNotification: true,
openFileFromNotification: true,
// saveInPublicStorage: true,
);
} catch (e) {
log(e.toString());
}
}
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: true,
color: Colors.blue,
home: Scaffold(
appBar: AppBar(
title: const Text('Download File Example'),
centerTitle: true,
backgroundColor: Colors.blue,
),
body: Column(
children: <Widget>[
const SizedBox(height: 20),
Center(
child: MaterialButton(
color: Colors.orange,
onPressed: _downloadFile,
child: const Text('Download File'),
),
),
],
),
));
}
}
为了更加清晰,我还附上了手机和控制台中通知栏的屏幕截图
我是根据包文档完成的。我可以下载该文件,但在控制台 t 中显示失败,并且在通知栏中也显示失败。
添加此行:xmlns:tools="https://schemas.android.com/tools"