[image_picker] Handle all images through URI (#2728)

diff --git a/packages/image_picker/image_picker/CHANGELOG.md b/packages/image_picker/image_picker/CHANGELOG.md
index 15516ca..66264e7 100644
--- a/packages/image_picker/image_picker/CHANGELOG.md
+++ b/packages/image_picker/image_picker/CHANGELOG.md
@@ -1,3 +1,7 @@
+## 0.6.6+1
+
+* Android: always use URI to get image/video data.
+
 ## 0.6.6
 
 * Use the new platform_interface package.
diff --git a/packages/image_picker/image_picker/android/src/main/java/io/flutter/plugins/imagepicker/FileUtils.java b/packages/image_picker/image_picker/android/src/main/java/io/flutter/plugins/imagepicker/FileUtils.java
index a8ca394..9ebf1fa 100644
--- a/packages/image_picker/image_picker/android/src/main/java/io/flutter/plugins/imagepicker/FileUtils.java
+++ b/packages/image_picker/image_picker/android/src/main/java/io/flutter/plugins/imagepicker/FileUtils.java
@@ -23,16 +23,8 @@
 
 package io.flutter.plugins.imagepicker;
 
-import android.annotation.SuppressLint;
-import android.content.ContentUris;
 import android.content.Context;
-import android.database.Cursor;
 import android.net.Uri;
-import android.os.Build;
-import android.os.Environment;
-import android.provider.DocumentsContract;
-import android.provider.MediaStore;
-import android.text.TextUtils;
 import java.io.File;
 import java.io.FileOutputStream;
 import java.io.IOException;
@@ -42,103 +34,6 @@
 class FileUtils {
 
   String getPathFromUri(final Context context, final Uri uri) {
-    String path = getPathFromLocalUri(context, uri);
-    if (path == null) {
-      path = getPathFromRemoteUri(context, uri);
-    }
-    return path;
-  }
-
-  @SuppressLint("NewApi")
-  private String getPathFromLocalUri(final Context context, final Uri uri) {
-    final boolean isKitKat = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT;
-
-    if (isKitKat && DocumentsContract.isDocumentUri(context, uri)) {
-      if (isExternalStorageDocument(uri)) {
-        final String docId = DocumentsContract.getDocumentId(uri);
-        final String[] split = docId.split(":");
-        final String type = split[0];
-
-        if ("primary".equalsIgnoreCase(type)) {
-          return Environment.getExternalStorageDirectory() + "/" + split[1];
-        }
-      } else if (isDownloadsDocument(uri)) {
-        final String id = DocumentsContract.getDocumentId(uri);
-
-        if (!TextUtils.isEmpty(id)) {
-          try {
-            final Uri contentUri =
-                ContentUris.withAppendedId(
-                    Uri.parse(Environment.DIRECTORY_DOWNLOADS), Long.valueOf(id));
-            return getDataColumn(context, contentUri, null, null);
-          } catch (NumberFormatException e) {
-            return null;
-          }
-        }
-
-      } else if (isMediaDocument(uri)) {
-        final String docId = DocumentsContract.getDocumentId(uri);
-        final String[] split = docId.split(":");
-        final String type = split[0];
-
-        Uri contentUri = null;
-        if ("image".equals(type)) {
-          contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
-        } else if ("video".equals(type)) {
-          contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
-        } else if ("audio".equals(type)) {
-          contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
-        }
-
-        final String selection = "_id=?";
-        final String[] selectionArgs = new String[] {split[1]};
-
-        return getDataColumn(context, contentUri, selection, selectionArgs);
-      }
-    } else if ("content".equalsIgnoreCase(uri.getScheme())) {
-
-      // Return the remote address
-      if (isGooglePhotosUri(uri)) {
-        return null;
-      }
-
-      return getDataColumn(context, uri, null, null);
-    } else if ("file".equalsIgnoreCase(uri.getScheme())) {
-      return uri.getPath();
-    }
-
-    return null;
-  }
-
-  private static String getDataColumn(
-      Context context, Uri uri, String selection, String[] selectionArgs) {
-    Cursor cursor = null;
-
-    final String column = "_data";
-    final String[] projection = {column};
-
-    try {
-      cursor = context.getContentResolver().query(uri, projection, selection, selectionArgs, null);
-      if (cursor != null && cursor.moveToFirst()) {
-        final int column_index = cursor.getColumnIndex(column);
-
-        //yandex.disk and dropbox do not have _data column
-        if (column_index == -1) {
-          return null;
-        }
-
-        return cursor.getString(column_index);
-      }
-    } finally {
-      if (cursor != null) {
-        cursor.close();
-      }
-    }
-    return null;
-  }
-
-  private static String getPathFromRemoteUri(final Context context, final Uri uri) {
-    // The code below is why Java now has try-with-resources and the Files utility.
     File file = null;
     InputStream inputStream = null;
     OutputStream outputStream = null;
@@ -147,6 +42,7 @@
       String extension = getImageExtension(uri);
       inputStream = context.getContentResolver().openInputStream(uri);
       file = File.createTempFile("image_picker", extension, context.getCacheDir());
+      file.deleteOnExit();
       outputStream = new FileOutputStream(file);
       if (inputStream != null) {
         copy(inputStream, outputStream);
@@ -199,20 +95,4 @@
     }
     out.flush();
   }
-
-  private static boolean isExternalStorageDocument(Uri uri) {
-    return "com.android.externalstorage.documents".equals(uri.getAuthority());
-  }
-
-  private static boolean isDownloadsDocument(Uri uri) {
-    return "com.android.providers.downloads.documents".equals(uri.getAuthority());
-  }
-
-  private static boolean isMediaDocument(Uri uri) {
-    return "com.android.providers.media.documents".equals(uri.getAuthority());
-  }
-
-  private static boolean isGooglePhotosUri(Uri uri) {
-    return "com.google.android.apps.photos.contentprovider".equals(uri.getAuthority());
-  }
 }
diff --git a/packages/image_picker/image_picker/example/android/app/build.gradle b/packages/image_picker/image_picker/example/android/app/build.gradle
index 600200b..f4b1e02 100755
--- a/packages/image_picker/image_picker/example/android/app/build.gradle
+++ b/packages/image_picker/image_picker/example/android/app/build.gradle
@@ -63,5 +63,6 @@
     testImplementation 'org.mockito:mockito-core:2.17.0'
     androidTestImplementation 'androidx.test:runner:1.1.1'
     androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.1'
+    testImplementation 'androidx.test:core:1.2.0'
     testImplementation "org.robolectric:robolectric:4.3.1"
 }
