[image_picker] fix camera on Android 11 (#3194)

diff --git a/packages/image_picker/image_picker/CHANGELOG.md b/packages/image_picker/image_picker/CHANGELOG.md
index f9c7640..9d89389 100644
--- a/packages/image_picker/image_picker/CHANGELOG.md
+++ b/packages/image_picker/image_picker/CHANGELOG.md
@@ -1,3 +1,7 @@
+## 0.8.3+2
+
+* Fix using Camera as image source on Android 11+
+
 ## 0.8.3+1
 
 * Fixed README Example.
@@ -26,6 +30,7 @@
 * Fix image picker causing a crash when the cache directory is deleted.
 
 ## 0.8.1+2
+
 * Update the example app to support the multi-image feature.
 
 ## 0.8.1+1
diff --git a/packages/image_picker/image_picker/android/src/main/java/io/flutter/plugins/imagepicker/ImagePickerDelegate.java b/packages/image_picker/image_picker/android/src/main/java/io/flutter/plugins/imagepicker/ImagePickerDelegate.java
index 8b904f5..dbd0f70 100644
--- a/packages/image_picker/image_picker/android/src/main/java/io/flutter/plugins/imagepicker/ImagePickerDelegate.java
+++ b/packages/image_picker/image_picker/android/src/main/java/io/flutter/plugins/imagepicker/ImagePickerDelegate.java
@@ -6,6 +6,7 @@
 
 import android.Manifest;
 import android.app.Activity;
+import android.content.ActivityNotFoundException;
 import android.content.Intent;
 import android.content.pm.PackageManager;
 import android.content.pm.ResolveInfo;
@@ -88,7 +89,6 @@
   private final ImageResizer imageResizer;
   private final ImagePickerCache cache;
   private final PermissionManager permissionManager;
-  private final IntentResolver intentResolver;
   private final FileUriResolver fileUriResolver;
   private final FileUtils fileUtils;
   private CameraDevice cameraDevice;
@@ -101,10 +101,6 @@
     boolean needRequestCameraPermission();
   }
 
-  interface IntentResolver {
-    boolean resolveActivity(Intent intent);
-  }
-
   interface FileUriResolver {
     Uri resolveFileProviderUriForFile(String fileProviderName, File imageFile);
 
@@ -148,12 +144,6 @@
             return ImagePickerUtils.needRequestCameraPermission(activity);
           }
         },
-        new IntentResolver() {
-          @Override
-          public boolean resolveActivity(Intent intent) {
-            return intent.resolveActivity(activity.getPackageManager()) != null;
-          }
-        },
         new FileUriResolver() {
           @Override
           public Uri resolveFileProviderUriForFile(String fileProviderName, File file) {
@@ -190,7 +180,6 @@
       final MethodCall methodCall,
       final ImagePickerCache cache,
       final PermissionManager permissionManager,
-      final IntentResolver intentResolver,
       final FileUriResolver fileUriResolver,
       final FileUtils fileUtils) {
     this.activity = activity;
@@ -200,7 +189,6 @@
     this.pendingResult = result;
     this.methodCall = methodCall;
     this.permissionManager = permissionManager;
-    this.intentResolver = intentResolver;
     this.fileUriResolver = fileUriResolver;
     this.fileUtils = fileUtils;
     this.cache = cache;
@@ -291,13 +279,6 @@
       useFrontCamera(intent);
     }
 
-    boolean canTakePhotos = intentResolver.resolveActivity(intent);
-
-    if (!canTakePhotos) {
-      finishWithError("no_available_camera", "No cameras available for taking pictures.");
-      return;
-    }
-
     File videoFile = createTemporaryWritableVideoFile();
     pendingCameraMediaUri = Uri.parse("file:" + videoFile.getAbsolutePath());
 
@@ -305,7 +286,18 @@
     intent.putExtra(MediaStore.EXTRA_OUTPUT, videoUri);
     grantUriPermissions(intent, videoUri);
 
-    activity.startActivityForResult(intent, REQUEST_CODE_TAKE_VIDEO_WITH_CAMERA);
+    try {
+      activity.startActivityForResult(intent, REQUEST_CODE_TAKE_VIDEO_WITH_CAMERA);
+    } catch (ActivityNotFoundException e) {
+      try {
+        // If we can't delete the file again here, there's not really anything we can do about it.
+        //noinspection ResultOfMethodCallIgnored
+        videoFile.delete();
+      } catch (SecurityException exception) {
+        exception.printStackTrace();
+      }
+      finishWithError("no_available_camera", "No cameras available for taking pictures.");
+    }
   }
 
   public void chooseImageFromGallery(MethodCall methodCall, MethodChannel.Result result) {
@@ -371,13 +363,6 @@
       useFrontCamera(intent);
     }
 
-    boolean canTakePhotos = intentResolver.resolveActivity(intent);
-
-    if (!canTakePhotos) {
-      finishWithError("no_available_camera", "No cameras available for taking pictures.");
-      return;
-    }
-
     File imageFile = createTemporaryWritableImageFile();
     pendingCameraMediaUri = Uri.parse("file:" + imageFile.getAbsolutePath());
 
@@ -385,7 +370,18 @@
     intent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);
     grantUriPermissions(intent, imageUri);
 
