downloadFromUrlStream static method
Future<DownloadResult>
downloadFromUrlStream({
- required String url,
- required String filename,
- ProgressCallback? onProgress,
- CompleteCallback? onComplete,
- ErrorCallback? onError,
- bool allowSelfSignedCertificate = false,
Downloads a file from URL using stream method with progress tracking. Works on all platforms and provides better memory efficiency.
Implementation
static Future<DownloadResult> downloadFromUrlStream({
required String url,
required String filename,
ProgressCallback? onProgress,
CompleteCallback? onComplete,
ErrorCallback? onError,
bool allowSelfSignedCertificate = false,
}) async {
try {
// Check storage permission for mobile platforms
if (!kIsWeb && (io.Platform.isAndroid || io.Platform.isIOS)) {
final hasPermission = await PermissionUtils.requestStoragePermission();
if (!hasPermission) {
throw PermissionDownloadException(
PermissionUtils.getPermissionErrorMessage(),
url: url,
);
}
}
// For web platform, use the existing optimized download method
if (kIsWeb) {
return await _downloadForWeb(
url: url,
fileName: filename,
onProgress: onProgress,
onComplete: onComplete,
onError: onError,
);
}
// For native platforms, use stream-based approach
// Create HTTP client
final client = _createHttpClient(allowSelfSignedCertificate);
try {
// Make HTTP request to get stream
final request = http.Request('GET', Uri.parse(url));
request.headers.addAll({
'User-Agent': 'UniversalDownloader/1.0.0 (Flutter Stream)',
'Accept': '*/*',
});
final streamedResponse = await client.send(request);
if (streamedResponse.statusCode != 200) {
throw NetworkDownloadException(
'Failed to download file: HTTP ${streamedResponse.statusCode}',
url: url,
);
}
final totalBytes = streamedResponse.contentLength ?? 0;
var downloadedBytes = 0;
// Convert HTTP stream to Stream<int> and track progress
final streamController = StreamController<int>();
streamedResponse.stream.listen(
(chunk) {
for (final byte in chunk) {
streamController.add(byte);
downloadedBytes++;
}
// Report progress
if (totalBytes > 0 && onProgress != null) {
onProgress(DownloadProgress.fromBytes(
totalBytes: totalBytes,
downloadedBytes: downloadedBytes,
));
}
},
onDone: () {
streamController.close();
},
onError: (error) {
streamController.addError(error);
},
);
// Use downloadStream to save the file
final dir =
await _getDownloadDirectory(false); // Use Downloads directory
final fullPath = path.join(dir.path, filename);
await downloadStream(
stream: streamController.stream,
filename: filename,
);
onComplete?.call(fullPath);
return DownloadResult.success(
filePath: fullPath,
url: url,
fileName: filename,
totalBytes: downloadedBytes,
);
} finally {
client.close();
}
} catch (e) {
final errorMessage = e.toString();
onError?.call(errorMessage);
return DownloadResult.failure(
url: url,
fileName: filename,
errorMessage: errorMessage,
);
}
}