-
Notifications
You must be signed in to change notification settings - Fork 9.8k
use temp image file in cacheDir to allow picking from remote resources #513
use temp image file in cacheDir to allow picking from remote resources #513
Conversation
Thanks for your pull request. It looks like this may be your first contribution to a Google open source project (if not, look below for help). 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 (or fixed any issues), please reply here (e.g. What to do if you already signed the CLAIndividual signers
Corporate signers
|
We found a Contributor License Agreement for you (the sender of this pull request), but were unable to find agreements for all the commit author(s) or Co-authors. If you authored these, maybe you used a different email address in the git commits than was used to sign the CLA (login here to double check)? If these were authored by someone else, then they will need to sign a CLA as well, and confirm that they're okay with these being contributed to Google. |
I signed it!
…________________________________
Da: googlebot <notifications@github.com>
Inviato: lunedì 30 aprile 2018 18:50
A: flutter/plugins
Cc: gbaccetta; Author
Oggetto: Re: [flutter/plugins] use temp image file in cacheDir to allow picking from remote resources (#513)
We found a Contributor License Agreement for you (the sender of this pull request), but were unable to find agreements for all the commit author(s) or Co-authors. If you authored these, maybe you used a different email address in the git commits than was used to sign the CLA (login here<https://cla.developers.google.com/> to double check)? If these were authored by someone else, then they will need to sign a CLA as well, and confirm that they're okay with these being contributed to Google.
In order to pass this check, please resolve this problem and have the pull request author add another comment and the bot will run again. If the bot doesn't comment, it means it doesn't think anything has changed.
—
You are receiving this because you authored the thread.
Reply to this email directly, view it on GitHub<#513 (comment)>, or mute the thread<https://github.com/notifications/unsubscribe-auth/ANXrKigEKAWGStsDCnYugJ4sUqdLie1mks5tt0DigaJpZM4Tsj7s>.
|
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.
Thanks for the contribution!
try { | ||
InputStream inputStream = null; | ||
OutputStream output = null; | ||
try { |
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 try-with-resources. It is too hard to get this code correct without.
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.
isn't resource management only for API 19+ and flutter for 16+ ?
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 are right, sorry. In that case, you need to wrap your calls to close
in try-catch blocks. Otherwise we risk not actually closing the input stream, as well as exiting abnormally from a finally block.
OutputStream output = null; | ||
try { | ||
inputStream = activity.getContentResolver().openInputStream(data.getData()); | ||
File file = new File(activity.getCacheDir(), "cachedImage.jpg"); |
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 if that file already exists?
When is the file cleaned up?
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 guessed that for the cleaning since it is the cacheDir and I was trying to always use the same file name that was ok. In that sense imageResizer is even worse since it create a scaled image version in the external directory where the original file is, leaving the user with two copies of it. However you are right about the file already existing
File file = new File(activity.getCacheDir(), "cachedImage.jpg"); | ||
output = new FileOutputStream(file); | ||
if (inputStream != null) { | ||
byte[] buffer = new byte[4 * 1024]; // or other buffer size |
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 avoid comments that convey only uncertainty. There is nothing inherently wrong with a 4K buffer.
@@ -300,8 +304,36 @@ public boolean onActivityResult(int requestCode, int resultCode, Intent data) { | |||
|
|||
private void handleChoosePictureResult(int resultCode, Intent data) { | |||
if (resultCode == Activity.RESULT_OK && data != null) { | |||
String path = fileUtils.getPathFromUri(activity, data.getData()); | |||
handleResult(path); | |||
//String path = fileUtils.getPathFromUri(activity, data.getData()); |
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 remove unneeded code rather than put it in a comment.
If FileUtils
is no longer used by the plugin, it should be removed as well.
handleResult(path); | ||
//String path = fileUtils.getPathFromUri(activity, data.getData()); | ||
|
||
//creating a temp file from uri to allow reading pictures from remote sources |
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.
And if it isn't remote, do we then copy the file needlessly?
Please format comments as whole sentences:
// Create a temporary file from ...
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.
Well we can keep using FileUtils for local path and create temporary file only for remoteResources when path is null in the same way as done for the camera intent
The commit appears to have been made using a different author name or email than that used for CLA signing. You probably have to amend your commit. |
@mravn-google @gbaccetta This PR breaks two tests (found in There's no CI integration for running these tests just yet; @goderbauer requested me to modify the Travis script in this comment in #461. I haven't had time to look into it, and honestly have no idea how to do / test it. (The tests can be run from the command line by running |
a9a10d4
to
036ccdf
Compare
CLAs look good, thanks! |
@roughike Travis ran the image_picker java tests on this PR and they're still passing. Is that unexpected? |
@goderbauer Java tests should now pass. The Java tests failed when there was only the first commit, So everything is working as expected! |
@gbaccetta Does this by any chance also fix flutter/flutter#17165? |
@goderbauer yes it fix also that problem, that's why I looked for this solution. For the formating problem I could not change my Android studio indentention from 4 to 2 characters... sorry about that |
ok, I should have fixed the formatting in last commit |
@gbaccetta You can format all Dart, Java and Objective C files by running See here: https://github.com/flutter/plugins/blob/master/CONTRIBUTING.md |
41f091f
to
36be00c
Compare
Check still failed even after correcting the format. Could not understand why this time. I'm sorry this is the first time I 'm trying to contribute to Google Open Source. @roughike that command for me fails with this from the plugin directory:
and with this from the root directory:
|
No worries! Let's say you have cloned this repo in cd Documents
cd my-github-contributions
cd plugins # this is the directory you want to be in
# Now we're inside the correct directory, so we can use the plugin tools.
pub global run flutter_plugin_tools format |
handleResult(path); | ||
//Path may be null if, for example, source is remote. | ||
if (path == null) { | ||
InputStream inputStream = null; |
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.
Just a drive-by comment: I would at least extract this logic into a separate method (called getRemotePathFromUri()
for example) to make the code a bit clearer.
Maybe even move this logic to FileUtils
class if we go crazy. If the Uri
has a distinctive scheme
or authority
, it could be added as an else if
at Line 90 in the FileUtils class.
Something like:
FileUtils.java (starting from line 90)
...
} else if (isRemoteFile(uri)) {
// Move the logic for getting remote path from the uri here.
// Then return the resolved path.
}
...
Disclaimer: I'm not in the Flutter team and you can just ignore this feedback if you want. ¯\(ツ)/¯
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.
Problem is the authority is not distintive.
For example local file from google photos has the same authority then remote file.
However the local file path is correctly retrieved but not the remote.
That's why I used the logic as a fallback cause this always works but need to create a temp file... Hence the idea was to say: let's try to retrieve the path in every manner we may know of and fallback to inputstream and tempFile if those methods fail. It allows to keep the plugin to work even if a provider change its distintive authority
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.
Problem is the authority is not distinctive.
How about the scheme
then?
If not, I would still personally move the logic to FileUtils
. In the very end of the getPathFromUri
method, we could return the path from remote Uri
if it can be resolved. If not, then just return null like it currently does.
OutputStream outputStream = null; | ||
try { | ||
inputStream = activity.getContentResolver().openInputStream(data.getData()); | ||
File file = File.createTempFile("cachedImage", "jpg", activity.getCacheDir()); |
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.
Just thinking if cachedImage.jpg
is a too generic name for an image to be stored in a cache directory. There could be a chance we're overwriting some other image by accident. Would it make sense to use something less common, like flutter_image_picker_cached_remote_image.jpg
for example?
UUIDs would be another option, but that could blow up the application's cache directory over time since images can get quite big. This might potentially give end users a bad impression of the app that uses this plugin.
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.
@roughike normay using createTempFile automatic append a random numeric string to the end of the name so that files will be "cachedImage-123456789.jpg" or something similar. I did not find of a nice way of automatically deleting the file created in the cacheDir
CLAs look good, thanks! |
@@ -63,7 +63,7 @@ | |||
* <p>C) User cancels picking an image. Finish with null result. | |||
*/ | |||
public class ImagePickerDelegate | |||
implements PluginRegistry.ActivityResultListener, | |||
implements PluginRegistry.ActivityResultListener, |
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.
These white space changes seem to be at odds with our CI's formatting requirements. Please revert.
outputStream.write(buffer, 0, read); | ||
} | ||
outputStream.flush(); | ||
return file.getPath(); |
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 returning a file path here even if there are exceptions thrown while closing the streams. We should only return a file path if all the I/O completes normally.
String getPathFromUri(final Context context, final Uri uri) { | ||
//Try to retrieve path on device |
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.
These comments add little value; the code already speaks for itself.
8ab48f3
to
d7bbf7f
Compare
We found a Contributor License Agreement for you (the sender of this pull request), but were unable to find agreements for all the commit author(s) or Co-authors. If you authored these, maybe you used a different email address in the git commits than was used to sign the CLA (login here to double check)? If these were authored by someone else, then they will need to sign a CLA as well, and confirm that they're okay with these being contributed to Google. |
9fe8c24
to
fbdd8c7
Compare
CLAs look good, thanks! |
…e, rebase into master and logic moved to FileUtils)
fbdd8c7
to
38ea750
Compare
Finally starting from scratch ( new branch from actual master + force push to clean all the mess) seems to have worked. Anyway formatting is really hard to achieve since |
@gbaccetta Do you want to work on the last review comment, or would you prefer us taking it from here? |
@mravn-google you can take over. However, as I see it, in case of exception the code return null and not the filePath. Unless I missinterpreted something |
@gbaccetta Thanks, I'll make a small tweak in a separate PR and then publish. |
Somebody please find a fix to the problem which is making the app crash if we choose an image using image_picker from google photos but works totally fine if the image is picked from the local gallery. I am in dire need for the solution. |
@SkullEnemyX I believe this PR is exactly that fix. |
I am unable to understand what to do exactly as the method is not clear (PS: I am a beginner in app development and flutter) |
That's fine! As far as I understand, a fix for your crash with Google Photos was just merged in this pull request. Is the problem still surfacing with version |
@gbaccetta @goderbauer @roughike @mravn-google This issue is completely not fixed, it still does exist, Guess is happening in Oreo and above(Pie). App just crashes when uploading images and it never displays the image too. |
imagePicker caused flutter app to crash when picking image from a remote source.
Using a temp file to store the inputStream obtained from the content provider solve the problem.
It actually use a temp file in the cachedDir named cachedImage.jpg.