From f8b67a0dd2fc38a2cac3586fb2e262741f0a25d7 Mon Sep 17 00:00:00 2001 From: Jonah Williams Date: Wed, 14 Mar 2018 14:39:58 -0700 Subject: [PATCH 1/7] add runtime permission requests for external storage and camera when requesting image from Camera on android: --- .../plugins/imagepicker/ImagePickerPlugin.java | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/packages/image_picker/android/src/main/java/io/flutter/plugins/imagepicker/ImagePickerPlugin.java b/packages/image_picker/android/src/main/java/io/flutter/plugins/imagepicker/ImagePickerPlugin.java index 68f621411c76..a964650bad96 100644 --- a/packages/image_picker/android/src/main/java/io/flutter/plugins/imagepicker/ImagePickerPlugin.java +++ b/packages/image_picker/android/src/main/java/io/flutter/plugins/imagepicker/ImagePickerPlugin.java @@ -4,12 +4,16 @@ package io.flutter.plugins.imagepicker; +import android.Manifest; import android.app.Activity; import android.content.Intent; +import android.content.pm.PackageManager; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.media.ExifInterface; import android.util.Log; +import android.support.v4.app.ActivityCompat; +import android.support.v4.content.ContextCompat; import com.esafirm.imagepicker.features.ImagePicker; import com.esafirm.imagepicker.features.camera.DefaultCameraModule; import com.esafirm.imagepicker.features.camera.OnImageReadyListener; @@ -35,7 +39,8 @@ public class ImagePickerPlugin implements MethodCallHandler, ActivityResultListe public static final int REQUEST_CODE_PICK = 2342; public static final int REQUEST_CODE_CAMERA = 2343; - + public static final int REQUEST_PERMISSIONS = 2345; + private static final int SOURCE_ASK_USER = 0; private static final int SOURCE_CAMERA = 1; private static final int SOURCE_GALLERY = 2; @@ -86,6 +91,14 @@ public void onMethodCall(MethodCall call, Result result) { ImagePicker.create(activity).single().showCamera(false).start(REQUEST_CODE_PICK); break; case SOURCE_CAMERA: + if (ContextCompat.checkSelfPermission(activity, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED || + ContextCompat.checkSelfPermission(activity, Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) { + ActivityCompat.requestPermissions(activity, + new String[]{Manifest.permission.CAMERA, Manifest.permission.READ_EXTERNAL_STORAGE}, REQUEST_PERMISSIONS); + pendingResult = null; + methodCall = null; + break; + } activity.startActivityForResult( cameraModule.getCameraIntent(activity), REQUEST_CODE_CAMERA); break; From d2d13c427b568b5ad7ace977d84cda02d0f48f74 Mon Sep 17 00:00:00 2001 From: Jonah Williams Date: Wed, 14 Mar 2018 14:45:17 -0700 Subject: [PATCH 2/7] run google-java-format --- .../imagepicker/ImagePickerPlugin.java | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/packages/image_picker/android/src/main/java/io/flutter/plugins/imagepicker/ImagePickerPlugin.java b/packages/image_picker/android/src/main/java/io/flutter/plugins/imagepicker/ImagePickerPlugin.java index a964650bad96..b1f43a2ff4ce 100644 --- a/packages/image_picker/android/src/main/java/io/flutter/plugins/imagepicker/ImagePickerPlugin.java +++ b/packages/image_picker/android/src/main/java/io/flutter/plugins/imagepicker/ImagePickerPlugin.java @@ -11,9 +11,9 @@ import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.media.ExifInterface; -import android.util.Log; import android.support.v4.app.ActivityCompat; import android.support.v4.content.ContextCompat; +import android.util.Log; import com.esafirm.imagepicker.features.ImagePicker; import com.esafirm.imagepicker.features.camera.DefaultCameraModule; import com.esafirm.imagepicker.features.camera.OnImageReadyListener; @@ -40,7 +40,7 @@ public class ImagePickerPlugin implements MethodCallHandler, ActivityResultListe public static final int REQUEST_CODE_PICK = 2342; public static final int REQUEST_CODE_CAMERA = 2343; public static final int REQUEST_PERMISSIONS = 2345; - + private static final int SOURCE_ASK_USER = 0; private static final int SOURCE_CAMERA = 1; private static final int SOURCE_GALLERY = 2; @@ -91,10 +91,17 @@ public void onMethodCall(MethodCall call, Result result) { ImagePicker.create(activity).single().showCamera(false).start(REQUEST_CODE_PICK); break; case SOURCE_CAMERA: - if (ContextCompat.checkSelfPermission(activity, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED || - ContextCompat.checkSelfPermission(activity, Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) { - ActivityCompat.requestPermissions(activity, - new String[]{Manifest.permission.CAMERA, Manifest.permission.READ_EXTERNAL_STORAGE}, REQUEST_PERMISSIONS); + if (ContextCompat.checkSelfPermission(activity, Manifest.permission.CAMERA) + != PackageManager.PERMISSION_GRANTED + || ContextCompat.checkSelfPermission( + activity, Manifest.permission.READ_EXTERNAL_STORAGE) + != PackageManager.PERMISSION_GRANTED) { + ActivityCompat.requestPermissions( + activity, + new String[] { + Manifest.permission.CAMERA, Manifest.permission.READ_EXTERNAL_STORAGE + }, + REQUEST_PERMISSIONS); pendingResult = null; methodCall = null; break; From ab8d17e0546f4495e82e73a13c60add708166dfa Mon Sep 17 00:00:00 2001 From: Jonah Williams Date: Wed, 14 Mar 2018 16:20:28 -0700 Subject: [PATCH 3/7] redirect to camera after accepting permissions --- .../imagepicker/ImagePickerPlugin.java | 30 +++++++++++++++++-- 1 file changed, 27 insertions(+), 3 deletions(-) diff --git a/packages/image_picker/android/src/main/java/io/flutter/plugins/imagepicker/ImagePickerPlugin.java b/packages/image_picker/android/src/main/java/io/flutter/plugins/imagepicker/ImagePickerPlugin.java index b1f43a2ff4ce..949bd18d9adf 100644 --- a/packages/image_picker/android/src/main/java/io/flutter/plugins/imagepicker/ImagePickerPlugin.java +++ b/packages/image_picker/android/src/main/java/io/flutter/plugins/imagepicker/ImagePickerPlugin.java @@ -24,6 +24,7 @@ import io.flutter.plugin.common.MethodChannel.Result; import io.flutter.plugin.common.PluginRegistry; import io.flutter.plugin.common.PluginRegistry.ActivityResultListener; +import io.flutter.plugin.common.PluginRegistry.RequestPermissionsResultListener; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileOutputStream; @@ -33,7 +34,8 @@ import java.util.List; /** Location Plugin */ -public class ImagePickerPlugin implements MethodCallHandler, ActivityResultListener { +public class ImagePickerPlugin + implements MethodCallHandler, ActivityResultListener, RequestPermissionsResultListener { private static String TAG = "ImagePicker"; private static final String CHANNEL = "image_picker"; @@ -57,6 +59,7 @@ public static void registerWith(PluginRegistry.Registrar registrar) { final MethodChannel channel = new MethodChannel(registrar.messenger(), CHANNEL); final ImagePickerPlugin instance = new ImagePickerPlugin(registrar); registrar.addActivityResultListener(instance); + registrar.addRequestPermissionsResultListener(instance); channel.setMethodCallHandler(instance); } @@ -102,8 +105,6 @@ public void onMethodCall(MethodCall call, Result result) { Manifest.permission.CAMERA, Manifest.permission.READ_EXTERNAL_STORAGE }, REQUEST_PERMISSIONS); - pendingResult = null; - methodCall = null; break; } activity.startActivityForResult( @@ -155,6 +156,29 @@ public void onImageReady(List images) { return false; } + @Override + public boolean onRequestPermissionsResult( + int requestCode, String[] permissions, int[] grantResults) { + if (requestCode == REQUEST_PERMISSIONS) { + if (grantResults.length == 2 + && grantResults[0] == PackageManager.PERMISSION_GRANTED + && grantResults[1] == PackageManager.PERMISSION_GRANTED) { + Activity activity = registrar.activity(); + if (activity == null) { + pendingResult.error( + "no_activity", "image_picker plugin requires a foreground activity.", null); + } + activity.startActivityForResult( + cameraModule.getCameraIntent(activity), REQUEST_CODE_CAMERA); + } else { + pendingResult = null; + methodCall = null; + } + return true; + } + return false; + } + private void handleResult(Image image) { if (pendingResult != null) { Double maxWidth = methodCall.argument("maxWidth"); From 08b31da6bd40b915023e0d825017b825a113ef62 Mon Sep 17 00:00:00 2001 From: Jonah Williams Date: Wed, 14 Mar 2018 16:38:07 -0700 Subject: [PATCH 4/7] send error if permissions are denied and handle error in example code --- .../io/flutter/plugins/imagepicker/ImagePickerPlugin.java | 1 + packages/image_picker/example/lib/main.dart | 6 ++++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/packages/image_picker/android/src/main/java/io/flutter/plugins/imagepicker/ImagePickerPlugin.java b/packages/image_picker/android/src/main/java/io/flutter/plugins/imagepicker/ImagePickerPlugin.java index 949bd18d9adf..520e8953ed28 100644 --- a/packages/image_picker/android/src/main/java/io/flutter/plugins/imagepicker/ImagePickerPlugin.java +++ b/packages/image_picker/android/src/main/java/io/flutter/plugins/imagepicker/ImagePickerPlugin.java @@ -171,6 +171,7 @@ public boolean onRequestPermissionsResult( activity.startActivityForResult( cameraModule.getCameraIntent(activity), REQUEST_CODE_CAMERA); } else { + pendingResult.error("no_permissions", "image_picker plugin requires camera permissions", null); pendingResult = null; methodCall = null; } diff --git a/packages/image_picker/example/lib/main.dart b/packages/image_picker/example/lib/main.dart index 0a8d42347051..a5dba3d28618 100755 --- a/packages/image_picker/example/lib/main.dart +++ b/packages/image_picker/example/lib/main.dart @@ -44,9 +44,11 @@ class _MyHomePageState extends State { child: new FutureBuilder( future: _imageFile, builder: (BuildContext context, AsyncSnapshot snapshot) { - if (snapshot.connectionState == ConnectionState.done) { + if (snapshot.connectionState == ConnectionState.done && snapshot.error == null) { return new Image.file(snapshot.data); - } else { + } else if (snapshot.error != null) { + return const Text('error picking image.'); + } else { return const Text('You have not yet picked an image.'); } })), From e773370c2d9e6ef1cbd94225cb2476df25c7b1b6 Mon Sep 17 00:00:00 2001 From: Jonah Williams Date: Wed, 14 Mar 2018 16:40:14 -0700 Subject: [PATCH 5/7] fix doc string --- .../java/io/flutter/plugins/imagepicker/ImagePickerPlugin.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/image_picker/android/src/main/java/io/flutter/plugins/imagepicker/ImagePickerPlugin.java b/packages/image_picker/android/src/main/java/io/flutter/plugins/imagepicker/ImagePickerPlugin.java index 520e8953ed28..4d253c441ed9 100644 --- a/packages/image_picker/android/src/main/java/io/flutter/plugins/imagepicker/ImagePickerPlugin.java +++ b/packages/image_picker/android/src/main/java/io/flutter/plugins/imagepicker/ImagePickerPlugin.java @@ -33,7 +33,7 @@ import java.util.Arrays; import java.util.List; -/** Location Plugin */ +/** ImagePicker Plugin */ public class ImagePickerPlugin implements MethodCallHandler, ActivityResultListener, RequestPermissionsResultListener { private static String TAG = "ImagePicker"; From cb5c6ecdf4fcc1a15ae28747548401b9b2524147 Mon Sep 17 00:00:00 2001 From: Jonah Williams Date: Wed, 14 Mar 2018 16:41:19 -0700 Subject: [PATCH 6/7] dartfmt --- packages/image_picker/example/lib/main.dart | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/packages/image_picker/example/lib/main.dart b/packages/image_picker/example/lib/main.dart index a5dba3d28618..7756d9dc579e 100755 --- a/packages/image_picker/example/lib/main.dart +++ b/packages/image_picker/example/lib/main.dart @@ -44,11 +44,12 @@ class _MyHomePageState extends State { child: new FutureBuilder( future: _imageFile, builder: (BuildContext context, AsyncSnapshot snapshot) { - if (snapshot.connectionState == ConnectionState.done && snapshot.error == null) { + if (snapshot.connectionState == ConnectionState.done && + snapshot.error == null) { return new Image.file(snapshot.data); } else if (snapshot.error != null) { return const Text('error picking image.'); - } else { + } else { return const Text('You have not yet picked an image.'); } })), From 1c1d6f65c3c36a0a9f69e7a107fac264386dd99b Mon Sep 17 00:00:00 2001 From: Jonah Williams Date: Wed, 14 Mar 2018 16:50:31 -0700 Subject: [PATCH 7/7] run google-java-format again --- .../java/io/flutter/plugins/imagepicker/ImagePickerPlugin.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/image_picker/android/src/main/java/io/flutter/plugins/imagepicker/ImagePickerPlugin.java b/packages/image_picker/android/src/main/java/io/flutter/plugins/imagepicker/ImagePickerPlugin.java index 4d253c441ed9..6b1811f67628 100644 --- a/packages/image_picker/android/src/main/java/io/flutter/plugins/imagepicker/ImagePickerPlugin.java +++ b/packages/image_picker/android/src/main/java/io/flutter/plugins/imagepicker/ImagePickerPlugin.java @@ -171,7 +171,8 @@ public boolean onRequestPermissionsResult( activity.startActivityForResult( cameraModule.getCameraIntent(activity), REQUEST_CODE_CAMERA); } else { - pendingResult.error("no_permissions", "image_picker plugin requires camera permissions", null); + pendingResult.error( + "no_permissions", "image_picker plugin requires camera permissions", null); pendingResult = null; methodCall = null; }