Skip to content
This repository was archived by the owner on Feb 22, 2023. It is now read-only.

Commit

Permalink
add runtime permission requests for external storage and camera (#424)
Browse files Browse the repository at this point in the history
* add runtime permission requests for external storage and camera when requesting image from Camera on android:

* run google-java-format

* redirect to camera after accepting permissions

* send error if permissions are denied and handle error in example code

* fix doc string

* dartfmt

* run google-java-format again
  • Loading branch information
jonahwilliams authored Mar 15, 2018
1 parent 2e00341 commit 96bfbc0
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,15 @@

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.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;
Expand All @@ -20,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;
Expand All @@ -28,13 +33,15 @@
import java.util.Arrays;
import java.util.List;

/** Location Plugin */
public class ImagePickerPlugin implements MethodCallHandler, ActivityResultListener {
/** ImagePicker Plugin */
public class ImagePickerPlugin
implements MethodCallHandler, ActivityResultListener, RequestPermissionsResultListener {
private static String TAG = "ImagePicker";
private static final String CHANNEL = "image_picker";

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;
Expand All @@ -52,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);
}

Expand Down Expand Up @@ -86,6 +94,19 @@ 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);
break;
}
activity.startActivityForResult(
cameraModule.getCameraIntent(activity), REQUEST_CODE_CAMERA);
break;
Expand Down Expand Up @@ -135,6 +156,31 @@ public void onImageReady(List<Image> 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.error(
"no_permissions", "image_picker plugin requires camera permissions", null);
pendingResult = null;
methodCall = null;
}
return true;
}
return false;
}

private void handleResult(Image image) {
if (pendingResult != null) {
Double maxWidth = methodCall.argument("maxWidth");
Expand Down
5 changes: 4 additions & 1 deletion packages/image_picker/example/lib/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,11 @@ class _MyHomePageState extends State<MyHomePage> {
child: new FutureBuilder<File>(
future: _imageFile,
builder: (BuildContext context, AsyncSnapshot<File> snapshot) {
if (snapshot.connectionState == ConnectionState.done) {
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 {
return const Text('You have not yet picked an image.');
}
Expand Down

0 comments on commit 96bfbc0

Please sign in to comment.