-    activity.startActivityForResult(intent, REQUEST_CODE_TAKE_IMAGE_WITH_CAMERA);
+    try {
+      activity.startActivityForResult(intent, REQUEST_CODE_TAKE_IMAGE_WITH_CAMERA);
+    } catch (ActivityNotFoundException e) {
+      try {
+        // If we can't delete the file again here, there's not really anything we can do about it.
+        //noinspection ResultOfMethodCallIgnored
+        imageFile.delete();
+      } catch (SecurityException exception) {
+        exception.printStackTrace();
+      }
+      finishWithError("no_available_camera", "No cameras available for taking pictures.");
+    }
   }
 
   private File createTemporaryWritableImageFile() {
diff --git a/packages/image_picker/image_picker/android/src/test/java/io/flutter/plugins/imagepicker/ImagePickerDelegateTest.java b/packages/image_picker/image_picker/android/src/test/java/io/flutter/plugins/imagepicker/ImagePickerDelegateTest.java
index 1b55a75..ebd58d0 100644
--- a/packages/image_picker/image_picker/android/src/test/java/io/flutter/plugins/imagepicker/ImagePickerDelegateTest.java
+++ b/packages/image_picker/image_picker/android/src/test/java/io/flutter/plugins/imagepicker/ImagePickerDelegateTest.java
@@ -7,7 +7,9 @@
 import static org.hamcrest.core.IsEqual.equalTo;
 import static org.junit.Assert.assertThat;
 import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.doThrow;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
@@ -16,6 +18,7 @@
 
 import android.Manifest;
 import android.app.Activity;
+import android.content.ActivityNotFoundException;
 import android.content.Context;
 import android.content.Intent;
 import android.content.pm.PackageManager;
@@ -42,7 +45,6 @@
   @Mock MethodCall mockMethodCall;
   @Mock MethodChannel.Result mockResult;
   @Mock ImagePickerDelegate.PermissionManager mockPermissionManager;
-  @Mock ImagePickerDelegate.IntentResolver mockIntentResolver;
   @Mock FileUtils mockFileUtils;
   @Mock Intent mockIntent;
   @Mock ImagePickerCache cache;
@@ -164,7 +166,6 @@
   @Test
   public void takeImageWithCamera_WhenCameraPermissionNotPresent_RequestsForPermission() {
     when(mockPermissionManager.needRequestCameraPermission()).thenReturn(false);
-    when(mockIntentResolver.resolveActivity(any(Intent.class))).thenReturn(true);
 
     ImagePickerDelegate delegate = createDelegate();
     delegate.takeImageWithCamera(mockMethodCall, mockResult);
@@ -178,7 +179,6 @@
   public void
       takeImageWithCamera_WhenHasCameraPermission_AndAnActivityCanHandleCameraIntent_LaunchesTakeWithCameraIntent() {
     when(mockPermissionManager.isPermissionGranted(Manifest.permission.CAMERA)).thenReturn(true);
-    when(mockIntentResolver.resolveActivity(any(Intent.class))).thenReturn(true);
 
     ImagePickerDelegate delegate = createDelegate();
     delegate.takeImageWithCamera(mockMethodCall, mockResult);
@@ -192,8 +192,9 @@
   public void
       takeImageWithCamera_WhenHasCameraPermission_AndNoActivityToHandleCameraIntent_FinishesWithNoCamerasAvailableError() {
     when(mockPermissionManager.isPermissionGranted(Manifest.permission.CAMERA)).thenReturn(true);
-    when(mockIntentResolver.resolveActivity(any(Intent.class))).thenReturn(false);
-
+    doThrow(ActivityNotFoundException.class)
+        .when(mockActivity)
+        .startActivityForResult(any(Intent.class), anyInt());
     ImagePickerDelegate delegate = createDelegate();
     delegate.takeImageWithCamera(mockMethodCall, mockResult);
 
@@ -205,7 +206,6 @@
   @Test
   public void takeImageWithCamera_WritesImageToCacheDirectory() {
     when(mockPermissionManager.isPermissionGranted(Manifest.permission.CAMERA)).thenReturn(true);
-    when(mockIntentResolver.resolveActivity(any(Intent.class))).thenReturn(true);
 
     ImagePickerDelegate delegate = createDelegate();
     delegate.takeImageWithCamera(mockMethodCall, mockResult);
@@ -231,7 +231,6 @@
   @Test
   public void
       onRequestTakeVideoPermissionsResult_WhenCameraPermissionGranted_LaunchesTakeVideoWithCameraIntent() {
-    when(mockIntentResolver.resolveActivity(any(Intent.class))).thenReturn(true);
 
     ImagePickerDelegate delegate = createDelegateWithPendingResultAndMethodCall();
     delegate.onRequestPermissionsResult(
@@ -247,7 +246,6 @@
   @Test
   public void
       onRequestTakeImagePermissionsResult_WhenCameraPermissionGranted_LaunchesTakeWithCameraIntent() {
-    when(mockIntentResolver.resolveActivity(any(Intent.class))).thenReturn(true);
 
     ImagePickerDelegate delegate = createDelegateWithPendingResultAndMethodCall();
     delegate.onRequestPermissionsResult(
@@ -379,7 +377,6 @@
         null,
         cache,
         mockPermissionManager,
-        mockIntentResolver,
         mockFileUriResolver,
         mockFileUtils);
   }
@@ -393,7 +390,6 @@
         mockMethodCall,
         cache,
         mockPermissionManager,
-        mockIntentResolver,
         mockFileUriResolver,
         mockFileUtils);
   }
diff --git a/packages/image_picker/image_picker/pubspec.yaml b/packages/image_picker/image_picker/pubspec.yaml
index e67e79f..e167d8a 100755
--- a/packages/image_picker/image_picker/pubspec.yaml
+++ b/packages/image_picker/image_picker/pubspec.yaml
@@ -3,7 +3,7 @@
   library, and taking new pictures with the camera.
 repository: https://github.com/flutter/plugins/tree/master/packages/image_picker/image_picker
 issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+image_picker%22
-version: 0.8.3+1
+version: 0.8.3+2
 
 environment:
   sdk: ">=2.12.0 <3.0.0"