You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
126 lines
3.5 KiB
126 lines
3.5 KiB
2 weeks ago
|
import 'dart:io';
|
||
|
import 'package:dio/dio.dart';
|
||
|
import 'package:permission_handler/permission_handler.dart';
|
||
|
import 'package:flutter/material.dart';
|
||
|
|
||
|
class DownloadApi {
|
||
|
final Dio dio = Dio();
|
||
|
|
||
|
// 申请存储权限
|
||
|
Future<bool> _requestStoragePermission(BuildContext context) async {
|
||
|
// 检查权限状态
|
||
|
PermissionStatus status = await Permission.manageExternalStorage.status;
|
||
|
|
||
|
if (status.isDenied) {
|
||
|
// 如果权限被拒绝,请求权限
|
||
|
// PermissionStatus status1 = await Permission.storage.request();
|
||
|
status = await Permission.manageExternalStorage.request();
|
||
|
print(status);
|
||
|
if (status.isDenied || status.isPermanentlyDenied || status.isRestricted) {
|
||
|
if (context.mounted) {
|
||
|
showDialog(
|
||
|
context: context,
|
||
|
builder: (BuildContext context) => AlertDialog(
|
||
|
title: const Text('需要存储权限'),
|
||
|
content: const Text('下载音乐需要存储权限,请在设置中允许访问存储权限。'),
|
||
|
actions: <Widget>[
|
||
|
TextButton(
|
||
|
child: const Text('取消'),
|
||
|
onPressed: () => Navigator.of(context).pop(),
|
||
|
),
|
||
|
TextButton(
|
||
|
child: const Text('去设置'),
|
||
|
onPressed: () {
|
||
|
Navigator.of(context).pop();
|
||
|
openAppSettings(); // 打开应用设置页面
|
||
|
},
|
||
|
),
|
||
|
],
|
||
|
),
|
||
|
);
|
||
|
}
|
||
|
return false;
|
||
|
}
|
||
|
}
|
||
|
return status.isGranted;
|
||
|
}
|
||
|
|
||
|
Future<String?> downloadMusic({
|
||
|
required String musicUrl,
|
||
|
required String name,
|
||
|
required BuildContext context,
|
||
|
required Function(double) onProgress,
|
||
|
}) async {
|
||
|
try {
|
||
|
// 音频文件后缀列表
|
||
|
final List<String> audioExtensions = [
|
||
|
'.mp3',
|
||
|
'.wav',
|
||
|
'.m4a',
|
||
|
'.aac',
|
||
|
'.ogg',
|
||
|
'.flac',
|
||
|
'.wma',
|
||
|
'.amr'
|
||
|
];
|
||
|
|
||
|
// 检查URL中是否包含音频后缀
|
||
|
String fileExtension = '';
|
||
|
|
||
|
final Uri uri = Uri.parse(musicUrl);
|
||
|
final String pathOnly = uri.path.toLowerCase();
|
||
|
|
||
|
for (var ext in audioExtensions) {
|
||
|
if (pathOnly.contains(ext)) {
|
||
|
fileExtension = ext;
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// 如果找到后缀,添加到文件名
|
||
|
final fileName = fileExtension.isNotEmpty
|
||
|
? name.endsWith(fileExtension) ? name : name + fileExtension
|
||
|
: name;
|
||
|
|
||
|
// 检查并申请权限
|
||
|
if (!await _requestStoragePermission(context)) {
|
||
|
throw Exception('没有存储权限');
|
||
|
}
|
||
|
|
||
|
// 获取下载目录
|
||
|
final downloadDir = Directory('/storage/emulated/0/MTMusic');
|
||
|
if (!await downloadDir.exists()) {
|
||
|
await downloadDir.create(recursive: true);
|
||
|
}
|
||
|
|
||
|
// 构建完整的文件路径
|
||
|
final filePath = '${downloadDir.path}/$fileName';
|
||
|
|
||
|
print("Music URL: $musicUrl");
|
||
|
print("Saving as: $filePath");
|
||
|
|
||
|
// 开始下载
|
||
|
await dio.download(
|
||
|
musicUrl,
|
||
|
filePath,
|
||
|
options: Options(
|
||
|
headers: {
|
||
|
// 如果需要添加请求头可以在这里添加
|
||
|
},
|
||
|
),
|
||
|
onReceiveProgress: (received, total) {
|
||
|
if (total != -1) {
|
||
|
// 计算下载进度并通过回调函数传递
|
||
|
double progress = received / total;
|
||
|
onProgress(progress); // 调用回调函数
|
||
|
}
|
||
|
},
|
||
|
);
|
||
|
|
||
|
return filePath;
|
||
|
} catch (e) {
|
||
|
print('Download error: $e');
|
||
|
return null;
|
||
|
}
|
||
|
}
|
||
|
}
|