Handle Image picker permissions (#1064)

This commit is contained in:
enahum
2017-10-26 09:17:56 -03:00
committed by GitHub
parent ad33738474
commit 59ce8571c3
3 changed files with 93 additions and 12 deletions

View File

@@ -6,8 +6,10 @@ import android.content.ActivityNotFoundException;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.ResolveInfo;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Build;
import android.provider.MediaStore;
import android.provider.Settings;
import android.support.annotation.NonNull;
@@ -44,6 +46,7 @@ import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.lang.ref.WeakReference;
import java.util.List;
import com.facebook.react.modules.core.PermissionListener;
import com.facebook.react.modules.core.PermissionAwareActivity;
@@ -196,7 +199,9 @@ public class ImagePickerModule extends ReactContextBaseJavaModule
public void doOnCancel()
{
responseHelper.invokeCancel(callback);
if (this.callback != null) {
responseHelper.invokeCancel(this.callback);
}
}
public void launchCamera()
@@ -221,6 +226,7 @@ public class ImagePickerModule extends ReactContextBaseJavaModule
return;
}
this.callback = callback;
this.options = options;
if (!permissionsCheck(currentActivity, callback, REQUEST_PERMISSIONS_FOR_CAMERA))
@@ -251,7 +257,12 @@ public class ImagePickerModule extends ReactContextBaseJavaModule
final File original = createNewFile(reactContext, this.options, false);
imageConfig = imageConfig.withOriginalFile(original);
cameraCaptureURI = RealPathUtil.compatUriFromFile(reactContext, imageConfig.original);
if (imageConfig.original != null) {
cameraCaptureURI = RealPathUtil.compatUriFromFile(reactContext, imageConfig.original);
}else {
responseHelper.invokeError(callback, "Couldn't get file path for photo");
return;
}
if (cameraCaptureURI == null)
{
responseHelper.invokeError(callback, "Couldn't get file path for photo");
@@ -266,7 +277,16 @@ public class ImagePickerModule extends ReactContextBaseJavaModule
return;
}
this.callback = callback;
// Workaround for Android bug.
// grantUriPermission also needed for KITKAT,
// see https://code.google.com/p/android/issues/detail?id=76683
if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.KITKAT) {
List<ResolveInfo> resInfoList = reactContext.getPackageManager().queryIntentActivities(cameraIntent, PackageManager.MATCH_DEFAULT_ONLY);
for (ResolveInfo resolveInfo : resInfoList) {
String packageName = resolveInfo.activityInfo.packageName;
reactContext.grantUriPermission(packageName, cameraCaptureURI, Intent.FLAG_GRANT_WRITE_URI_PERMISSION | Intent.FLAG_GRANT_READ_URI_PERMISSION);
}
}
try
{
@@ -294,6 +314,7 @@ public class ImagePickerModule extends ReactContextBaseJavaModule
}
this.options = options;
this.callback = callback;
if (!permissionsCheck(currentActivity, callback, REQUEST_PERMISSIONS_FOR_LIBRARY))
{
@@ -314,7 +335,7 @@ public class ImagePickerModule extends ReactContextBaseJavaModule
{
requestCode = REQUEST_LAUNCH_IMAGE_LIBRARY;
libraryIntent = new Intent(Intent.ACTION_PICK,
MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
}
if (libraryIntent.resolveActivity(reactContext.getPackageManager()) == null)
@@ -323,8 +344,6 @@ public class ImagePickerModule extends ReactContextBaseJavaModule
return;
}
this.callback = callback;
try
{
currentActivity.startActivityForResult(libraryIntent, requestCode);
@@ -571,7 +590,9 @@ public class ImagePickerModule extends ReactContextBaseJavaModule
innerActivity.startActivityForResult(intent, 1);
}
});
dialog.show();
if (dialog != null) {
dialog.show();
}
return false;
}
else
@@ -606,7 +627,7 @@ public class ImagePickerModule extends ReactContextBaseJavaModule
private boolean isCameraAvailable() {
return reactContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA)
|| reactContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA_ANY);
|| reactContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA_ANY);
}
private @NonNull String getRealPathFromURI(@NonNull final Uri uri) {

View File

@@ -1,5 +1,6 @@
import React, {PureComponent} from 'react';
import PropTypes from 'prop-types';
import {injectIntl, intlShape} from 'react-intl';
import {
Platform,
StyleSheet,
@@ -10,21 +11,38 @@ import ImagePicker from 'react-native-image-picker';
import {changeOpacity} from 'app/utils/theme';
export default class AttachmentButton extends PureComponent {
class AttachmentButton extends PureComponent {
static propTypes = {
blurTextBox: PropTypes.func.isRequired,
intl: intlShape.isRequired,
navigator: PropTypes.object.isRequired,
theme: PropTypes.object.isRequired,
uploadFiles: PropTypes.func.isRequired
};
attachFileFromCamera = () => {
const {formatMessage} = this.props.intl;
const options = {
quality: 0.7,
noData: true,
storageOptions: {
cameraRoll: true,
waitUntilSaved: true
},
permissionDenied: {
title: formatMessage({
id: 'mobile.android.camera_permission_denied_title',
defaultMessage: 'Camera access is required'
}),
text: formatMessage({
id: 'mobile.android.camera_permission_denied_description',
defaultMessage: 'To take photos and videos with your camera, please change your permission settings.'
}),
reTryTitle: formatMessage({
id: 'mobile.android.permission_denied_retry',
defaultMessage: 'Set Permission'
}),
okTitle: formatMessage({id: 'mobile.android.permission_denied_dismiss', defaultMessage: 'Dismiss'})
}
};
@@ -38,9 +56,25 @@ export default class AttachmentButton extends PureComponent {
};
attachFileFromLibrary = () => {
const {formatMessage} = this.props.intl;
const options = {
quality: 0.7,
noData: true
noData: true,
permissionDenied: {
title: formatMessage({
id: 'mobile.android.photos_permission_denied_title',
defaultMessage: 'Photo library access is required'
}),
text: formatMessage({
id: 'mobile.android.photos_permission_denied_description',
defaultMessage: 'To upload images from your library, please change your permission settings.'
}),
reTryTitle: formatMessage({
id: 'mobile.android.permission_denied_retry',
defaultMessage: 'Set Permission'
}),
okTitle: formatMessage({id: 'mobile.android.permission_denied_dismiss', defaultMessage: 'Dismiss'})
}
};
if (Platform.OS === 'ios') {
@@ -57,10 +91,26 @@ export default class AttachmentButton extends PureComponent {
};
attachVideoFromLibraryAndroid = () => {
const {formatMessage} = this.props.intl;
const options = {
quality: 0.7,
mediaType: 'video',
noData: true
noData: true,
permissionDenied: {
title: formatMessage({
id: 'mobile.android.videos_permission_denied_title',
defaultMessage: 'Video library access is required'
}),
text: formatMessage({
id: 'mobile.android.videos_permission_denied_description',
defaultMessage: 'To upload videos from your library, please change your permission settings.'
}),
reTryTitle: formatMessage({
id: 'mobile.android.permission_denied_retry',
defaultMessage: 'Set Permission'
}),
okTitle: formatMessage({id: 'mobile.android.permission_denied_dismiss', defaultMessage: 'Dismiss'})
}
};
ImagePicker.launchImageLibrary(options, (response) => {
@@ -70,7 +120,7 @@ export default class AttachmentButton extends PureComponent {
this.uploadFiles([response]);
});
}
};
uploadFiles = (images) => {
this.props.uploadFiles(images);
@@ -175,3 +225,5 @@ const style = StyleSheet.create({
justifyContent: 'center'
}
});
export default injectIntl(AttachmentButton);

View File

@@ -1880,6 +1880,14 @@
"mobile.advanced_settings.reset_message": "\nThis will reset all offline data and restart the app. You will be automatically logged back in once the app restarts.\n",
"mobile.advanced_settings.reset_title": "Reset Cache",
"mobile.advanced_settings.title": "Advanced Settings",
"mobile.android.camera_permission_denied_title": "Camera access is required",
"mobile.android.camera_permission_denied_description": "To take photos and videos with your camera, please change your permission settings.",
"mobile.android.photos_permission_denied_title": "Photo library access is required",
"mobile.android.photos_permission_denied_description": "To upload images from your library, please change your permission settings.",
"mobile.android.videos_permission_denied_title": "Video library access is required",
"mobile.android.videos_permission_denied_description": "To upload videos from your library, please change your permission settings.",
"mobile.android.permission_denied_retry": "Set permission",
"mobile.android.permission_denied_dismiss": "Dismiss",
"mobile.channel_drawer.search": "Jump to...",
"mobile.channel_info.alertMessageDeleteChannel": "Are you sure you want to delete the {term} {name}?",
"mobile.channel_info.alertMessageLeaveChannel": "Are you sure you want to leave the {term} {name}?",