From e7d812cefce083fa09762d25cd42303737d05b9f Mon Sep 17 00:00:00 2001 From: Talha Javed Khan <50271102+talhakhan1297@users.noreply.github.com> Date: Wed, 30 Aug 2023 23:10:59 +0500 Subject: [PATCH] [path_provider] Fix93198: Added getDownloadsDirectory() for Android (#4708) This PR adds the Android implementation for the getDownloadsDirectory() function by making getDownloadsDirectory redirect at the Dart level to getExternalStorageDirectories with the downloads directory constant. *List which issues are fixed by this PR. You must list at least one issue.* Fixes [#93198](https://github.com/flutter/flutter/issues/93198) --- .../path_provider_android/CHANGELOG.md | 4 +++ .../example/lib/main.dart | 16 +++++++++++ .../lib/path_provider_android.dart | 16 ++++++++--- .../path_provider_android/pubspec.yaml | 2 +- .../test/path_provider_android_test.dart | 28 +++++++++++++------ 5 files changed, 52 insertions(+), 14 deletions(-) diff --git a/packages/path_provider/path_provider_android/CHANGELOG.md b/packages/path_provider/path_provider_android/CHANGELOG.md index 5cb76a9e7675..407f1504d697 100644 --- a/packages/path_provider/path_provider_android/CHANGELOG.md +++ b/packages/path_provider/path_provider_android/CHANGELOG.md @@ -1,3 +1,7 @@ +## 2.2.0 + +* Adds implementation of `getDownloadsDirectory()`. + ## 2.1.1 * Adds pub topics to package metadata. diff --git a/packages/path_provider/path_provider_android/example/lib/main.dart b/packages/path_provider/path_provider_android/example/lib/main.dart index 79293e155c01..29ce6f191550 100644 --- a/packages/path_provider/path_provider_android/example/lib/main.dart +++ b/packages/path_provider/path_provider_android/example/lib/main.dart @@ -41,6 +41,7 @@ class _MyHomePageState extends State { Future? _appDocumentsDirectory; Future? _appCacheDirectory; Future? _externalDocumentsDirectory; + Future? _externalDownloadsDirectory; Future?>? _externalStorageDirectories; Future?>? _externalCacheDirectories; @@ -118,6 +119,12 @@ class _MyHomePageState extends State { }); } + void _requestDownloadsDirectory() { + setState(() { + _externalDownloadsDirectory = provider.getDownloadsPath(); + }); + } + @override Widget build(BuildContext context) { return Scaffold( @@ -199,6 +206,15 @@ class _MyHomePageState extends State { ]), FutureBuilder?>( future: _externalCacheDirectories, builder: _buildDirectories), + Padding( + padding: const EdgeInsets.all(16.0), + child: ElevatedButton( + onPressed: _requestDownloadsDirectory, + child: const Text('Get Downloads Directory'), + ), + ), + FutureBuilder( + future: _externalDownloadsDirectory, builder: _buildDirectory), ], ), ), diff --git a/packages/path_provider/path_provider_android/lib/path_provider_android.dart b/packages/path_provider/path_provider_android/lib/path_provider_android.dart index c65b0abc30b9..20effb2f3c29 100644 --- a/packages/path_provider/path_provider_android/lib/path_provider_android.dart +++ b/packages/path_provider/path_provider_android/lib/path_provider_android.dart @@ -81,12 +81,20 @@ class PathProviderAndroid extends PathProviderPlatform { Future?> getExternalStoragePaths({ StorageDirectory? type, }) async { - return (await _api.getExternalStoragePaths(_convertStorageDirectory(type))) - .cast(); + return _getExternalStoragePaths(type: type); } @override - Future getDownloadsPath() { - throw UnsupportedError('getDownloadsPath is not supported on Android'); + Future getDownloadsPath() async { + final List paths = + await _getExternalStoragePaths(type: StorageDirectory.downloads); + return paths.isEmpty ? null : paths.first; + } + + Future> _getExternalStoragePaths({ + StorageDirectory? type, + }) async { + return (await _api.getExternalStoragePaths(_convertStorageDirectory(type))) + .cast(); } } diff --git a/packages/path_provider/path_provider_android/pubspec.yaml b/packages/path_provider/path_provider_android/pubspec.yaml index cc55cb471aba..1e8a84919896 100644 --- a/packages/path_provider/path_provider_android/pubspec.yaml +++ b/packages/path_provider/path_provider_android/pubspec.yaml @@ -2,7 +2,7 @@ name: path_provider_android description: Android implementation of the path_provider plugin. repository: https://github.com/flutter/packages/tree/main/packages/path_provider/path_provider_android issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+path_provider%22 -version: 2.1.1 +version: 2.2.0 environment: sdk: ">=2.19.0 <4.0.0" diff --git a/packages/path_provider/path_provider_android/test/path_provider_android_test.dart b/packages/path_provider/path_provider_android/test/path_provider_android_test.dart index 5f94da6c4f3c..6d31a3cd6e50 100644 --- a/packages/path_provider/path_provider_android/test/path_provider_android_test.dart +++ b/packages/path_provider/path_provider_android/test/path_provider_android_test.dart @@ -18,6 +18,10 @@ const String kExternalStoragePaths = 'externalStoragePaths'; const String kDownloadsPath = 'downloadsPath'; class _Api implements TestPathProviderApi { + _Api({this.returnsExternalStoragePaths = true}); + + final bool returnsExternalStoragePaths; + @override String? getApplicationDocumentsPath() => kApplicationDocumentsPath; @@ -34,8 +38,9 @@ class _Api implements TestPathProviderApi { String? getExternalStoragePath() => kExternalStoragePaths; @override - List getExternalStoragePaths(messages.StorageDirectory directory) => - [kExternalStoragePaths]; + List getExternalStoragePaths(messages.StorageDirectory directory) { + return [if (returnsExternalStoragePaths) kExternalStoragePaths]; + } @override String? getTemporaryPath() => kTemporaryPath; @@ -98,13 +103,18 @@ void main() { }); } // end of for-loop - test('getDownloadsPath fails', () async { - try { - await pathProvider.getDownloadsPath(); - fail('should throw UnsupportedError'); - } catch (e) { - expect(e, isUnsupportedError); - } + test('getDownloadsPath succeeds', () async { + final String? path = await pathProvider.getDownloadsPath(); + expect(path, kExternalStoragePaths); + }); + + test( + 'getDownloadsPath returns null, when getExternalStoragePaths returns ' + 'an empty list', () async { + final PathProviderAndroid pathProvider = PathProviderAndroid(); + TestPathProviderApi.setup(_Api(returnsExternalStoragePaths: false)); + final String? path = await pathProvider.getDownloadsPath(); + expect(path, null); }); }); }