Upload camera and camera file from INPUT web view

My application is website-based and I need to upload photos from the INPUT field camp. I have two situations, and since I don’t know another way to do this, depending on the page that I select one or the other using "boolean boolFileChoser" depending on the request of the URL:

a. file collector

b. photo shoot camera.

I was collecting files and fully uploaded the file, there is a problem with the camera. As soon as I try to load Pic Pic, it will work. As far as I know it, because URI.

a) File picker: content: // media / external / images / 1234

b) Camera shooting: file: ///mnt/sdcard/Pic.jpg

I did not find a way to change it.

See update

Now it crashes due to a nullpointer error when trying to load "content: // media / external / images / 1234". (only with a camera, not a file selection.). In addition, if the selection / camera switch is closed (back button), I cannot call it again. Strike>

Case a) and b) is 100% working, here is the working code, including how I know if fileChooser or camera are called:

@Override protected void onActivityResult(int requestCode, int resultCode, Intent intent) { if (resultCode != RESULT_OK) { /** fixed code **/ //To be able to use the filechooser again in case of error mUploadMessage.onReceiveValue(null); /** fixed code **/ return; } if (mUploadMessage==null) { Log.d("androidruntime","no mUploadMessage"); return; } if (requestCode == FILECHOOSER_RESULTCODE) { Uri selectedImage= intent == null || resultCode != RESULT_OK ? null : intent.getData(); Log.d("androidruntime","url: "+selectedImage.toString()); }else if (requestCode == CAMERAREQUEST_RESULTCODE) { if(mCapturedImageURI==null){ Log.d("androidruntime","no mCapturedImageURI"); return; } /** fixed code **/ getContentResolver().notifyChange(mCapturedImageURI, null); ContentResolver cr = getContentResolver(); Uri uriContent= Uri.parse(MediaStore.Images.Media.insertImage(getContentResolver(), photo.getAbsolutePath(), null, null)); photo = null; /** fixed code **/ } mUploadMessage.onReceiveValue(selectedImage); mUploadMessage = null; } private static final int FILECHOOSER_RESULTCODE = 2888; private static final int CAMERAREQUEST_RESULTCODE = 1888; private ValueCallback<Uri> mUploadMessage; private Uri mCapturedImageURI = null; protected class AwesomeWebChromeClient extends WebChromeClient{ // Per Android 3.0+ public void openFileChooser(ValueCallback<Uri> uploadMsg, String acceptType){ /**updated, out of the IF **/ mUploadMessage = uploadMsg; /**updated, out of the IF **/ if(boolFileChooser){ //Take picture from filechooser Intent i = new Intent(Intent.ACTION_GET_CONTENT); i.addCategory(Intent.CATEGORY_OPENABLE); i.setType("image/*"); MainActivity.this.startActivityForResult( Intent.createChooser( i, "Escoger Archivo" ), MainActivity.FILECHOOSER_RESULTCODE ); } else { //Take photo and upload picture Intent cameraIntent = new Intent("android.media.action.IMAGE_CAPTURE"); File photo = new File(Environment.getExternalStorageDirectory(), "Pic.jpg"); cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(photo)); mCapturedImageURI = Uri.fromFile(photo); startActivityForResult(cameraIntent, MainActivity.CAMERA_REQUEST); } } // Per Android < 3.0 public void openFileChooser(ValueCallback<Uri> uploadMsg){ openFileChooser(uploadMsg, ""); } //Altre public void openFileChooser(ValueCallback<Uri> uploadMsg, String acceptType, String capture) { openFileChooser(uploadMsg, ""); } /** Added code to clarify chooser. **/ //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", "Per cònsola: " + cm.message()); if(message.endsWith("foto")){ boolFileChooser= true; } else if(message.endsWith("pujada")){ boolFileChooser= false; } } /** Added code to clarify chooser. **/ } 

UPDATE 1

I could get the uri format "content: // media / external / images / xxx", but the application still crashes when trying to load uri via "mUploadMessage.onReceiveValue (selectedImage)". Now I get a nullpointer exception.


UPDATE 2

Fixed and working.

I had "ValueCallback uploadMsg" in a local variable only in the case of file selection, so it always threw me an exception when I tried to upload a photo file because it was null. As soon as I removed from the if-else statement, everything worked. The previous update was the easiest method to upload files.

I already added 'mUploadMessage.onReceiveValue (null);' if the intent of Camera / filechooser is canceled (you must deal with it on your web page), if not, you cannot run the INPUT (Intent) field again.


UPDATE 3

A part of the code has been added inside AwesomeChromeClient to distinguish this parameter, take a picture or select a file. its MY way to do this and add to the petition, I'm sure there are many other valid ways to do this,

Now the code is 100% functional. If you indicate whether you want to select an image or file

+4
source share
3 answers

solved. There is functional code inside my question if anyone needs it.

Here's a solution to the problems:

  • Could not open camera / filechooser if I previously opened and canceled:

     //inside onActivityResult if (resultCode != RESULT_OK) { mUploadMessage.onReceiveValue(null); return; } 
  • Get the uri format "content: // media / external / images / xxx" to load uri through "mUploadMessage.onReceiveValue (selectedImage);" avoiding the nullpointerexception error

     //inside OnActivityResult getContentResolver().notifyChange(mCapturedImageURI, null); ContentResolver cr = getContentResolver(); Uri uriContent = Uri.parse(android.provider.MediaStore.Images.Media.insertImage(getContentResolver(), photo.getAbsolutePath(), null, null)); 
+2
source

Sorry to write in my post, but this is how I loaded the camera and filechooser from the WebView input field:

Below is the code for this important topic, the rest of the irrelevant code is deleted.

 public class MainActivity extends Activity { private WebView webView; private String urlStart = "http://www.example.com/mobile/"; //File choser parameters private static final int FILECHOOSER_RESULTCODE = 2888; private ValueCallback<Uri> mUploadMessage; //Camera parameters private Uri mCapturedImageURI = null; @SuppressLint("SetJavaScriptEnabled") @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); webView = (WebView) findViewById(R.id.webView); webView.getSettings().setJavaScriptEnabled(true); webView.getSettings().setLoadWithOverviewMode(true); webView.getSettings().setAllowFileAccess(true); webView.loadUrl(urlStart); webView.setWebChromeClient(new WebChromeClient() { // openFileChooser for Android 3.0+ public void openFileChooser(ValueCallback<Uri> uploadMsg, String acceptType) { mUploadMessage = uploadMsg; try{ Intent cameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); File externalDataDir = Environment.getExternalStoragePublicDirectory( Environment.DIRECTORY_DCIM); File cameraDataDir = new File(externalDataDir.getAbsolutePath() + File.separator + "browser-photos"); cameraDataDir.mkdirs(); String mCameraFilePath = cameraDataDir.getAbsolutePath() + File.separator + System.currentTimeMillis() + ".jpg"; mCapturedImageURI = Uri.fromFile(new File(mCameraFilePath)); cameraIntent.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[] { cameraIntent }); startActivityForResult(chooserIntent, FILECHOOSER_RESULTCODE); } catch(Exception e){ Toast.makeText(getBaseContext(), "Camera Exception:"+e, Toast.LENGTH_LONG).show(); } } // For Android < 3.0 @SuppressWarnings("unused") public void openFileChooser(ValueCallback<Uri> uploadMsg ) { openFileChooser(uploadMsg, ""); } // For Android > 4.1.1 @SuppressWarnings("unused") public void openFileChooser(ValueCallback<Uri> uploadMsg, String acceptType, String capture){ openFileChooser(uploadMsg, acceptType); } 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", "www.example.com: " + message); } }); } @Override protected void onActivityResult(int requestCode, int resultCode, Intent intent) { // TODO Auto-generated method stub 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(); } } catch(Exception e) { Toast.makeText(getApplicationContext(), "activity :"+e, Toast.LENGTH_LONG).show(); } mUploadMessage.onReceiveValue(result); mUploadMessage = null; } } 

I hope someone will be helpful :)

+5
source

Solved and working fine.

Just take a look at the code for the WebChromeClient class. You will see that the settings are changed earlier.

 public boolean onShowFileChooser(WebView webView, ValueCallback<Uri[]> filePathCallback, WebChromeClient.FileChooserParams fileChooserParams) { throw new RuntimeException("Stub!"); } 

Decision:

You just follow the latest ChromeBrowser code in this github link Android Chrome Browser Code on Github

Use the same github code for your project.

Note. Problem with KitKat version for Android 4.0. Besides android 4.4, it works great for other versions of Android.

Because it is still an open defect from Google. Please check the link below.

openFileChooser not called when clicked on android 4.4 web browser

+1
source

Source: https://habr.com/ru/post/1444746/


All Articles