Skip to content

Commit e7d812c

Browse files
[path_provider] Fix93198: Added getDownloadsDirectory() for Android (flutter#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](flutter/flutter#93198)
1 parent 1f208aa commit e7d812c

File tree

5 files changed

+52
-14
lines changed

5 files changed

+52
-14
lines changed

packages/path_provider/path_provider_android/CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
## 2.2.0
2+
3+
* Adds implementation of `getDownloadsDirectory()`.
4+
15
## 2.1.1
26

37
* Adds pub topics to package metadata.

packages/path_provider/path_provider_android/example/lib/main.dart

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ class _MyHomePageState extends State<MyHomePage> {
4141
Future<String?>? _appDocumentsDirectory;
4242
Future<String?>? _appCacheDirectory;
4343
Future<String?>? _externalDocumentsDirectory;
44+
Future<String?>? _externalDownloadsDirectory;
4445
Future<List<String>?>? _externalStorageDirectories;
4546
Future<List<String>?>? _externalCacheDirectories;
4647

@@ -118,6 +119,12 @@ class _MyHomePageState extends State<MyHomePage> {
118119
});
119120
}
120121

122+
void _requestDownloadsDirectory() {
123+
setState(() {
124+
_externalDownloadsDirectory = provider.getDownloadsPath();
125+
});
126+
}
127+
121128
@override
122129
Widget build(BuildContext context) {
123130
return Scaffold(
@@ -199,6 +206,15 @@ class _MyHomePageState extends State<MyHomePage> {
199206
]),
200207
FutureBuilder<List<String>?>(
201208
future: _externalCacheDirectories, builder: _buildDirectories),
209+
Padding(
210+
padding: const EdgeInsets.all(16.0),
211+
child: ElevatedButton(
212+
onPressed: _requestDownloadsDirectory,
213+
child: const Text('Get Downloads Directory'),
214+
),
215+
),
216+
FutureBuilder<String?>(
217+
future: _externalDownloadsDirectory, builder: _buildDirectory),
202218
],
203219
),
204220
),

packages/path_provider/path_provider_android/lib/path_provider_android.dart

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -81,12 +81,20 @@ class PathProviderAndroid extends PathProviderPlatform {
8181
Future<List<String>?> getExternalStoragePaths({
8282
StorageDirectory? type,
8383
}) async {
84-
return (await _api.getExternalStoragePaths(_convertStorageDirectory(type)))
85-
.cast<String>();
84+
return _getExternalStoragePaths(type: type);
8685
}
8786

8887
@override
89-
Future<String?> getDownloadsPath() {
90-
throw UnsupportedError('getDownloadsPath is not supported on Android');
88+
Future<String?> getDownloadsPath() async {
89+
final List<String> paths =
90+
await _getExternalStoragePaths(type: StorageDirectory.downloads);
91+
return paths.isEmpty ? null : paths.first;
92+
}
93+
94+
Future<List<String>> _getExternalStoragePaths({
95+
StorageDirectory? type,
96+
}) async {
97+
return (await _api.getExternalStoragePaths(_convertStorageDirectory(type)))
98+
.cast<String>();
9199
}
92100
}

packages/path_provider/path_provider_android/pubspec.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ name: path_provider_android
22
description: Android implementation of the path_provider plugin.
33
repository: https://github.com/flutter/packages/tree/main/packages/path_provider/path_provider_android
44
issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+path_provider%22
5-
version: 2.1.1
5+
version: 2.2.0
66

77
environment:
88
sdk: ">=2.19.0 <4.0.0"

packages/path_provider/path_provider_android/test/path_provider_android_test.dart

Lines changed: 19 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,10 @@ const String kExternalStoragePaths = 'externalStoragePaths';
1818
const String kDownloadsPath = 'downloadsPath';
1919

2020
class _Api implements TestPathProviderApi {
21+
_Api({this.returnsExternalStoragePaths = true});
22+
23+
final bool returnsExternalStoragePaths;
24+
2125
@override
2226
String? getApplicationDocumentsPath() => kApplicationDocumentsPath;
2327

@@ -34,8 +38,9 @@ class _Api implements TestPathProviderApi {
3438
String? getExternalStoragePath() => kExternalStoragePaths;
3539

3640
@override
37-
List<String?> getExternalStoragePaths(messages.StorageDirectory directory) =>
38-
<String>[kExternalStoragePaths];
41+
List<String?> getExternalStoragePaths(messages.StorageDirectory directory) {
42+
return <String?>[if (returnsExternalStoragePaths) kExternalStoragePaths];
43+
}
3944

4045
@override
4146
String? getTemporaryPath() => kTemporaryPath;
@@ -98,13 +103,18 @@ void main() {
98103
});
99104
} // end of for-loop
100105

101-
test('getDownloadsPath fails', () async {
102-
try {
103-
await pathProvider.getDownloadsPath();
104-
fail('should throw UnsupportedError');
105-
} catch (e) {
106-
expect(e, isUnsupportedError);
107-
}
106+
test('getDownloadsPath succeeds', () async {
107+
final String? path = await pathProvider.getDownloadsPath();
108+
expect(path, kExternalStoragePaths);
109+
});
110+
111+
test(
112+
'getDownloadsPath returns null, when getExternalStoragePaths returns '
113+
'an empty list', () async {
114+
final PathProviderAndroid pathProvider = PathProviderAndroid();
115+
TestPathProviderApi.setup(_Api(returnsExternalStoragePaths: false));
116+
final String? path = await pathProvider.getDownloadsPath();
117+
expect(path, null);
108118
});
109119
});
110120
}

0 commit comments

Comments
 (0)