diff --git a/packages/image_picker/image_picker/example/android/app/src/test/java/io/flutter/plugins/imagepicker/FileUtilTest.java b/packages/image_picker/image_picker/example/android/app/src/test/java/io/flutter/plugins/imagepicker/FileUtilTest.java
new file mode 100644
index 0000000..c9fa338
--- /dev/null
+++ b/packages/image_picker/image_picker/example/android/app/src/test/java/io/flutter/plugins/imagepicker/FileUtilTest.java
@@ -0,0 +1,57 @@
+// Copyright 2019 The Flutter Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package io.flutter.plugins.imagepicker;
+
+import static java.nio.charset.StandardCharsets.UTF_8;
+import static org.junit.Assert.assertTrue;
+import static org.robolectric.Shadows.shadowOf;
+
+import android.content.Context;
+import android.net.Uri;
+import androidx.test.core.app.ApplicationProvider;
+import java.io.BufferedInputStream;
+import java.io.ByteArrayInputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.RobolectricTestRunner;
+import org.robolectric.shadows.ShadowContentResolver;
+
+@RunWith(RobolectricTestRunner.class)
+public class FileUtilTest {
+
+  private Context context;
+  private FileUtils fileUtils;
+  ShadowContentResolver shadowContentResolver;
+
+  @Before
+  public void before() {
+    context = ApplicationProvider.getApplicationContext();
+    shadowContentResolver = shadowOf(context.getContentResolver());
+    fileUtils = new FileUtils();
+  }
+
+  @Test
+  public void FileUtil_GetPathFromUri() throws IOException {
+    Uri uri = Uri.parse("content://dummy/dummy.png");
+    shadowContentResolver.registerInputStream(
+        uri, new ByteArrayInputStream("imageStream".getBytes(UTF_8)));
+    String path = fileUtils.getPathFromUri(context, uri);
+    File file = new File(path);
+    int size = (int) file.length();
+    byte[] bytes = new byte[size];
+
+    BufferedInputStream buf = new BufferedInputStream(new FileInputStream(file));
+    buf.read(bytes, 0, bytes.length);
+    buf.close();
+
+    assertTrue(bytes.length > 0);
+    String imageStream = new String(bytes, UTF_8);
+    assertTrue(imageStream.equals("imageStream"));
+  }
+}
diff --git a/packages/image_picker/image_picker/lib/image_picker.dart b/packages/image_picker/image_picker/lib/image_picker.dart
index 114e5a4..0dd9cac 100755
--- a/packages/image_picker/image_picker/lib/image_picker.dart
+++ b/packages/image_picker/image_picker/lib/image_picker.dart
@@ -27,6 +27,8 @@
 
   /// Returns a [File] object pointing to the image that was picked.
   ///
+  /// The returned [File] is intended to be used within a single APP session. Do not save the file path and use it across sessions.
+  ///
   /// The `source` argument controls where the image comes from. This can
   /// be either [ImageSource.camera] or [ImageSource.gallery].
   ///
@@ -39,7 +41,6 @@
   /// image types such as JPEG. If compression is not supported for the image that is picked,
   /// an warning message will be logged.
   ///
-  ///
   /// Use `preferredCameraDevice` to specify the camera to use when the `source` is [ImageSource.camera].
   /// The `preferredCameraDevice` is ignored when `source` is [ImageSource.gallery]. It is also ignored if the chosen camera is not supported on the device.
   /// Defaults to [CameraDevice.rear].
@@ -65,6 +66,8 @@
 
   /// Returns a [File] object pointing to the video that was picked.
   ///
+  /// The returned [File] is intended to be used within a single APP session. Do not save the file path and use it across sessions.
+  ///
   /// The [source] argument controls where the video comes from. This can
   /// be either [ImageSource.camera] or [ImageSource.gallery].
   ///
diff --git a/packages/image_picker/image_picker/pubspec.yaml b/packages/image_picker/image_picker/pubspec.yaml
index 8f7ed44..48b781a 100755
--- a/packages/image_picker/image_picker/pubspec.yaml
+++ b/packages/image_picker/image_picker/pubspec.yaml
@@ -2,7 +2,7 @@
 description: Flutter plugin for selecting images from the Android and iOS image
   library, and taking new pictures with the camera.
 homepage: https://github.com/flutter/plugins/tree/master/packages/image_picker/image_picker
-version: 0.6.6
+version: 0.6.6+1
 
 flutter:
   plugin: