fix: saf download
This commit is contained in:
@@ -556,6 +556,7 @@ class DownloadStorageService {
|
||||
|
||||
/// Copy a file from temp cache to SAF and return the SAF URI
|
||||
/// Returns null if SAF is not available or copy fails
|
||||
/// Always cleans up temp file regardless of success/failure
|
||||
Future<String?> copyToSaf(
|
||||
String tempFilePath,
|
||||
List<String> pathComponents,
|
||||
@@ -566,34 +567,37 @@ class DownloadStorageService {
|
||||
|
||||
final safService = SafStorageService.instance;
|
||||
|
||||
// Create nested directory structure in SAF
|
||||
final targetDirUri = await safService.createNestedDirectories(
|
||||
_customDownloadPath!,
|
||||
pathComponents,
|
||||
);
|
||||
try {
|
||||
// Create nested directory structure in SAF
|
||||
final targetDirUri = await safService.createNestedDirectories(
|
||||
_customDownloadPath!,
|
||||
pathComponents,
|
||||
);
|
||||
|
||||
if (targetDirUri == null) {
|
||||
return null;
|
||||
}
|
||||
if (targetDirUri == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Copy the file to SAF
|
||||
final safUri = await safService.copyFileToSaf(
|
||||
tempFilePath,
|
||||
targetDirUri,
|
||||
fileName,
|
||||
mimeType,
|
||||
);
|
||||
// Copy the file to SAF using native copy
|
||||
final safUri = await safService.copyFileToSaf(
|
||||
tempFilePath,
|
||||
targetDirUri,
|
||||
fileName,
|
||||
mimeType,
|
||||
);
|
||||
|
||||
// Delete temp file after successful copy
|
||||
if (safUri != null) {
|
||||
return safUri;
|
||||
} finally {
|
||||
// Always clean up temp file regardless of success/failure
|
||||
try {
|
||||
await File(tempFilePath).delete();
|
||||
final tempFile = File(tempFilePath);
|
||||
if (await tempFile.exists()) {
|
||||
await tempFile.delete();
|
||||
}
|
||||
} catch (_) {
|
||||
// Ignore cleanup errors
|
||||
}
|
||||
}
|
||||
|
||||
return safUri;
|
||||
}
|
||||
|
||||
/// Get the MIME type for a file extension
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import 'dart:async';
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:flutter/foundation.dart';
|
||||
@@ -138,7 +139,7 @@ class SafStorageService {
|
||||
}
|
||||
}
|
||||
|
||||
/// Copy a file from local storage to SAF directory using streaming
|
||||
/// Copy a file from local storage to SAF directory using native copy
|
||||
/// Returns the SAF URI of the copied file, or null on failure
|
||||
Future<String?> copyFileToSaf(
|
||||
String sourceFilePath,
|
||||
@@ -147,6 +148,7 @@ class SafStorageService {
|
||||
String mimeType,
|
||||
) async {
|
||||
if (!isAvailable) return null;
|
||||
|
||||
try {
|
||||
final sourceFile = File(sourceFilePath);
|
||||
if (!await sourceFile.exists()) {
|
||||
@@ -154,27 +156,26 @@ class SafStorageService {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Start a write stream session
|
||||
final writeInfo = await _safStream.startWriteStream(
|
||||
targetDirectoryUri,
|
||||
fileName,
|
||||
mimeType,
|
||||
);
|
||||
final sessionId = writeInfo.session;
|
||||
// Use pasteLocalFile for native-side copy (no method channel streaming)
|
||||
// This is much more efficient for large files and avoids hangs
|
||||
final result = await _safStream
|
||||
.pasteLocalFile(
|
||||
sourceFilePath,
|
||||
targetDirectoryUri,
|
||||
fileName,
|
||||
mimeType,
|
||||
overwrite: true,
|
||||
)
|
||||
.timeout(
|
||||
const Duration(minutes: 30),
|
||||
onTimeout: () => throw TimeoutException('SAF copy timed out'),
|
||||
);
|
||||
|
||||
final stream = sourceFile.openRead();
|
||||
|
||||
await for (final chunk in stream) {
|
||||
await _safStream.writeChunk(sessionId, Uint8List.fromList(chunk));
|
||||
}
|
||||
|
||||
// End the write stream
|
||||
await _safStream.endWriteStream(sessionId);
|
||||
|
||||
debugPrint(
|
||||
'SAF copyFileToSaf: successfully copied to $targetDirectoryUri/$fileName',
|
||||
);
|
||||
return writeInfo.fileResult.uri.toString();
|
||||
debugPrint('SAF copyFileToSaf: successfully copied to ${result.uri}');
|
||||
return result.uri.toString();
|
||||
} on TimeoutException catch (e) {
|
||||
debugPrint('SAF copyFileToSaf timeout: $e');
|
||||
return null;
|
||||
} catch (e) {
|
||||
debugPrint('SAF copyFileToSaf error: $e');
|
||||
return null;
|
||||
|
||||
Reference in New Issue
Block a user