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 _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: [ 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 downloadMusic({ required String musicUrl, required String name, required BuildContext context, required Function(double) onProgress, }) async { try { // 音频文件后缀列表 final List 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; } } }