4

I have kept an html file on a website.

https://pinapakait.com/cam/testcam.html

It has following simple input type file code input type="file" accept="image/*;capture=camera"

It is opening files, camera options when opened in mobile through web browser. But now opening in web view of android.

Your help is very much appreciated.

Gave following permissions

uses-permission android:name="android.permission.INTERNET" 
uses-permission android:name="android.permission.CAMERA" 
uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"
uses-feature android:name="android.hardware.camera" android:required="true"
uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"

uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"
uses-permission android:name="android.permission.WRITE_INTERNAL_STORAGE"
uses-permission android:name="android.permission.READ_INTERNAL_STORAGE" 

set following settings for web view.

    setLoadsImagesAutomatically(true)
    setJavaScriptEnabled(true)
    setDomStorageEnabled(true)
    setLoadWithOverviewMode(true)
    setPluginState(WebSettings.PluginState.ON)
    setMediaPlaybackRequiresUserGesture(false)
    setPluginState(WebSettings.PluginState.ON)
    setAppCacheEnabled(true)

    setScrollBarStyle(View.SCROLLBARS_INSIDE_OVERLAY)
    setAllowFileAccessFromFileURLs(true)
    setAllowUniversalAccessFromFileURLs(true)
    setJavaScriptCanOpenWindowsAutomatically(true)
    setBuiltInZoomControls(true)

    setPluginsEnabled(true)
    setAllowFileAccess(true)
    setAllowContentAccess(true)
    setSupportZoom(true)

1 Answer 1

3

I had same problem with webview and after googling it I found this solution by extending WebChromeClient .

    public class MyWebChromeClient extends WebChromeClient {

    DetailsFragmentWebView context;
    public ValueCallback<Uri> mUploadMessage;
    public ValueCallback<Uri[]> mUploadMessageAboveL;
    public Uri mCapturedImageURI;

    public MyWebChromeClient(DetailsFragmentWebView context){
        this.context = context;
        //this.mCapturedImageURI = mCapturedImageURI;
        //this.mUploadMessage = mUploadMessage;
        //this.mUploadMessageAboveL = mUploadMessageAboveL;
    }

    // openFileChooser for Android 3.0+
    public void openFileChooser(ValueCallback<Uri> uploadMsg, ValueCallback<Uri[]> uploadMsgAboveL, String acceptType){

        // Update message
        mUploadMessage = uploadMsg;
        mUploadMessageAboveL = uploadMsgAboveL;
        try{

            // 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
            context.startActivityForResult(chooserIntent, FILECHOOSER_RESULTCODE);

        }
        catch(Exception e){
            Toast.makeText(context.getActivity(), "Chrome Exception:"+e,
                    Toast.LENGTH_LONG).show();
        }

    }


    //openFileChooser for other Android versions
    public void openFileChooser(ValueCallback<Uri> uploadMsg,
                                String acceptType,
                                String capture) {

        openFileChooser(uploadMsg , mUploadMessageAboveL, acceptType);
    }

    @Override
    public boolean onShowFileChooser(WebView webView, ValueCallback<Uri[]> filePathCallback, FileChooserParams fileChooserParams) {
        openFileChooser(null ,filePathCallback , "");
        return true;
    }
}

And set your webview to use this class :

MyWebChromeClient  myChromeClient = new myChromeClient(this);
webView.webChromeClient = myChromeClient;

Also you need to add this code to your Activity :

    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
    //super.onActivityResult(requestCode, resultCode, data)
    if (requestCode == FILECHOOSER_RESULTCODE) {
        if (null == myChromeClient.mUploadMessage && null == myChromeClient.mUploadMessageAboveL) return
        val result = if (resultCode != RESULT_OK) null
                        else if (data!=null) data.data
                        else myChromeClient.mCapturedImageURI
        if (myChromeClient.mUploadMessageAboveL != null) {
            onActivityResultAboveL(requestCode, resultCode, data)
        } else if (myChromeClient.mUploadMessage != null) {
            myChromeClient.mUploadMessage?.onReceiveValue(result)
            myChromeClient.mUploadMessage = null
        }
    }
}

@TargetApi(Build.VERSION_CODES.LOLLIPOP)
private fun onActivityResultAboveL(requestCode: Int, resultCode: Int, intent: Intent?) {
    if (requestCode != FILECHOOSER_RESULTCODE || myChromeClient.mUploadMessageAboveL == null)
        return
    var results: Array<Uri>? = null
    if (resultCode == Activity.RESULT_OK) {
        if (intent != null) {
            val dataString = intent.dataString
            val clipData = intent.clipData
            if (clipData != null) {
                results = Array<Uri>(clipData.itemCount) { _->return Unit}
                for (i in 0 until clipData.itemCount) {
                    val item = clipData.getItemAt(i)
                    results[i] = item.uri
                }
            }
            if (dataString != null)
                results = arrayOf(Uri.parse(dataString))
        }else if (myChromeClient.mCapturedImageURI!=null)
            results = arrayOf(myChromeClient.mCapturedImageURI)
    }
    myChromeClient.mUploadMessageAboveL?.onReceiveValue(results)
    myChromeClient.mUploadMessageAboveL = null
}
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.