I have one problem with Oppo F1 and LG G2 running Lollipop. On other devices running Lollipop, the problem does not appear
My Problem is that File Chooser doesn't show with the mentioned devices.
What I'm currently doing:
private WebView web;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_add_event);
web = (WebView) findViewById(R.id.webView_addEvent);
web.loadUrl(tempURL);
startWebViewForLolipop();
}
private void startWebViewForLolipop() {
//CODING FOR LOLIPOP VERSION
// Create new webview Client to show progress dialog
// Called When opening a url or click on link
// You can create external class extends with WebViewClient
// Taking WebViewClient as inner class
web.setWebViewClient(new WebViewClient() {
// ProgressDialog progressDialog;
//If you will not use this method url links are open in new brower not in webview
public boolean shouldOverrideUrlLoading(WebView view, String url) {
// Check if Url contains ExternalLinks string in url
// then open url in new browser
// else all webview links will open in webview browser
if (url.contains("google")) {
// Could be cleverer and use a regex
//Open links in new browser
view.getContext().startActivity(
new Intent(Intent.ACTION_VIEW, Uri.parse(url)));
// Here we can open new activity
return true;
} else {
// Stay within this webview and load url
view.loadUrl(url);
return true;
}
}
//Show loader on url load
public void onLoadResource(WebView view, String url) {
// if url contains string androidexample
// Then show progress Dialog
/* if (progressDialog == null *//*&& url.contains("androidexample")*//*
) {
// in standard case YourActivity.this
progressDialog = new ProgressDialog(AddEvent.this);
progressDialog.setMessage("Loading...");
progressDialog.show();
}*/
}
// Called when all page resources loaded
public void onPageFinished(WebView view, String url) {
try {
// Close progressDialog
if (probressbar.isShown())
probressbar.setVisibility(View.GONE);
} catch (Exception exception) {
exception.printStackTrace();
}
}
});
// You can create external class extends with WebChromeClient
// Taking WebViewClient as inner class
// we will define openFileChooser for select file from camera or sdcard
web.setWebChromeClient(new WebChromeClient() {
// openFileChooser for Android 3.0+
public void openFileChooser(ValueCallback<Uri> uploadMsg, String acceptType) {
// Update message
mUploadMessage = uploadMsg;
try {
// Create ImgDir Folder at sdcard
File imageStorageDir = new File(
Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_PICTURES)
, "ImgDir");
if (!imageStorageDir.exists()) {
// Create AndroidExampleFolder at sdcard
imageStorageDir.mkdirs();
} else {
//Delete Old Content
if (imageStorageDir.isDirectory()) {
String[] children = imageStorageDir.list();
for (int i = 0; i < children.length; i++) {
new File(imageStorageDir, children[i]).delete();
}
}
imageStorageDir.delete();
// Create AndroidExampleFolder at sdcard
imageStorageDir.mkdirs();
}
// Create camera captured image file path and name
File file = new File(
imageStorageDir + File.separator + "IMG_"
+ String.valueOf(System.currentTimeMillis())
+ ".jpg");
mCapturedImageURI = Uri.fromFile(file);
// Camera capture image intent
final Intent captureIntent = new Intent(
android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
captureIntent.putExtra(MediaStore.EXTRA_OUTPUT, mCapturedImageURI);
Intent i = new Intent(Intent.ACTION_GET_CONTENT);
i.addCategory(Intent.CATEGORY_OPENABLE);
i.setType("image/*");
// Create file chooser intent
Intent chooserIntent = Intent.createChooser(i, "Image Chooser");
// Set camera intent to file chooser
chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS
, new Parcelable[]{captureIntent});
// On select image call onActivityResult method of activity
startActivityForResult(chooserIntent, FILECHOOSER_RESULTCODE);
} catch (Exception e) {
Toast.makeText(getBaseContext(), "Exception:" + e,
Toast.LENGTH_LONG).show();
}
}
// openFileChooser for Android < 3.0
public void openFileChooser(ValueCallback<Uri> uploadMsg) {
openFileChooser(uploadMsg, "");
}
//openFileChooser for other Android versions
public void openFileChooser(ValueCallback<Uri> uploadMsg,
String acceptType,
String capture) {
openFileChooser(uploadMsg, acceptType);
}
// The webPage has 2 filechoosers and will send a
// console message informing what action to perform,
// taking a photo or updating the file
public boolean onConsoleMessage(ConsoleMessage cm) {
onConsoleMessage(cm.message(), cm.lineNumber(), cm.sourceId());
return true;
}
public void onConsoleMessage(String message, int lineNumber, String sourceID) {
Log.d("androidruntime", "Show console messages, Used for debugging: " + message);
}
}); // End setWebChromeClient
/*
web.setWebChromeClient(new WebChromeClient() {
public boolean onShowFileChooser(
WebView webView, ValueCallback<Uri[]> filePathCallback,
WebChromeClient.FileChooserParams fileChooserParams) {
// Double check that we don't have any existing callbacks
if (mFilePathCallback != null) {
mFilePathCallback.onReceiveValue(null);
}
mFilePathCallback = filePathCallback;
*/
/* File imageStorageDir = new File(
Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_PICTURES)
, "ImgDir/addEvent");
if (!imageStorageDir.exists()) {
// Create ImgDir/addEvent Folder at sdcard
imageStorageDir.mkdirs();
}
// Create camera captured image file path and name
File file = new File(
imageStorageDir + File.separator + "IMG_"
+ String.valueOf(System.currentTimeMillis())
+ ".jpg");
mCapturedImageURI = Uri.fromFile(file);*//*
*/
/* if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
mFilePathCallback = filePathCallback;
try {
Intent intent = fileChooserParams.createIntent();
startActivityForResult(intent, 1);
} catch (Exception e) {
// TODO: when open file chooser failed
}
} else {*//*
// Set up the take picture intent
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if (takePictureIntent.resolveActivity(AddEvent.this.getPackageManager()) != null) {
// Create the File where the photo should go
File photoFile = null;
try{
photoFile = createImageFile();
takePictureIntent.putExtra("PhotoPath", mCameraPhotoPath);
} catch (IOException e){
e.printStackTrace();
Log.e("TAG", "Unable to create Image File", e);
}
// 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;
}
}
// Set up the intent to get an existing image
Intent contentSelectionIntent = new Intent(Intent.ACTION_GET_CONTENT);
contentSelectionIntent.addCategory(Intent.CATEGORY_OPENABLE);
contentSelectionIntent.setType("image*/
/*");
// Set up the intents for the Intent chooser
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);
startActivityForResult(chooserIntent, 1);
// }
return true;
}
});
*/
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent intent) {
if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.KITKAT) {
super.onActivityResult(requestCode, resultCode, intent);
if (requestCode == FILECHOOSER_RESULTCODE) {
if (null == this.mUploadMessage) {
return;
}
Uri result = null;
try {
if (resultCode != RESULT_OK) {
result = null;
} else {
// retrieve from the private variable if the intent is null
//result = intent == null ? mCapturedImageURI : intent.getData();
Log.d("TAG", "Image File Path : " + mCapturedImageURI);
String test = intent.toString();
if (intent == null) {
String temp = decodeFile(mCapturedImageURI.getPath(), getImageName(mCapturedImageURI.getPath()));
result = Uri.parse("file:///"+temp);
//result = mCapturedImageURI;
} else {
if (test.equals("Intent { }")) {
String temp = decodeFile(mCapturedImageURI.getPath(), getImageName(mCapturedImageURI.getPath()));
result = Uri.parse("file:///"+temp);
//result = mCapturedImageURI;
} else {
String temp = decodeFile(intent.getData().toString(), getImageName(intent.getData().toString()));
result = Uri.parse("file:///"+temp);
result = Uri.parse(decodeFile(intent.getData().toString(), getImageName(intent.getData().toString())));
//result = intent.getData();
}
}
/* // retrieve from the private variable if the intent is null
String test = intent.toString();
if (intent == null) {
result = mCapturedImageURI;
} else {
if (test.equals("Intent { }")) {
result = mCapturedImageURI;
} else
result = intent.getData();
}*/
}
} catch (Exception e) {
Toast.makeText(getApplicationContext(), "activity :" + e,
Toast.LENGTH_LONG).show();
}
mUploadMessage.onReceiveValue(result);
mUploadMessage = null;
}
} else {
/* if (requestCode == 1 && Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
mFilePathCallback.onReceiveValue(WebChromeClient.FileChooserParams.parseResult(resultCode, intent));
mFilePathCallback = null;
return;
} else {*/
if (requestCode == FILECHOOSER_RESULTCODE) {
//// TODO: 23/6/16 temporary comment this code
/*if (requestCode != 1 || mFilePathCallback == null) {
super.onActivityResult(requestCode, resultCode, intent);
return;
}*/
if (null == this.mUploadMessage) {
return;
}
Uri result = null;
try {
if (resultCode != RESULT_OK) {
result = null;
} else {
// retrieve from the private variable if the intent is null
//result = intent == null ? mCapturedImageURI : intent.getData();
Log.d("TAG", "Image File Path : " + mCapturedImageURI);
if (intent == null) {
String temp = decodeFile(mCapturedImageURI.getPath(), getImageName(mCapturedImageURI.getPath()));
result = Uri.parse("file:///"+temp);
//result = mCapturedImageURI;
} else {
String test = intent.toString();
if (test.equals("Intent { }")) {
String temp = decodeFile(mCapturedImageURI.getPath(), getImageName(mCapturedImageURI.getPath()));
result = Uri.parse("file:///"+temp);
//result = mCapturedImageURI;
} else {
String temp = decodeFile(intent.getData().toString(), getImageName(intent.getData().toString()));
result = Uri.parse("file:///"+temp);
result = Uri.parse(decodeFile(intent.getData().toString(), getImageName(intent.getData().toString())));
//result = intent.getData();
}
}
}
} catch (Exception e) {
Toast.makeText(getApplicationContext(), "activity :" + e, Toast.LENGTH_LONG).show();
}
mUploadMessage.onReceiveValue(result);
mUploadMessage = null;
/* Uri[] results = null;
// Check that the response is a good one
if (resultCode == Activity.RESULT_OK) {
if (intent == 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 = intent.getDataString();
if (dataString != null) {
results = new Uri[]{Uri.parse(dataString)};
}
}
}
mFilePathCallback.onReceiveValue(results);
mFilePathCallback = null;
return;*/
// }
}
}
}
Related
I have given file access permission to web view. But still SPA inside webiew is unable to open file explorer/unable to access media.
binding.admWebView.settings.allowFileAccess=true
binding.admWebView.settings.setSupportMultipleWindows(true)
binding.admWebView.settings.javaScriptCanOpenWindowsAutomatically = true
Try this -
1. Add permission on AndroidManifest.xml
<uses-permission android:name="android.permission.CAMERA" />
<uses-feature android:name="android.hardware.camera" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
2. MainActivity.java
public class MainActivity extends AppCompatActivity {
public ProgressDialog progressDialog;
private WebView webView;
private static final int FILECHOOSER_RESULTCODE = 1;
private ValueCallback<Uri> mUploadMessage;
private Uri mCapturedImageURI = null;
private String mCameraPhotoPath;
// the same for Android 5.0 methods only
private ValueCallback<Uri[]> mFilePathCallback;
/* access modifiers changed from: protected */
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView((int) R.layout.activity_main);
ProgressDialog progressDialog2 = new ProgressDialog(this);
this.progressDialog = progressDialog2;
progressDialog2.setMessage("Please wait ...");
this.progressDialog.setCancelable(false);
this.progressDialog.show();
load();
}
private void load() {
WebView webView2 = (WebView) findViewById(R.id.web_view);
this.webView = webView2;
webView2.loadUrl("https://google.com/");
this.webView.getSettings().setDomStorageEnabled(true);
this.webView.getSettings().setJavaScriptEnabled(true);
this.webView.getSettings().setSaveFormData(true);
this.webView.getSettings().setAllowContentAccess(true);
this.webView.getSettings().setAllowFileAccess(true);
this.webView.getSettings().setAllowFileAccessFromFileURLs(true);
this.webView.getSettings().setAllowUniversalAccessFromFileURLs(true);
this.webView.getSettings().setAllowFileAccess(true);
this.webView.getSettings().setSupportZoom(true);
this.webView.getSettings().setBuiltInZoomControls(true);
this.webView.getSettings().setDisplayZoomControls(false);
this.webView.setClickable(true);
this.webView.setWebChromeClient(new WebChromeClient() {
private View mCustomView;
private WebChromeClient.CustomViewCallback mCustomViewCallback;
protected FrameLayout mFullscreenContainer;
private int mOriginalOrientation;
private int mOriginalSystemUiVisibility;
public Bitmap getDefaultVideoPoster()
{
if (mCustomView == null) {
return null;
}
return BitmapFactory.decodeResource(getApplicationContext().getResources(), 2130837573);
}
public void onHideCustomView()
{
((FrameLayout)getWindow().getDecorView()).removeView(this.mCustomView);
this.mCustomView = null;
getWindow().getDecorView().setSystemUiVisibility(this.mOriginalSystemUiVisibility);
setRequestedOrientation(this.mOriginalOrientation);
this.mCustomViewCallback.onCustomViewHidden();
this.mCustomViewCallback = null;
}
public void onShowCustomView(View paramView, WebChromeClient.CustomViewCallback paramCustomViewCallback)
{
if (this.mCustomView != null)
{
onHideCustomView();
return;
}
this.mCustomView = paramView;
this.mOriginalSystemUiVisibility = getWindow().getDecorView().getSystemUiVisibility();
this.mOriginalOrientation = getRequestedOrientation();
this.mCustomViewCallback = paramCustomViewCallback;
((FrameLayout)getWindow().getDecorView()).addView(this.mCustomView, new FrameLayout.LayoutParams(-1, -1));
getWindow().getDecorView().setSystemUiVisibility(3846 | View.SYSTEM_UI_FLAG_LAYOUT_STABLE);
}
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(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
Log.e("Adi", "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, "Select image/video");
chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, intentArray);
startActivityForResult(chooserIntent, FILECHOOSER_RESULTCODE);
return true;
}
// creating image files (Lollipop only)
private File createImageFile() throws IOException {
File imageStorageDir = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES), "DirectoryNameHere");
if (!imageStorageDir.exists()) {
imageStorageDir.mkdirs();
}
// create an image file name
imageStorageDir = new File(imageStorageDir + File.separator + "IMG_" + String.valueOf(System.currentTimeMillis()) + ".jpg");
return imageStorageDir;
}
// openFileChooser for Android 3.0+
public void openFileChooser(ValueCallback<Uri> uploadMsg, String acceptType) {
mUploadMessage = uploadMsg;
try {
File imageStorageDir = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES), "DirectoryNameHere");
if (!imageStorageDir.exists()) {
imageStorageDir.mkdirs();
}
File file = new File(imageStorageDir + File.separator + "IMG_" + String.valueOf(System.currentTimeMillis()) + ".jpg");
mCapturedImageURI = Uri.fromFile(file); // save to the private variable
final Intent captureIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
captureIntent.putExtra(MediaStore.EXTRA_OUTPUT, mCapturedImageURI);
// captureIntent.putExtra(MediaStore.EXTRA_SCREEN_ORIENTATION, ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
Intent i = new Intent(Intent.ACTION_GET_CONTENT);
i.addCategory(Intent.CATEGORY_OPENABLE);
i.setType("image/*");
Intent chooserIntent = Intent.createChooser(i, "Select image/video");
chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, new Parcelable[]{captureIntent});
startActivityForResult(chooserIntent, FILECHOOSER_RESULTCODE);
} catch (Exception e) {
Toast.makeText(getBaseContext(), "Camera Exception:" + e, Toast.LENGTH_LONG).show();
}
}
// openFileChooser for Android < 3.0
public void openFileChooser(ValueCallback<Uri> uploadMsg) {
openFileChooser(uploadMsg, "");
}
// openFileChooser for other Android versions
/* may not work on KitKat due to lack of implementation of openFileChooser() or onShowFileChooser()
https://code.google.com/p/android/issues/detail?id=62220
however newer versions of KitKat fixed it on some devices */
public void openFileChooser(ValueCallback<Uri> uploadMsg, String acceptType, String capture) {
openFileChooser(uploadMsg, acceptType);
}
});
webView.setWebViewClient(new WebViewClient() {
#Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
view.loadUrl(url);
return true;
}
#Override
public void onPageStarted(WebView view, String url, Bitmap favicon) {
super.onPageStarted(view, url, favicon);
}
#Override
public void onPageFinished(WebView view, String url) {
super.onPageFinished(view, url);
progressDialog.dismiss();
}
});
}
// return here when file selected from camera or from SD Card
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
// code for all versions except of Lollipop
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
if (requestCode == FILECHOOSER_RESULTCODE) {
if (null == this.mUploadMessage) {
return;
}
Uri result = null;
try {
if (resultCode != RESULT_OK) {
result = null;
} else {
// retrieve from the private variable if the intent is null
result = data == null ? mCapturedImageURI : data.getData();
}
} catch (Exception e) {
Toast.makeText(getApplicationContext(), "activity :" + e, Toast.LENGTH_LONG).show();
}
mUploadMessage.onReceiveValue(result);
mUploadMessage = null;
}
} // end of code for all versions except of Lollipop
// start of code for Lollipop only
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
if (requestCode != FILECHOOSER_RESULTCODE || mFilePathCallback == null) {
super.onActivityResult(requestCode, resultCode, data);
return;
}
Uri[] results = null;
// check that the response is a good one
if (resultCode == Activity.RESULT_OK) {
if (data == null || data.getData() == 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)};
}
}
}
mFilePathCallback.onReceiveValue(results);
mFilePathCallback = null;
} // end of code for Lollipop only
}
}
I have an webview app and in one page I have a input type=file.
I was searching here for a solution but the answer was "no chance to make it work"
File Upload Not working in Android 4.4.2
The questions are a little old, I'd like to know if anyone know a solution for this.
My webview code:
public class MainActivity extends Activity {
private static final int INPUT_FILE_REQUEST_CODE = 1;
private static final int FILECHOOSER_RESULTCODE = 1;
private static final String TAG = MainActivity.class.getSimpleName();
private WebView webView;
private ValueCallback<Uri> mUploadMessage;
private Uri mCapturedImageURI = null;
private ValueCallback<Uri[]> mFilePathCallback;
private String mCameraPhotoPath;
SwipeRefreshLayout mySwipeRefreshLayout;
private ViewTreeObserver.OnScrollChangedListener mOnScrollChangedListener;
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
if (requestCode != INPUT_FILE_REQUEST_CODE || mFilePathCallback == null) {
super.onActivityResult(requestCode, resultCode, data);
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)};
}
}
}
mFilePathCallback.onReceiveValue(results);
mFilePathCallback = null;
} else if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.KITKAT) {
if (requestCode != FILECHOOSER_RESULTCODE || mUploadMessage == null) {
super.onActivityResult(requestCode, resultCode, data);
return;
}
Uri result = null;
try {
if (resultCode != RESULT_OK) {
result = null;
} else {
// retrieve from the private variable if the intent is null
result = data == null ? mCapturedImageURI : data.getData();
}
} catch (Exception e) {
Toast.makeText(getApplicationContext(), "activity :" + e,
Toast.LENGTH_LONG).show();
}
mUploadMessage.onReceiveValue(result);
mUploadMessage = null;
}
}
#SuppressLint("SetJavaScriptEnabled")
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
webView = findViewById(R.id.webView1);
WebSettings webSettings = webView.getSettings();
webSettings.setJavaScriptEnabled(true);
webSettings.setLoadWithOverviewMode(true);
webSettings.setAllowFileAccess(true);
webView.setWebViewClient(new Client());
webView.setWebChromeClient(new ChromeClient());
if (Build.VERSION.SDK_INT >= 19) {
webView.setLayerType(View.LAYER_TYPE_HARDWARE, null);
}
else {
webView.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
}
webView.loadUrl("https://www.exemple.com"); //change with your website
mySwipeRefreshLayout = findViewById(R.id.swipeContainer);
mySwipeRefreshLayout.setOnRefreshListener(
new SwipeRefreshLayout.OnRefreshListener() {
#Override
public void onRefresh() {
webView.reload();
if (mySwipeRefreshLayout.isRefreshing()) {
mySwipeRefreshLayout.setRefreshing(false);
}
}
}
);
mySwipeRefreshLayout.getViewTreeObserver().removeOnScrollChangedListener(mOnScrollChangedListener);
mySwipeRefreshLayout.getViewTreeObserver().addOnScrollChangedListener(mOnScrollChangedListener =
new ViewTreeObserver.OnScrollChangedListener() {
#Override
public void onScrollChanged() {
if (webView.getScrollY() == 0)
mySwipeRefreshLayout.setEnabled(true);
else
mySwipeRefreshLayout.setEnabled(false);
}
});
}
private File createImageFile() throws IOException {
// Create an image file name
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.US).format(new Date());
String imageFileName = "JPEG_" + timeStamp + "_";
File storageDir = Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_PICTURES);
File imageFile = File.createTempFile(
imageFileName, /* prefix */
".jpg", /* suffix */
storageDir /* directory */
);
return imageFile;
}
public class ChromeClient extends WebChromeClient {
// For Android 5.0
public boolean onShowFileChooser(WebView view, ValueCallback<Uri[]> filePath, WebChromeClient.FileChooserParams fileChooserParams) {
// Double check that we don't have any existing callbacks
if (mFilePathCallback != null) {
mFilePathCallback.onReceiveValue(null);
}
mFilePathCallback = filePath;
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if (takePictureIntent.resolveActivity(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
Log.e(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);
startActivityForResult(chooserIntent, INPUT_FILE_REQUEST_CODE);
return true;
}
// openFileChooser for Android 3.0+
void openFileChooser(ValueCallback<Uri> uploadMsg, String acceptType) {
mUploadMessage = uploadMsg;
// Create AndroidExampleFolder at sdcard
// Create AndroidExampleFolder at sdcard
File imageStorageDir = new File(
Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_PICTURES)
, "AndroidExampleFolder");
if (!imageStorageDir.exists()) {
// Create AndroidExampleFolder at sdcard
imageStorageDir.mkdirs();
}
// Create camera captured image file path and name
File file = new File(
imageStorageDir + File.separator + "IMG_"
+ String.valueOf(System.currentTimeMillis())
+ ".jpg");
mCapturedImageURI = Uri.fromFile(file);
// Camera capture image intent
final Intent captureIntent = new Intent(
android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
captureIntent.putExtra(MediaStore.EXTRA_OUTPUT, mCapturedImageURI);
Intent i = new Intent(Intent.ACTION_GET_CONTENT);
i.addCategory(Intent.CATEGORY_OPENABLE);
i.setType("image/*");
// Create file chooser intent
Intent chooserIntent = Intent.createChooser(i, "Image Chooser");
// Set camera intent to file chooser
chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS
, new Parcelable[] { captureIntent });
// On select image call onActivityResult method of activity
startActivityForResult(chooserIntent, FILECHOOSER_RESULTCODE);
}
// openFileChooser for Android < 3.0
public void openFileChooser(ValueCallback<Uri> uploadMsg) {
openFileChooser(uploadMsg, "");
}
//openFileChooser for other Android versions
public void openFileChooser(ValueCallback<Uri> uploadMsg,
String acceptType,
String capture) {
openFileChooser(uploadMsg, acceptType);
}
}
}
}
any ideas how to make input=file work in android 4.4.2?
I had "upload file success" with WebView which loaded the html5 page. But I have a problem in the code. My code as follows:
mWebView = (WebView) findViewById(R.id.wv_card);
WebSettings webSettings = mWebView.getSettings();
webSettings.setAllowFileAccess(true); // 设置允许访问文件数据
webSettings.setJavaScriptEnabled(true);
webSettings.setJavaScriptCanOpenWindowsAutomatically(true);
webSettings.setSupportZoom(false);
webSettings.setUseWideViewPort(true);
webSettings.setLoadWithOverviewMode(true);
mWebView.setWebChromeClient(new XHSWebChromeClient());
/**
* More info this method can be found at
* http://developer.android.com/training/camera/photobasics.html
*
* #return 创建的文件
* #throws IOException
*/
private File createImageFile() throws IOException {
// Create an image file name
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.CHINESE).format(new Date());
String imageFileName = "JPEG_" + timeStamp + "_";
String sdcard = Environment.getExternalStorageDirectory().toString();
File storageDir = new File(sdcard + "/WeiJuMei/Download");
return File.createTempFile(
imageFileName, /* prefix */
".jpg", /* suffix */
storageDir /* directory */
);
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
Uri uri = null;
try {
if (requestCode == FILE_CHOOSER_RESULT_CODE) {
if (null == mUploadMessage) return;
Uri result = data == null || resultCode != RESULT_OK ? null : data.getData();
if (result == null) {
mUploadMessage.onReceiveValue(null);
mUploadMessage = null;
return;
}
Log.i(TAG, "onActivityResult" + result.toString());
String path = FileUtils.getPath(this, result);
if (TextUtils.isEmpty(path)) {
mUploadMessage.onReceiveValue(null);
mUploadMessage = null;
return;
}
uri = Uri.fromFile(new File(path));
Log.i(TAG, "onActivityResult after parser uri:" + uri.toString());
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
// mUploadMessage.onReceiveValue(new Uri[]{uri});
if (/*requestCode != INPUT_FILE_REQUEST_CODE ||*/ mUploadMessage == null) {
super.onActivityResult(requestCode, resultCode, data);
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)};
}
}
}
mUploadMessage.onReceiveValue(results);
// mUploadMessage = null;
// return;
} else {
mUploadMessage.onReceiveValue(uri);
}
mUploadMessage = null;
}
} catch (Exception e) {
try {
mUploadMessage.onReceiveValue(uri);
mUploadMessage = null;
} catch (Exception e1) {
mUploadMessage.onReceiveValue(null);
mUploadMessage = null;
return;
}
}
}
public class XHSWebChromeClient extends WebChromeClient {
#Override
public void onProgressChanged(WebView webView, int newProgress) {
progressBar.setProgress(newProgress);
if (newProgress == 100) {
progressBar.setVisibility(View.GONE);
}
super.onProgressChanged(webView, newProgress);
}
#Override
public boolean onJsAlert(WebView webView, String s, String s1, JsResult jsResult) {
return super.onJsAlert(webView, s, s1, jsResult);
}
// For Android 3.0+
public void openFileChooser(ValueCallback<Uri> uploadMsg) {
Log.i(TAG, "in openFile Uri Callback");
if (mUploadMessage != null) {
mUploadMessage.onReceiveValue(null);
}
mUploadMessage = uploadMsg;
Intent i = new Intent(Intent.ACTION_GET_CONTENT);
i.addCategory(Intent.CATEGORY_OPENABLE);
i.setType("*/*");
startActivityForResult(Intent.createChooser(i, "File Chooser"), FILE_CHOOSER_RESULT_CODE);
}
// For Android 3.0+
public void openFileChooser(ValueCallback uploadMsg, String acceptType) {
Log.i(TAG, "in openFile Uri Callback has accept Type" + acceptType);
if (mUploadMessage != null) {
mUploadMessage.onReceiveValue(null);
}
mUploadMessage = uploadMsg;
Intent i = new Intent(Intent.ACTION_GET_CONTENT);
i.addCategory(Intent.CATEGORY_OPENABLE);
String type = TextUtils.isEmpty(acceptType) ? "*/*" : acceptType;
i.setType(type);
startActivityForResult(Intent.createChooser(i, "File Chooser"),
FILE_CHOOSER_RESULT_CODE);
}
// For Android 4.1
public void openFileChooser(ValueCallback<Uri> uploadMsg, String acceptType, String capture) {
Log.i(TAG, "in openFile Uri Callback has accept Type" + acceptType + "has capture" + capture);
if (mUploadMessage != null) {
mUploadMessage.onReceiveValue(null);
}
mUploadMessage = uploadMsg;
Intent i = new Intent(Intent.ACTION_GET_CONTENT);
i.addCategory(Intent.CATEGORY_OPENABLE);
String type = TextUtils.isEmpty(acceptType) ? "*/*" : acceptType;
i.setType(type);
startActivityForResult(Intent.createChooser(i, "File Chooser"), FILE_CHOOSER_RESULT_CODE);
}
// Android 5.0+
#Override
#SuppressLint("NewApi")
public boolean onShowFileChooser(WebView webView, ValueCallback<Uri[]> filePathCallback, android.webkit.WebChromeClient.FileChooserParams fileChooserParams) {
if (mUploadMessage != null) {
mUploadMessage.onReceiveValue(null);
}
mUploadMessage = filePathCallback;
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if (takePictureIntent.resolveActivity(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
Log.i(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);
startActivityForResult(chooserIntent, INPUT_FILE_REQUEST_CODE);
return true;
}
}
When choosing native image with Chinese path I found upload image was failing, but english path is successful, Why does this happen and how can I solve this problem?
I am creating a webview app. I want file chooser functionality from the webview. I successfully created the file chooser but it opens file manager to choose file.
Now I want camera to be open when user clicks on choose file.
public class MainActivity extends AppCompatActivity{
public static final String PAGE_URL = "http://192.168.94.1/fileupload/";
private static final int INPUT_FILE_REQUEST_CODE = 1;
private static final int FILECHOOSER_RESULTCODE = 1;
private static final String TAG = MainActivity.class.getSimpleName();
private WebView webView;
private WebSettings webSettings;
private ValueCallback<Uri> mUploadMessage;
private Uri mCapturedImageURI = null;
private ValueCallback<Uri[]> mFilePathCallback;
private String mCameraPhotoPath;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
webView = (WebView) findViewById(R.id.activity_main_webview);
webSettings = webView.getSettings();
webSettings.setJavaScriptEnabled(true);
webSettings.setLoadWithOverviewMode(true);
webSettings.setAllowFileAccess(true);
webView.setWebViewClient(new Client());
webView.setWebChromeClient(new ChromeClient());
if (Build.VERSION.SDK_INT >= 19) {
webView.setLayerType(View.LAYER_TYPE_HARDWARE, null);
} else if (Build.VERSION.SDK_INT >= 11 && Build.VERSION.SDK_INT < 19) {
webView.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
}
webView.loadUrl(Constants.URL);
}
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
if (requestCode != INPUT_FILE_REQUEST_CODE || mFilePathCallback == null) {
super.onActivityResult(requestCode, resultCode, data);
return;
}
Uri[] results = null;
if (resultCode == Activity.RESULT_OK) {
if (data == null) {
if (mCameraPhotoPath != null) {
results = new Uri[]{Uri.parse(mCameraPhotoPath)};
}
} else {
String dataString = data.getDataString();
if (dataString != null) {
results = new Uri[]{Uri.parse(dataString)};
}
}
}
mFilePathCallback.onReceiveValue(results);
mFilePathCallback = null;
} else if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.KITKAT) {
if (requestCode != FILECHOOSER_RESULTCODE || mUploadMessage == null) {
super.onActivityResult(requestCode, resultCode, data);
return;
}
if (requestCode == FILECHOOSER_RESULTCODE) {
if (null == this.mUploadMessage) {
return;
}
Uri result = null;
try {
if (resultCode != RESULT_OK) {
result = null;
} else {
result = data == null ? mCapturedImageURI : data.getData();
}
} catch (Exception e) {
Toast.makeText(getApplicationContext(), "activity :" + e,
Toast.LENGTH_LONG).show();
}
mUploadMessage.onReceiveValue(result);
mUploadMessage = null;
}
}
return;
}
private File createImageFile() throws IOException {
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
String imageFileName = "JPEG_" + timeStamp + "_";
File storageDir = Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_PICTURES);
File imageFile = File.createTempFile(
imageFileName, /* prefix */
".jpg", /* suffix */
storageDir /* directory */
);
return imageFile;
}
public class ChromeClient extends WebChromeClient {
public boolean onShowFileChooser(WebView view, ValueCallback<Uri[]> filePath, WebChromeClient.FileChooserParams fileChooserParams) {
if (mFilePathCallback != null) {
mFilePathCallback.onReceiveValue(null);
}
mFilePathCallback = filePath;
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if (takePictureIntent.resolveActivity(getPackageManager()) != null) {
File photoFile = null;
try {
photoFile = createImageFile();
takePictureIntent.putExtra("PhotoPath", mCameraPhotoPath);
} catch (IOException ex) {
Log.e(TAG, "Unable to create Image File", ex);
}
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);
startActivityForResult(chooserIntent, INPUT_FILE_REQUEST_CODE);
return true;
}
public void openFileChooser(ValueCallback<Uri> uploadMsg, String acceptType) {
mUploadMessage = uploadMsg;
File imageStorageDir = new File(
Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_PICTURES)
, "ViewPeer");
if (!imageStorageDir.exists()) {
imageStorageDir.mkdirs();
}
File file = new File(
imageStorageDir + File.separator + "IMG_"
+ String.valueOf(System.currentTimeMillis())
+ ".jpg");
mCapturedImageURI = Uri.fromFile(file);
final Intent captureIntent = new Intent(
android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
captureIntent.putExtra(MediaStore.EXTRA_OUTPUT, mCapturedImageURI);
Intent i = new Intent(Intent.ACTION_GET_CONTENT);
i.addCategory(Intent.CATEGORY_OPENABLE);
i.setType("image/*");
Intent chooserIntent = Intent.createChooser(i, "Image Chooser");
chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS
, new Parcelable[]{captureIntent});
startActivityForResult(chooserIntent, FILECHOOSER_RESULTCODE);
}
public void openFileChooser(ValueCallback<Uri> uploadMsg) {
openFileChooser(uploadMsg, "");
}
public void openFileChooser(ValueCallback<Uri> uploadMsg,
String acceptType,
String capture) {
openFileChooser(uploadMsg, acceptType);
}
}
public boolean onKeyDown(int keyCode, KeyEvent event) {
if ((keyCode == KeyEvent.KEYCODE_BACK) && webView.canGoBack()) {
webView.goBack();
return true;
}
return super.onKeyDown(keyCode, event);
}
public class Client extends WebViewClient {
ProgressDialog progressDialog;
public boolean shouldOverrideUrlLoading(WebView view, String url) {
if (url.contains("mailto:")) {
view.getContext().startActivity(
new Intent(Intent.ACTION_VIEW, Uri.parse(url)));
return true;
} else {
view.loadUrl(url);
return true;
}
}
public void onPageStarted(WebView view, String url, Bitmap favicon) {
if (progressDialog == null) {
progressDialog = new ProgressDialog(MainActivity.this);
progressDialog.setMessage("Loading...");
progressDialog.show();
}
}
public void onPageFinished(WebView view, String url) {
try {
if (progressDialog.isShowing()) {
progressDialog.dismiss();
progressDialog = null;
}
} catch (Exception exception) {
exception.printStackTrace();
}
}
}
}
The above code works fine but it opens file manager from where I can select an image. But I want to open camera from where user can directly click the image to upload.
Please help me :)
Instead of Intent chooserIntent = new Intent(Intent.ACTION_CHOOSER);
Use ACTION_IMAGE_CAPTURE like this
/*************************** Camera Intent Start ************************/
// Define the file-name to save photo taken by Camera activity
String fileName = "Camera_Example.jpg";
// Create parameters for Intent with filename
ContentValues values = new ContentValues();
values.put(MediaStore.Images.Media.TITLE, fileName);
values.put(MediaStore.Images.Media.DESCRIPTION,"Image capture by camera");
// imageUri is the current activity attribute, define and save it for later usage
imageUri = getContentResolver().insert(
MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
/**** EXTERNAL_CONTENT_URI : style URI for the "primary" external storage volume. ****/
// Standard Intent action that can be sent to have the camera
// application capture an image and return it.
Intent intent = new Intent( MediaStore.ACTION_IMAGE_CAPTURE );
intent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);
intent.putExtra(MediaStore.EXTRA_VIDEO_QUALITY, 1);
startActivityForResult( intent, CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE);
/*************************** Camera Intent End ************************/
I need to pick images from the device and upload it to the server. For the first time, when I pick the images, onShowFileChooser() gets called and everything works. But, when I try to click upload again, onShowFileChooser() never gets called. But it's working for non-lollypop devices. openFileChoser() gets called, whenever I click upload. Is there anything that I'm missing. Here is my code :
//Needed for file upload feature
vWebView.setWebChromeClient(new WebChromeClient() {
// file upload callback (Android 2.2 (API level 8) -- Android 2.3 (API level 10)) (hidden method)
public void openFileChooser(ValueCallback<Uri> filePathCallback) {
showAttachmentDialog(filePathCallback);
}
// file upload callback (Android 3.0 (API level 11) -- Android 4.0 (API level 15)) (hidden method)
public void openFileChooser(ValueCallback filePathCallback, String acceptType) {
showAttachmentDialog(filePathCallback);
}
// file upload callback (Android 4.1 (API level 16) -- Android 4.3 (API level 18)) (hidden method)
public void openFileChooser(ValueCallback<Uri> filePathCallback, String acceptType, String capture) {
showAttachmentDialog(filePathCallback);
}
// file upload callback (Android 5.0 (API level 21) -- current) (public method)
// for Lollipop, all in one
#Override
public boolean onShowFileChooser(
WebView webView, ValueCallback<Uri[]> filePathCallback,
WebChromeClient.FileChooserParams fileChooserParams) {
// Double check that we don't have any existing callbacks
if (mFilePathCallbackArray != null) {
mFilePathCallbackArray.onReceiveValue(null);
}
mFilePathCallbackArray = filePathCallback;
// Set up the take picture intent
if (mTypeCap == IMAGE) {
Intent takePictureIntent = pictureIntentSetup();
return showChooserDialog(takePictureIntent);
}
//set up video capture intent
else {
Intent takeVideoIntent = videoIntentSetUp();
return showChooserDialog(takeVideoIntent);
}
}
});
//For lollypop
private Intent pictureIntentSetup() {
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if (takePictureIntent.resolveActivity(getActivity().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
Log.e("Failed", "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;
}
}
return takePictureIntent;
}
//For lollypop
private Intent videoIntentSetUp() {
Intent takeVideoIntent = new Intent(MediaStore.ACTION_VIDEO_CAPTURE);
if (takeVideoIntent.resolveActivity(getActivity().getPackageManager()) != null) {
// create the file where the video should go
File videoFile = null;
try {
videoFile = createVideoFile();
takeVideoIntent.putExtra("PhotoPath", mCameraPhotoPath);
} catch (IOException ex) {
// Error occurred while creating the File
Log.e("Failed", "Unable to create Video File", ex);
}
// continue only if the file was successfully created
if (videoFile != null) {
mCameraPhotoPath = "file:" + videoFile.getAbsolutePath();
takeVideoIntent.putExtra(MediaStore.EXTRA_OUTPUT,
Uri.fromFile(videoFile));
} else {
takeVideoIntent = null;
}
}
return takeVideoIntent;
}
//For lollypop
private boolean showChooserDialog(Intent intent) {
Intent contentSelectionIntent = new Intent(Intent.ACTION_GET_CONTENT);
contentSelectionIntent.addCategory(Intent.CATEGORY_OPENABLE);
if (mTypeCap.equalsIgnoreCase(IMAGE))
contentSelectionIntent.setType(IMAGE);
else
contentSelectionIntent.setType(VIDEO);
Intent[] intentArray;
if (intent != null) {
intentArray = new Intent[]{intent};
} else {
intentArray = new Intent[0];
}
Intent chooserIntent = new Intent(Intent.ACTION_CHOOSER);
chooserIntent.putExtra(Intent.EXTRA_INTENT, contentSelectionIntent);
if (mTypeCap.equalsIgnoreCase(IMAGE))
chooserIntent.putExtra(Intent.EXTRA_TITLE, "Image Chooser");
else
chooserIntent.putExtra(Intent.EXTRA_TITLE, "Video Chooser");
chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, intentArray);
getActivity().startActivityForResult(chooserIntent, FILE_CHOOSER_RESULT_CODE);
return true;
}
OnActivityResult of the activity:
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
//File upload related
if (requestCode == NewsDetailFragment.FILE_CHOOSER_RESULT_CODE && (resultCode == RESULT_OK || resultCode == RESULT_CANCELED)) {
Fragment fragment = getSupportFragmentManager()
.findFragmentById(R.id.container);
if (fragment != null && fragment instanceof DetailFragment) {
Fragment currentFragment = ((DetailFragment) fragment).getCurrentFragment();
if (currentFragment instanceof WebDetailFragment)
currentFragment.onActivityResult(requestCode, resultCode, data);
}
}
}
}
onActivityResult of fragment:
#Override
public void onActivityResult(int requestCode, int resultCode, Intent intentData) {
super.onActivityResult(requestCode, resultCode, intentData);
// code for all versions except of Lollipop
if (!Utility.isLollypopAndAbove()) {
Uri result = null;
// check that the response is a good one
if (resultCode == Activity.RESULT_OK) {
if (requestCode == FILE_CHOOSER_RESULT_CODE) {
if (null == this.mFilePathCallback) {
return;
}
if (null == mFilePathCallback) return;
if (intentData == null) {
// if there is not data, then we may have taken a photo
if (mCameraPhotoPath != null) {
result = Uri.parse(mCameraPhotoPath);
}
} else {
String dataString = intentData.getDataString();
if (dataString != null) {
result = Uri.parse(dataString);
}
}
// Uri result = intentData == null || resultCode != Activity.RESULT_OK ? null
// : intentData.getData();
}
// for Lollipop only
}
mFilePathCallback.onReceiveValue(result);
mFilePathCallback = null;
}
else {
Uri[] results = null;
// check that the response is a good one
if(resultCode==Activity.RESULT_OK) {
if (requestCode == FILE_CHOOSER_RESULT_CODE) {
if (null == mFilePathCallbackArray) {
return;
}
if (intentData == 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 = intentData.getDataString();
if (dataString != null) {
results = new Uri[]{Uri.parse(dataString)};
}
}
}
}
mFilePathCallbackArray.onReceiveValue(results);
mFilePathCallbackArray = null;
return;
}
}
firstly, sorry to my english. you should return empty Uri[]{} to file receive
mUploadMessageForAndroid5.onReceiveValue(new Uri[]{});
my code can choose take photo or local image:
private static final int REQUEST_GET_THE_THUMBNAIL = 4000;
private static final long ANIMATION_DURATION = 200;
public final static int FILECHOOSER_RESULTCODE = 1;
public final static int FILECHOOSER_RESULTCODE_FOR_ANDROID_5 = 2;
//JS
webView.getSettings().setJavaScriptEnabled(true);
//set ChromeClient
webView.setWebChromeClient(getChromeClient());
//ChromeClinet配置
private WebChromeClient getChromeClient() {
return new WebChromeClient() {
//3.0++
public void openFileChooser(ValueCallback<Uri> uploadMsg, String acceptType) {
openFileChooserImpl(uploadMsg);
}
//3.0--
public void openFileChooser(ValueCallback<Uri> uploadMsg) {
openFileChooserImpl(uploadMsg);
}
public void openFileChooser(ValueCallback<Uri> uploadMsg, String acceptType, String capture) {
openFileChooserImpl(uploadMsg);
}
// For Android > 5.0
public boolean onShowFileChooser(WebView webView, ValueCallback<Uri[]> uploadMsg, WebChromeClient.FileChooserParams fileChooserParams) {
openFileChooserImplForAndroid5(uploadMsg);
return true;
}
};
}
private void openFileChooserImpl(ValueCallback<Uri> uploadMsg) {
mUploadMessage = uploadMsg;
new AlertDialog.Builder(mActivity)
.setItems(items, new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
if (items[which].equals(items[0])) {
Intent i = new Intent(Intent.ACTION_GET_CONTENT);
i.addCategory(Intent.CATEGORY_OPENABLE);
i.setType("image/*");
startActivityForResult(Intent.createChooser(i, "File Chooser"), FILECHOOSER_RESULTCODE);
} else if (items[which].equals(items[1])) {
dispatchTakePictureIntent();
}
dialog.dismiss();
}
})
.setOnCancelListener(new DialogInterface.OnCancelListener() {
#Override
public void onCancel(DialogInterface dialog) {
Log.v(TAG, TAG + " # onCancel");
mUploadMessage = null;
dialog.dismiss();
}})
.show();
}
private void openFileChooserImplForAndroid5(ValueCallback<Uri[]> uploadMsg) {
mUploadMessageForAndroid5 = uploadMsg;
new AlertDialog.Builder(mActivity)
.setItems(items, new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
if (items[which].equals(items[0])) {
Intent contentSelectionIntent = new Intent(Intent.ACTION_GET_CONTENT);
contentSelectionIntent.addCategory(Intent.CATEGORY_OPENABLE);
contentSelectionIntent.setType("image/*");
Intent chooserIntent = new Intent(Intent.ACTION_CHOOSER);
chooserIntent.putExtra(Intent.EXTRA_INTENT, contentSelectionIntent);
chooserIntent.putExtra(Intent.EXTRA_TITLE, "Image Chooser");
startActivityForResult(chooserIntent, FILECHOOSER_RESULTCODE_FOR_ANDROID_5);
} else if (items[which].equals(items[1])) {
dispatchTakePictureIntent();
}
dialog.dismiss();
}
})
.setOnCancelListener(new DialogInterface.OnCancelListener() {
#Override
public void onCancel(DialogInterface dialog) {
Log.v(TAG, TAG + " # onCancel");
//important to return new Uri[]{}, when nothing to do. This can slove input file wrok for once.
//InputEventReceiver: Attempted to finish an input event but the input event receiver has already been disposed.
mUploadMessageForAndroid5.onReceiveValue(new Uri[]{});
mUploadMessageForAndroid5 = null;
dialog.dismiss();
}}).show();
}
private void dispatchTakePictureIntent() {
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if (takePictureIntent.resolveActivity(mActivity.getPackageManager()) != null) {
// File file = new File(createImageFile());
Uri imageUri = null;
try {
imageUri = Uri.fromFile(createImageFile());
} catch (IOException e) {
e.printStackTrace();
}
//temp sd card file
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);
startActivityForResult(takePictureIntent, REQUEST_GET_THE_THUMBNAIL);
}
}
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 = new File(Environment.getExternalStorageDirectory().getAbsolutePath() + "/don_test/");
if (!storageDir.exists()) {
storageDir.mkdirs();
}
File image = File.createTempFile(
imageFileName, /* prefix */
".jpg", /* suffix */
storageDir /* directory */
);
// Save a file: path for use with ACTION_VIEW intents
mCurrentPhotoPath = image.getAbsolutePath();
return image;
}
#Override
public void onActivityResult(int requestCode, int resultCode, Intent intent) {
Log.v(TAG, TAG + " # onActivityResult # requestCode=" + requestCode + " # resultCode=" + resultCode);
if (requestCode == FILECHOOSER_RESULTCODE) {
if (null == mUploadMessage)
return;
Uri result = intent == null || resultCode != Activity.RESULT_OK ? null : intent.getData();
mUploadMessage.onReceiveValue(result);
mUploadMessage = null;
} else if (requestCode == FILECHOOSER_RESULTCODE_FOR_ANDROID_5) {
if (null == mUploadMessageForAndroid5)
return;
Uri result;
if (intent == null || resultCode != Activity.RESULT_OK) {
result = null;
} else {
result = intent.getData();
}
if (result != null) {
Log.v(TAG, TAG + " # result.getPath()=" + result.getPath());
mUploadMessageForAndroid5.onReceiveValue(new Uri[]{result});
} else {
mUploadMessageForAndroid5.onReceiveValue(new Uri[]{});
}
mUploadMessageForAndroid5 = null;
} else if (requestCode == REQUEST_GET_THE_THUMBNAIL) {
if (resultCode == Activity.RESULT_OK) {
File file = new File(mCurrentPhotoPath);
Uri localUri = Uri.fromFile(file);
Intent localIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, localUri);
mActivity.sendBroadcast(localIntent);
Uri result = Uri.fromFile(file);
mUploadMessageForAndroid5.onReceiveValue(new Uri[]{result});
mUploadMessageForAndroid5 = null;
} else {
File file = new File(mCurrentPhotoPath);
Log.v(TAG, TAG + " # file=" + file.exists());
if (file.exists()) {
file.delete();
}
}
}
}
Faced similar problem i was returning boolean value in method onShowFileChooser, issue was fixed when i called super class method
#Override
public boolean onShowFileChooser(WebView webView, ValueCallback<Uri[]> filePathCallback, FileChooserParams fileChooserParams) {
//Logic to implement
return super.onShowFileChooser(webView, filePathCallback, fileChooserParams);
}
In the onShowFileChooser() method you should return true, only if you are using the filePathCallback, which is the best way:
private ValueCallback<Uri[]> filePathCallback;
#Override
public boolean onShowFileChooser(
WebView webView, ValueCallback<Uri[]> filePathCallback,
WebChromeClient.FileChooserParams fileChooserParams) {
// do whatever you need to do, to show a file chooser/camera intent
this.filePathCallback = filePathCallback;
return true;
}
#Override
protected void onActivityResult(int requestCode, int resultCode,
Intent intent) {
// Check for your correct requestCode from your intent here
if (resultCode == RESULT_CANCELED) {
// this is important, call the callback with null parameter
this.filePathCallback.onReceiveValue(null);
} else if (resultCode == RESULT_OK) {
// extract the uri(s) you need here
this.filePathCallback.onReceiveValue(new Uri[]{result});
}
}
I had the similar issue that onShowFileChooser only works once. After few hours of trail and error and then I figured out using a simple experiment:
Not invoking ValueCallback will result onShowFileChooser only works once. Below code only works once...
override fun onShowFileChooser(
view: WebView?,
filePath: ValueCallback<Array<Uri>>?,
fileChooserParams: FileChooserParams?
): Boolean {
Log.i("blah", "<== onShowFileChooser ==>")
// filePath?.onReceiveValue(null)
return true
}
Properly invoking ValueCallback will make onShowFileChooser work every time:
override fun onShowFileChooser(
view: WebView?,
filePath: ValueCallback<Array<Uri>>?,
fileChooserParams: FileChooserParams?
): Boolean {
Log.i("blah", "<== onShowFileChooser ==>")
filePath?.onReceiveValue(null)
return true
}
so I just check all branches and make sure all properly invoking ValueCallback then the webview works as expected.
I had the same issue, the problem was I was expecting an OnActivityResult, but when you press the back button, this was not triggered.
The solution was implementing on onResume the following code, to tell the callback the answer was empty and being able to reuse it:
#Override
protected void onResume() {
super.onResume();
if (mFilePathCallbackArray == null)
return;
mFilePathCallbackArray.onReceiveValue(new Uri[]{});
mFilePathCallbackArray = null;
}
Just set a null value:
if (resultCode == Activity.RESULT_OK) {
handleImageRequest(data)
} else {
mValueCallbackArray?.onReceiveValue(null)
mValueCallbackArray = null
}
I had exactly same issue, But my use case is little different but my webview was loaded on a fragment as is in your code. first time the file chooser displayed fine on both Lollipop & pre Lollipop devices, but next time onwards it failed to display file chooser it self. The Reason being the I was not handled the onActivityResult in proper way at first time. My working code snippet is as follows for Lollipop:
#TargetApi(Build.VERSION_CODES.LOLLIPOP)
private boolean onActivityResultLolliPop(
int requestCode, int resultCode, Intent data) {
if (requestCode != SurveyWebChromeClient.FILE_CHOOSER_REQUEST_CODE
|| mFilePathCallbackL == null) {
super.onActivityResult(requestCode, resultCode, data);
return true;
}
Uri[] results = null;
if (resultCode == Activity.RESULT_OK) {
if (data == null) {
if (mCameraPhotoVideoPath != null) {//if there is not data here, then we may have taken a photo/video
results = new Uri[]{Uri.parse(mCameraPhotoVideoPath)};
}
} else {
String dataString = data.getDataString();
ClipData clipData = data.getClipData();
if (clipData != null) {
results = new Uri[clipData.getItemCount()];
for (int i = 0; i < clipData.getItemCount(); i++) {
ClipData.Item item = clipData.getItemAt(i);
results[i] = item.getUri();
}
}
if (dataString != null)
results = new Uri[]{Uri.parse(dataString)};
}
}
mFilePathCallbackL.onReceiveValue(results);
mFilePathCallbackL = null;
return false;
}
Just let onShowFIleChooser() return false, will work next time
public boolean onShowFileChooser(){
...
return **false**;
}
This is working for me (Kotlin, Jetpack compose)->
override fun onShowFileChooser(
webView: WebView?,
filePathCb: ValueCallback<Array<Uri>>?,
fileChooserParams: FileChooserParams?,
): Boolean {
if (filePathCallback != null) {
filePathCallback!!.onReceiveValue(null)
}
filePathCallback = filePathCb
return true
}
In future I can upload or reject the file upload->
if(onCloseCameraClick){
filePathCallback?.onReceiveValue(null)
filePathCallback = null
showMediaPicker = false
}
else{
filePathCallback?.onReceiveValue(arrayOf(uri))
filePathCallback = null
showMediaPicker = false
}