ソースを参照

Don't show camera options for a file upload that would result in nothing happening for the user.

On Android, if the application declares the camera permission, then even intents
that use the camera require permission to be granted. This is a problem for apps
that combine an in-app camera with a WebView that has file uploading and the user
has not given permission for the camera.

Note, this will not request permission for camera. This will simply prevent
showing the camera options that would be a no-op action for users. It does this
by checking if the camera permission is declared, and if so, checks that the
user has granted permission.

More information: https://blog.egorand.me/taking-photos-not-so-simply-how-i-got-bitten-by-action_image_capture/
Daniel Vicory 4 年 前
コミット
d497212b44
共有1 個のファイルを変更した25 個の追加5 個の削除を含む
  1. 25
    5
      android/src/main/java/com/reactnativecommunity/webview/RNCWebViewModule.java

+ 25
- 5
android/src/main/java/com/reactnativecommunity/webview/RNCWebViewModule.java ファイルの表示

32
 import java.io.File;
32
 import java.io.File;
33
 import java.io.IOException;
33
 import java.io.IOException;
34
 import java.util.ArrayList;
34
 import java.util.ArrayList;
35
+import java.util.Arrays;
35
 
36
 
36
 import static android.app.Activity.RESULT_OK;
37
 import static android.app.Activity.RESULT_OK;
37
 
38
 
180
     filePathCallback = callback;
181
     filePathCallback = callback;
181
 
182
 
182
     ArrayList<Parcelable> extraIntents = new ArrayList<>();
183
     ArrayList<Parcelable> extraIntents = new ArrayList<>();
183
-    if (acceptsImages(acceptTypes)) {
184
-      extraIntents.add(getPhotoIntent());
185
-    }
186
-    if (acceptsVideo(acceptTypes)) {
187
-      extraIntents.add(getVideoIntent());
184
+    if (! needsCameraPermission()) {
185
+      if (acceptsImages(acceptTypes)) {
186
+        extraIntents.add(getPhotoIntent());
187
+      }
188
+      if (acceptsVideo(acceptTypes)) {
189
+        extraIntents.add(getVideoIntent());
190
+      }
188
     }
191
     }
189
 
192
 
190
     Intent fileSelectionIntent = getFileChooserIntent(acceptTypes, allowMultiple);
193
     Intent fileSelectionIntent = getFileChooserIntent(acceptTypes, allowMultiple);
233
     return result;
236
     return result;
234
   }
237
   }
235
 
238
 
239
+  protected boolean needsCameraPermission() {
240
+    boolean needed = false;
241
+
242
+    PackageManager packageManager = getCurrentActivity().getPackageManager();
243
+    try {
244
+      String[] requestedPermissions = packageManager.getPackageInfo(getReactApplicationContext().getPackageName(), PackageManager.GET_PERMISSIONS).requestedPermissions;
245
+      if (Arrays.asList(requestedPermissions).contains(Manifest.permission.CAMERA)
246
+        && ContextCompat.checkSelfPermission(getCurrentActivity(), Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
247
+        needed = true;
248
+      }
249
+    } catch (PackageManager.NameNotFoundException e) {
250
+      needed = true;
251
+    }
252
+
253
+    return needed;
254
+  }
255
+
236
   private Intent getPhotoIntent() {
256
   private Intent getPhotoIntent() {
237
     Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
257
     Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
238
     outputFileUri = getOutputUri(MediaStore.ACTION_IMAGE_CAPTURE);
258
     outputFileUri = getOutputUri(MediaStore.ACTION_IMAGE_CAPTURE);