Upload camera photo and filechooser from webview INPUT field

a 夏天 提交于 2019-11-30 04:05:47
user3459287

This is how I implemented camera upload and filechooser from WebView input field:

Below is the code for this important topic. The non relevant code is removed.

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 it will be helpful for someone :)

Solved. Inside my question, there's the functional code in case anyone needs it.

Here's the solution of the issues:

  1. Couldn't open camera/filechooser if I previously opened and cancelled:

    //inside onActivityResult
    if (resultCode != RESULT_OK) {
         mUploadMessage.onReceiveValue(null);
         return;
    }
    
  2. Get the "content://media/external/images/xxx" uri format, to upload the uri via "mUploadMessage.onReceiveValue(selectedImage);", avoiding a nullpointerexception

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

Resolved and its working fine.

Just look at the code of WebChromeClient class. You will find parameters are changed from earlier.

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

Solution:

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

Utilize same github code for your project.

Note: There is still issue with android 4.4 KitKat version. Except android 4.4 its working fine for other versions of Android.

Because this is still open defect from Google. Please check in the below link.

openFileChooser not called when is clicked on android 4.4 webview

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!