Skip to content

Commit

Permalink
Update ReactWebViewManager.java
Browse files Browse the repository at this point in the history
Add file input to WebView facebook#12807 facebook#12807
  • Loading branch information
deepyu authored Jul 25, 2018
1 parent bc9fd7f commit a872d47
Showing 1 changed file with 115 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -9,18 +9,25 @@

import javax.annotation.Nullable;

import java.io.File;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;

import android.app.Activity;
import android.content.ActivityNotFoundException;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.Picture;
import android.net.Uri;
import android.os.Build;
import android.os.Environment;
import android.provider.MediaStore;
import android.text.TextUtils;
import android.view.ViewGroup.LayoutParams;
import android.webkit.ConsoleMessage;
Expand All @@ -34,6 +41,7 @@
import android.webkit.CookieManager;

import com.facebook.common.logging.FLog;
import com.facebook.react.bridge.ActivityEventListener;
import com.facebook.react.common.ReactConstants;
import com.facebook.react.bridge.Arguments;
import com.facebook.react.bridge.LifecycleEventListener;
Expand Down Expand Up @@ -103,8 +111,13 @@ public class ReactWebViewManager extends SimpleViewManager<WebView> {
// state and release page resources (including any running JavaScript).
protected static final String BLANK_URL = "about:blank";

public static final int INPUT_FILE_REQUEST_CODE = 1001;
public static final String EXTRA_FROM_NOTIFICATION = "EXTRA_FROM_NOTIFICATION";

protected WebViewConfig mWebViewConfig;
protected @Nullable WebView.PictureListener mPictureListener;
private ValueCallback<Uri[]> mFilePathCallback;
private String mCameraPhotoPath;

protected static class ReactWebViewClient extends WebViewClient {

Expand Down Expand Up @@ -356,7 +369,7 @@ protected ReactWebView createReactWebViewInstance(ThemedReactContext reactContex
}

@Override
protected WebView createViewInstance(ThemedReactContext reactContext) {
protected WebView createViewInstance(final ThemedReactContext reactContext) {
ReactWebView webView = createReactWebViewInstance(reactContext);
webView.setWebChromeClient(new WebChromeClient() {
@Override
Expand All @@ -372,8 +385,109 @@ public boolean onConsoleMessage(ConsoleMessage message) {
public void onGeolocationPermissionsShowPrompt(String origin, GeolocationPermissions.Callback callback) {
callback.invoke(origin, true, false);
}

private File createImageFile() throws IOException {
// Create an image file name
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
String imageFileName = "JPEG_" + timeStamp + "_";
File storageDir = Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_PICTURES);
File imageFile = new File(
storageDir, /* directory */
imageFileName+".jpg" /* filename */
);
return imageFile;
}

public boolean onShowFileChooser(
WebView webView,
ValueCallback<Uri[]> filePathCallback,
WebChromeClient.FileChooserParams fileChooserParams) {
if(mFilePathCallback != null) {
mFilePathCallback.onReceiveValue(null);
}
mFilePathCallback = filePathCallback;

Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if (takePictureIntent.resolveActivity(reactContext.getCurrentActivity().getPackageManager()) != null) {
// Create the File where the photo should go
File photoFile = null;
try {
photoFile = createImageFile();
takePictureIntent.putExtra("PhotoPath", mCameraPhotoPath);
} catch (IOException ex) {
// Error occurred while creating the File
FLog.e(ReactConstants.TAG, "Unable to create Image File", ex);
}

// Continue only if the File was successfully created
if (photoFile != null) {
mCameraPhotoPath = "file:" + photoFile.getAbsolutePath();
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT,
Uri.fromFile(photoFile));
} else {
takePictureIntent = null;
}
}

Intent contentSelectionIntent = new Intent(Intent.ACTION_GET_CONTENT);
contentSelectionIntent.addCategory(Intent.CATEGORY_OPENABLE);
contentSelectionIntent.setType("image/*");

Intent[] intentArray;
if(takePictureIntent != null) {
intentArray = new Intent[]{takePictureIntent};
} else {
intentArray = new Intent[0];
}

Intent chooserIntent = new Intent(Intent.ACTION_CHOOSER);
chooserIntent.putExtra(Intent.EXTRA_INTENT, contentSelectionIntent);
chooserIntent.putExtra(Intent.EXTRA_TITLE, "Image Chooser");
chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, intentArray);

reactContext.getCurrentActivity().startActivityForResult(chooserIntent, INPUT_FILE_REQUEST_CODE);
return true;
}
});

reactContext.addLifecycleEventListener(webView);
reactContext.addActivityEventListener(new ActivityEventListener() {
@Override
public void onActivityResult (Activity activity, int requestCode, int resultCode, Intent data) {
if(requestCode != INPUT_FILE_REQUEST_CODE || mFilePathCallback == null) {
return;
}
Uri[] results = null;

// Check that the response is a good one
if(resultCode == Activity.RESULT_OK) {
if(data == null) {
// If there is not data, then we may have taken a photo
if(mCameraPhotoPath != null) {
results = new Uri[]{Uri.parse(mCameraPhotoPath)};
}
} else {
String dataString = data.getDataString();
if (dataString != null) {
results = new Uri[]{Uri.parse(dataString)};
}
}
}

if(results == null) {
mFilePathCallback.onReceiveValue(new Uri[]{});
}
else {
mFilePathCallback.onReceiveValue(results);
}
mFilePathCallback = null;
return;
}

@Override
public void onNewIntent(Intent intent) {}
});
mWebViewConfig.configWebView(webView);
webView.getSettings().setBuiltInZoomControls(true);
webView.getSettings().setDisplayZoomControls(false);
Expand Down

0 comments on commit a872d47

Please sign in to comment.