-
Notifications
You must be signed in to change notification settings - Fork 9.8k
Conversation
Thanks for your pull request. It looks like this may be your first contribution to a Google open source project. Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA). 📝 Please visit https://cla.developers.google.com/ to sign. Once you've signed, please reply here (e.g.
|
I signed it! |
CLAs look good, thanks! |
|
||
/// Path to a directory where the application may access top level storage | ||
/// | ||
/// On iOS, This function returns null as it is not possible to access outside |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sentences in comments are missing terminating .
Few typos in iOS sentence, change to:
/// On iOS, this function returns null, as it is not possible to access the
/// file system outside the apps sandbox.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you very much for your interest! :-)
Please update the README.md with this new method and increase the version number (update puspec.yaml and CHANGELOG.md).
Also, it would be great if the example app could display the new method as well.
@@ -40,3 +40,16 @@ const _channel = const MethodChannel('plugins.flutter.io/path_provider'); | |||
return null; | |||
return new Directory(path); | |||
} | |||
|
|||
/// Path to a directory where the application may access top level storage |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please add dot at the end.
|
||
/// Path to a directory where the application may access top level storage | ||
/// | ||
/// On iOS, This function returns null as it is not possible to access outside |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
On iOS, This -> On iOS, this
/// Path to a directory where the application may access top level storage | ||
/// | ||
/// On iOS, This function returns null as it is not possible to access outside | ||
/// the apps sandbox |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Again, a dot at the end of the sentence.
/// On iOS, This function returns null as it is not possible to access outside | ||
/// the apps sandbox | ||
/// | ||
/// On Android this returns getExternalStorageDirectory |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Again a dot at the end of the sentence.
@@ -46,4 +51,8 @@ private String getPathProviderTemporaryDirectory() { | |||
private String getPathProviderApplicationDocumentsDirectory() { | |||
return PathUtils.getDataDirectory(activity); | |||
} | |||
|
|||
private String getPathProviderStorageDirectory() { | |||
return Environment.getExternalStorageDirectory().getAbsolutePath(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What is the use case for this? The documentation for getExternalDirectory() says not to use this directly but instead use getExternalStoragePublicDirectory(String) .
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The use case I had in mind for this was to get the root of the available file system, such that a file browser could be created within an app. I wanted to create a toy audio book app that would allow the user to navigate to a directory and mark it as the location all audio books could be found under. The latter API call you bring up is not quite targeted for this use case, as it expects you to specify what type of media you are interested in (i.e. for finding the location to save pictures). In my case the user may have located their audio books at any place accessible on the external storage.
/// the apps sandbox | ||
/// | ||
/// On Android this returns getExternalStorageDirectory | ||
Future<Directory> getExternalStorageDirectory() async { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
On iOS, this will result in a MissingPluginException since there is no handling of a method with that name. To avoid this, you could check the OS for iOS here and throw a UnsupportedError. Remember to document also, that the OS needs to be determined before calling this method.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I added a check for iOS and documented in the comments above the function
f390673
to
282d8d2
Compare
I have added to the example to make use of this new function, but I unfortunately could not test the example, as it seems to be broken by a change in flutter itself (most likely due to moving this stuff out to stand alone). I followed the structure of the existing example, so I don't expect any issues. I would be happy to look into fixing the example as a new small project. I appreciate you considering this pull request. I am quite new to mobile app development. (I am coming from a background of python/c++ for high performance computing in astrophysics). Flutter is the first framework that has gotten my genuinely interested in the mobile ecosystem. I really like the design choices and am enjoying Dart as a language. I appreciate the opportunity to contribute to this project. |
Also, I don't know the etiquette on this project in regards to cleaning up commits, and commit history in general. Is it advisable to squash the commits down like I did? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We are very happy to get contributions so thanks for taking you time to do so.
Please remember to compile and run the code before submitting. I was able to run the example by fixing the compile errors :-)
If you are not using IntelliJ as your IDE, you could consider it. We recommend using an IntelliJ IDE with Flutter for code completion, inline error checking, and visual debugging features.
You don't need to squash the commits here as you can squash when you merge the PR. Also it makes it much easier to review the changes if you keep separate commits when you address comments. :-)
@@ -105,6 +113,24 @@ class _MyHomePageState extends State<MyHomePage> { | |||
child: new FutureBuilder<Directory>( | |||
future: _appDocumentsDirectory, builder: _buildDirectory), | |||
), | |||
new Cloumn( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Cloumn -> Column
new Cloumn( | ||
children : <Widget>[ | ||
new Padding( | ||
padding: const EdgeInserts.add(16.0), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
EdgeInserts.add(16.0) -> EdgeInsets.all(16.0)
new Padding( | ||
padding: const EdgeInserts.add(16.0), | ||
child: new RaisedButton( | ||
child: const Test('${Platform.operatingSystem != "ios" ? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
const Test -> New Text
You cannot have const here as the expression is not constant.
child: new RaisedButton( | ||
child: const Test('${Platform.operatingSystem != "ios" ? | ||
"Get External Storage Directory" : | ||
"External Directories are unavailable " + |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Directories -> directories
"Get External Storage Directory" : | ||
"External Directories are unavailable " + | ||
"on iOS"}'), | ||
onPressed: _requestExternalStorageDirectory, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let onPressed
be null on iOS. This disables the button.
@@ -65,6 +66,13 @@ class _MyHomePageState extends State<MyHomePage> { | |||
}); | |||
} | |||
|
|||
void _requestExternalStorageDirectory() { | |||
setState(() { | |||
if (Platform.operatingSystem != "ios") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please check the OS with Platform.isIOS
instead, here and below as well.
packages/path-provider/CHANGELOG.md
Outdated
@@ -1,3 +1,7 @@ | |||
## [0.2.1] - 2017-05-11 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Once we reach the final version this date should be updated accordingly.
packages/path-provider/CHANGELOG.md
Outdated
@@ -1,3 +1,7 @@ | |||
## [0.2.1] - 2017-05-11 | |||
|
|||
* Add function to determine external storage directory |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Missing terminating .
/// On Android this returns getExternalStorageDirectory. | ||
Future<Directory> getExternalStorageDirectory() async { | ||
if (Platform.operatingSystem == "ios") | ||
throw new UnimplementedError("Functionality not available on iOS"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please use UnsupportedError
instead.
I have addressed the issues mentioned above (except updating the final date), and rebased my fork onto master. I must say I am actually quite embarrassed at some of the mistakes I had. Previously I had assumed the build failures I was seeing in the platform specific libraries were related to API changes, but it was my own silly bugs causing it to fail. I must spend more time looking over things in the future. You have been quite patient in working with me, and I thank you for that. I am sorry that this has caused so much work for you. I have two commits related to the changes requested, which can be squashed prior to merging in whatever manor you prefer. Please let me know if there is anything else to be done. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM when the empty lines are removed.
import io.flutter.plugin.common.MethodCall; | ||
import io.flutter.plugin.common.MethodChannel; | ||
import io.flutter.plugin.common.MethodChannel.MethodCallHandler; | ||
import io.flutter.plugin.common.MethodChannel.Result; | ||
import io.flutter.plugin.common.PluginRegistry.Registrar; | ||
import io.flutter.util.PathUtils; | ||
|
||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remove empty lines
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should I squash down to one commit?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can use the 'Squash and merge' button, and remove the extra commit messages.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have no write access to the github repository, so I can not actually do the merge myself. I have squashed all the commits on my fork, so it can be merged at any point.
Android supports accessing the "external" storage medium. Support finding this path in flutter with a method call in path_provider
Yup, we will handle the merge. Thanks so much for contributing to Flutter, @natelust ! |
FAILURE: Build failed with an exception. * Where: Build file 'C:\Users\srburton\AppData\Roaming\Pub\Cache\hosted\pub.dartlang.org\shared_preferences_macos-0.0.1+6\android\build.gradle' line: 22 * What went wrong: A problem occurred evaluating root project 'shared_preferences_macos'. > Failed to apply plugin [id 'com.android.library'] > Minimum supported Gradle version is 5.4.1. Current version is 5.1.1. If using the gradle wrapper, try editing the distributionUrl in C:\Users\srburton\AppData\Roaming\Pub\Cache\hosted\pub.dartlang.org\shared_preferences_macos-0.0.1+6\android\gradle\wrapper\gradle-wrapper.properties to gradle-5.4.1-all.zip * Try: Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights. * Get more help at https://help.gradle.org BUILD FAILED in 1s [ +1 ms] Running Gradle task 'assembleAarRelease'... (completed in 2,0s) [ ] FAILURE: Build failed with an exception. * Where: Build file 'C:\Users\srburton\AppData\Roaming\Pub\Cache\hosted\pub.dartlang.org\shared_preferences_macos-0.0.1+6\android\build.gradle' line: 22 * What went wrong: A problem occurred evaluating root project 'shared_preferences_macos'. > Failed to apply plugin [id 'com.android.library'] > Minimum supported Gradle version is 5.4.1. Current version is 5.1.1. If using the gradle wrapper, try editing the distributionUrl in C:\Users\srburton\AppData\Roaming\Pub\Cache\hosted\pub.dartlang.org\shared_preferences_macos-0.0.1+6\android\gradle\wrapper\gradle-wrapper.properties to gradle-5.4.1-all.zip * Try: Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights. * Get more help at https://help.gradle.org BUILD FAILED in 1s [ +5 ms] "flutter apk" took 179.497ms. The plugin shared_preferences_macos could not be built due to the issue above. #0 throwToolExit (package:flutter_tools/src/base/common.dart:28:3) flutter#1 buildPluginsAsAar (package:flutter_tools/src/android/gradle.dart:726:7) flutter#2 _asyncErrorWrapperHelper.<anonymous closure> (dart:async-patch/async_patch.dart:80:45) #3 _rootRunBinary (dart:async/zone.dart:1146:38) flutter#4 _CustomZone.runBinary (dart:async/zone.dart:1039:19) flutter#5 _FutureListener.handleError (dart:async/future_impl.dart:153:20) flutter#6 Future._propagateToListeners.handleError (dart:async/future_impl.dart:692:47) flutter#7 Future._propagateToListeners (dart:async/future_impl.dart:713:24) flutter#8 Future._completeError (dart:async/future_impl.dart:532:5) flutter#9 _AsyncAwaitCompleter.completeError (dart:async-patch/async_patch.dart:38:15) flutter#10 buildGradleAar (package:flutter_tools/src/android/gradle.dart) flutter#11 _asyncThenWrapperHelper.<anonymous closure> (dart:async-patch/async_patch.dart:73:64) flutter#12 _rootRunUnary (dart:async/zone.dart:1134:38) flutter#13 _CustomZone.runUnary (dart:async/zone.dart:1031:19) flutter#14 _FutureListener.handleValue (dart:async/future_impl.dart:139:18) flutter#15 Future._propagateToListeners.handleValueCallback (dart:async/future_impl.dart:680:45) flutter#16 Future._propagateToListeners (dart:async/future_impl.dart:709:32) #17 Future._completeWithValue (dart:async/future_impl.dart:524:5) flutter#18 _AsyncAwaitCompleter.complete (dart:async-patch/async_patch.dart:32:15) flutter#19 _completeOnAsyncReturn (dart:async-patch/async_patch.dart:290:13) flutter#20 _DefaultProcessUtils.run (package:flutter_tools/src/base/process.dart) flutter#21 _asyncThenWrapperHelper.<anonymous closure> (dart:async-patch/async_patch.dart:73:64) flutter#22 _rootRunUnary (dart:async/zone.dart:1134:38) flutter#23 _CustomZone.runUnary (dart:async/zone.dart:1031:19) flutter#24 _FutureListener.handleValue (dart:async/future_impl.dart:139:18) flutter#25 Future._propagateToListeners.handleValueCallback (dart:async/future_impl.dart:680:45) flutter#26 Future._propagateToListeners (dart:async/future_impl.dart:709:32) flutter#27 Future._completeWithValue (dart:async/future_impl.dart:524:5) flutter#28 Future.wait.<anonymous closure> (dart:async/future.dart:400:22) flutter#29 _rootRunUnary (dart:async/zone.dart:1134:38) flutter#30 _CustomZone.runUnary (dart:async/zone.dart:1031:19) flutter#31 _FutureListener.handleValue (dart:async/future_impl.dart:139:18) flutter#32 Future._propagateToListeners.handleValueCallback (dart:async/future_impl.dart:680:45) flutter#33 Future._propagateToListeners (dart:async/future_impl.dart:709:32) flutter#34 Future._completeWithValue (dart:async/future_impl.dart:524:5) flutter#35 Future._asyncComplete.<anonymous closure> (dart:async/future_impl.dart:554:7) flutter#36 _rootRun (dart:async/zone.dart:1126:13) flutter#37 _CustomZone.run (dart:async/zone.dart:1023:19) flutter#38 _CustomZone.runGuarded (dart:async/zone.dart:925:7) flutter#39 _CustomZone.bindCallbackGuarded.<anonymous closure> (dart:async/zone.dart:965:23) flutter#40 _microtaskLoop (dart:async/schedule_microtask.dart:43:21) flutter#41 _startMicrotaskLoop (dart:async/schedule_microtask.dart:52:5) flutter#42 _runPendingImmediateCallback (dart:isolate-patch/isolate_patch.dart:118:13) flutter#43 _RawReceivePortImpl._handleMessage (dart:isolate-patch/isolate_patch.dart:175:5)
[firebase_remote_config] Fix Future already completed RemoteConfig.instance
Android supports accessing the "external" storage medium. Support
finding this path in flutter with a method call in path_provider
I am interested in writing a flutter app that will access some files a user may have put on their device manually (android). This necessitates looking up the path for the external storage. Though I could do the same thing in my own package, I figured it would be more useful to have this functionality in the path provider package so it can be more broadly used. Sadly this functionality is restricted to android only, as iOS does not let you escape the app sandbox. If there is some other mechanism you would prefer me to go through instead of just creating a pull request, please let me know.