Android-PWA-Wrapper icon indicating copy to clipboard operation
Android-PWA-Wrapper copied to clipboard

File input not working

Open maTorresani opened this issue 4 years ago • 1 comments

I had built the APK for my React website, and I just had one issue.

There are some pages in my website where I used HTML file input to allow the user to send an image to the form. When I try it on mobile navigator Chrome, it works fine opening the options camera or files, but in the app it is not opening anything I just click at the file input label and nothing happens.

I though it was permission issue and tried this: https://github.com/xtools-at/Android-PWA-Wrapper/issues/17. Now the app ask for the permissions CAMERA, READ_EXTERNAL_STORAGE and WRITE_EXTERNAL_STORAGE, but the input behavior stills the same.

So I have no idea what the problem is. Did anyone get the same problem?

maTorresani avatar Aug 15 '21 19:08 maTorresani

I also encountered this problem recently, and I solved it in this way: In MainActivity.java,add:

   @Override
    public void onActivityResult(int requestCode, int resultCode, Intent intent)
    {
        if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP)
        {
            if (requestCode == REQUEST_SELECT_FILE)
            {
                if (webViewHelper.uploadMessage == null)
                    return;
                webViewHelper.uploadMessage.onReceiveValue(WebChromeClient.FileChooserParams.parseResult(resultCode, intent));
                webViewHelper.uploadMessage = null;
            }
        }
        else if (requestCode == FILECHOOSER_RESULTCODE)
        {
            if (null == webViewHelper.mUploadMessage)
                return;
            // Use MainActivity.RESULT_OK if you're implementing WebView inside Fragment
            // Use RESULT_OK only if you're implementing WebView inside an Activity
            Uri result = intent == null || resultCode != MainActivity.RESULT_OK ? null : intent.getData();
            webViewHelper.mUploadMessage.onReceiveValue(result);
            webViewHelper.mUploadMessage = null;
        }
        else
            Toast.makeText(getApplicationContext(), "Failed to Upload Image", Toast.LENGTH_LONG).show();
    }

In WebViewHelper.java,add:

    public ValueCallback<Uri[]> uploadMessage;
    public ValueCallback<Uri> mUploadMessage;


private List<String> extractValidMimeTypes(String[] mimeTypes) {
        List<String> results = new ArrayList<String>();
        List<String> mimes;
        if (mimeTypes.length == 1 && mimeTypes[0].contains(",")) {
            mimes = Arrays.asList(mimeTypes[0].split(","));
        } else {
            mimes = Arrays.asList(mimeTypes);
        }
        MimeTypeMap mtm = MimeTypeMap.getSingleton();
        for (String mime : mimes) {
            if (mime != null && mime.trim().startsWith(".")) {
                String extensionWithoutDot = mime.trim().substring(1, mime.trim().length());
                String derivedMime = mtm.getMimeTypeFromExtension(extensionWithoutDot);
                if (derivedMime != null && !results.contains(derivedMime)) {
                    // adds valid mime type derived from the file extension
                    results.add(derivedMime);
                }
            } else if (mtm.getExtensionFromMimeType(mime) != null && !results.contains(mime)) {
                // adds valid mime type checked agains file extensions mappings
                results.add(mime);
            }
        }
        return results;
    }

In fuction setupwebview:

        webSettings.setAllowFileAccess(true);
        webSettings.setAllowContentAccess(true);

In webView.setWebChromeClient,add:

// For 3.0+ Devices (Start)
            // onActivityResult attached before constructor
            protected void openFileChooser(ValueCallback uploadMsg, String acceptType) {
                mUploadMessage = uploadMsg;
                Intent i = new Intent(Intent.ACTION_GET_CONTENT);
                i.addCategory(Intent.CATEGORY_OPENABLE);
                i.setType("image/*");
                activity.startActivityForResult(Intent.createChooser(i, "File Browser"), FILECHOOSER_RESULTCODE);
            }

            // For Lollipop 5.0+ Devices
            public boolean onShowFileChooser(WebView mWebView, ValueCallback<Uri[]> filePathCallback, WebChromeClient.FileChooserParams fileChooserParams) {
                if (uploadMessage != null) {
                    uploadMessage.onReceiveValue(null);
                    uploadMessage = null;
                }

                uploadMessage = filePathCallback;

                Intent intent = null;
                if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) {
                    intent = fileChooserParams.createIntent();
                    List<String> validMimeTypes = extractValidMimeTypes(fileChooserParams.getAcceptTypes());
                    if (validMimeTypes.isEmpty()) {
                        intent.setType("image/*");
                    } else {
                        intent.setType(String.join(" ", validMimeTypes));
                    }
                }
                try {
                    activity.startActivityForResult(intent, REQUEST_SELECT_FILE);
                } catch (ActivityNotFoundException e) {
                    uploadMessage = null;
                    Toast.makeText(activity.getApplicationContext(), "Cannot Open File Chooser", Toast.LENGTH_LONG).show();
                    return false;
                }
                return true;
            }


            public void showFileChooser(ValueCallback<String[]> filePathCallback,
                                        String acceptType, boolean paramBoolean) {
                Intent i = new Intent(Intent.ACTION_GET_CONTENT);
                i.addCategory(Intent.CATEGORY_OPENABLE);
                i.setType("image/*");
                activity.startActivityForResult(Intent.createChooser(i, "File Chooser"), FILECHOOSER_RESULTCODE);
            }

            public void showFileChooser(ValueCallback<String[]> uploadFileCallback,
                                        FileChooserParams fileChooserParams) {
                Intent i = new Intent(Intent.ACTION_GET_CONTENT);
                i.addCategory(Intent.CATEGORY_OPENABLE);
                i.setType("image/*");
                activity.startActivityForResult(Intent.createChooser(i, "File Chooser"), FILECHOOSER_RESULTCODE);
            }

mizhiyugan529 avatar Sep 02 '22 04:09 mizhiyugan529