如何在webview中打开第三方URL上的选择文件意图?

问题描述 投票:1回答:1

我正在创建一个应用程序,其中有第三方URL,此URL在webview中打开。此URL包含

HTTPS

输入网址。这个网址在webview中打开。在第二个屏幕中,它显示选择文件,当我点击它时没有任何反应。

这是我使用的代码。

public static final int INPUT_FILE_REQUEST_CODE = 1;
public static final String EXTRA_FROM_NOTIFICATION = "EXTRA_FROM_NOTIFICATION";
private ValueCallback<Uri[]> mFilePathCallback;
private String mCameraPhotoPath;
WebView webView;
public WebSettings webSettings;

在onCreate里面

 webView = (WebView) view.findViewById(R.id.webview);

    webSettings = this.webView.getSettings();
    webSettings.setJavaScriptEnabled(true);
    webSettings.setDomStorageEnabled(true);
    WebViewClientImpl webViewClient = new WebViewClientImpl(getActivity());
    this.webView.setWebViewClient(webViewClient);
    this.webView.clearCache(true);

    this.webView.addJavascriptInterface(new WebAppInterface(getActivity()), "Android");
    this.webView.getSettings().setAppCacheEnabled(true);

    if (getPerspective().isNetworkAvailable()) {
        this.webView.loadUrl(videokycurl);
    } else {
        getPerspective().openNoInternetFragment();
    }

private class WebViewClientImpl extends WebViewClient {
    private Activity activity = null;

    WebViewClientImpl(Activity activity) {
        this.activity = activity;
    }

    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(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(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;
    }

    @Override
    public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) {
        handler.proceed();
    }

    @Override
    public void onPageStarted(WebView view, String url, Bitmap favicon) {
        super.onPageStarted(view, url, favicon);
        Log.e(TAG, "Page Start");
    }

    @Override
    public boolean shouldOverrideUrlLoading(WebView view, String url) {
        view.loadUrl(url);
        if (isCalled) {
            view.loadUrl(url);
            return shouldOverrideUrlLoading(view, url);
        }
        isCalled = false;
        return false;
    }

    @Override
    public void onPageFinished(WebView view, String url) {
        super.onPageFinished(view, url);
        Log.e(TAG, "Page Stop");
    }
}

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 = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
    File imageFile = File.createTempFile(
            imageFileName,  /* prefix */
            ".jpg",         /* suffix */
            storageDir      /* directory */
    );
    return imageFile;
}

public class WebAppInterface {
    Context mContext;

    WebAppInterface(Context c) {
        mContext = c;
    }

    @JavascriptInterface
    public void iron(String toast) {
        Log.e(TAG, "Value from Toast : " + toast);
        try {
            if (toast.equalsIgnoreCase("BankMandate")) {
                getPerspective().openBankMandateNotRegister("", "", "");
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
    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;
    return;
}

当我clicked选择一个文件时,注意到了。请帮助弄清楚这个错误在此先感谢。

android android-webview filechooser
1个回答
0
投票

使用下面的代码解决你的问题,我修改了你的课程

private static final int INPUT_FILE_REQUEST_CODE = 1;
private static final String TAG = ShowWebView.class.getSimpleName();
private WebView webView;
private WebSettings webSettings;
private ValueCallback<Uri[]> mUploadMessage;
private String mCameraPhotoPath = null;
private long size = 0;
String videokycurl;
ImageView img_back;

// Storage Permissions variables
private static final int REQUEST_EXTERNAL_STORAGE = 1;
private static String[] PERMISSIONS_STORAGE = {
        Manifest.permission.READ_EXTERNAL_STORAGE,
        Manifest.permission.WRITE_EXTERNAL_STORAGE,
        Manifest.permission.CAMERA
};

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (requestCode != INPUT_FILE_REQUEST_CODE || mUploadMessage == null) {
        super.onActivityResult(requestCode, resultCode, data);
        return;
    }
    try {
        String file_path = mCameraPhotoPath.replace("file:", "");
        File file = new File(file_path);
        size = file.length();

    } catch (Exception e) {
        Log.e("Error!", "Error while opening image file" + e.getLocalizedMessage());
    }

    if (data != null || mCameraPhotoPath != null) {
        Integer count = 0; //fix fby https://github.com/nnian
        ClipData images = null;
        try {
            images = data.getClipData();
        } catch (Exception e) {
            Log.e("Error!", e.getLocalizedMessage());
        }

        if (images == null && data != null && data.getDataString() != null) {
            count = data.getDataString().length();
        } else if (images != null) {
            count = images.getItemCount();
        }
        Uri[] results = new Uri[count];
        // Check that the response is a good one
        if (resultCode == Activity.RESULT_OK) {
            if (size != 0) {
                // If there is not data, then we may have taken a photo
                if (mCameraPhotoPath != null) {
                    results = new Uri[]{Uri.parse(mCameraPhotoPath)};
                }
            } else if (data.getClipData() == null) {
                results = new Uri[]{Uri.parse(data.getDataString())};
            } else {

                for (int i = 0; i < images.getItemCount(); i++) {
                    results[i] = images.getItemAt(i).getUri();
                }
            }
        }

        mUploadMessage.onReceiveValue(results);
        mUploadMessage = null;
    }
}

public static void verifyStoragePermissions(Activity activity) {
    // Check if we have read or write permission
    int writePermission = ActivityCompat.checkSelfPermission(activity, Manifest.permission.WRITE_EXTERNAL_STORAGE);
    int readPermission = ActivityCompat.checkSelfPermission(activity, Manifest.permission.READ_EXTERNAL_STORAGE);
    int cameraPermission = ActivityCompat.checkSelfPermission(activity, Manifest.permission.CAMERA);

    if (writePermission != PackageManager.PERMISSION_GRANTED || readPermission != PackageManager.PERMISSION_GRANTED || cameraPermission != PackageManager.PERMISSION_GRANTED) {
        // We don't have permission so prompt the user
        ActivityCompat.requestPermissions(
                activity,
                PERMISSIONS_STORAGE,
                REQUEST_EXTERNAL_STORAGE
        );
    }
}

现在在oncreate方法中这样做

verifyStoragePermissions(this);

webView = (WebView) findViewById(R.id.webview);
    webSettings = webView.getSettings();
    webSettings.setAppCacheEnabled(true);
    webView.clearCache(true);
    webSettings.setCacheMode(webSettings.LOAD_CACHE_ELSE_NETWORK);
    webSettings.setJavaScriptEnabled(true);
    webView.getSettings().setDomStorageEnabled(true);
    webSettings.setLoadWithOverviewMode(true);
    webSettings.setAllowFileAccess(true);
    this.webView.addJavascriptInterface(new WebAppInterface(this), "Android");
    webView.setWebViewClient(new PQClient());
    webView.setWebChromeClient(new PQChromeClient());
    //if SDK version is greater of 19 then activate hardware acceleration otherwise activate software acceleration
    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);
    }


    Log.e(TAG, "URL : " + videokycurl);
    webView.loadUrl(videokycurl);

现在创建一个扩展WebChromeClient的类“PQChromeClient”

public class PQChromeClient 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 (mUploadMessage != null) {
            mUploadMessage.onReceiveValue(null);
        }
        mUploadMessage = filePath;
        Log.e("FileCooserParams => ", filePath.toString());


        Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
        Intent takeVideoIntent = new Intent(MediaStore.ACTION_VIDEO_CAPTURE);
        Intent chooserIntent = new Intent(Intent.ACTION_CHOOSER);
        Intent contentSelectionIntent = new Intent(Intent.ACTION_GET_CONTENT);
        contentSelectionIntent.addCategory(Intent.CATEGORY_OPENABLE);
        contentSelectionIntent.setType("*/*");
        Intent[] intentArray = new Intent[]{takePictureIntent, takeVideoIntent};
        chooserIntent.putExtra(Intent.EXTRA_INTENT, contentSelectionIntent);
        chooserIntent.putExtra(Intent.EXTRA_TITLE, "Choose an action");
        chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, intentArray);
        startActivityForResult(chooserIntent, 1);
        return true;}}

public class PQClient extends WebViewClient {
    ProgressDialog progressDialog;

    @Override
    public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) {
        Log.e("SSL Error", "error: " + error.getPrimaryError());
        handler.proceed();
    }

    public boolean shouldOverrideUrlLoading(WebView view, String url) {

        // If url contains mailto link then open Mail Intent
        if (url.contains("mailto:")) {

            // 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 onPageStarted(WebView view, String url, Bitmap favicon) {

        // Then show progress  Dialog
        // in standard case YourActivity.this
        if (progressDialog == null) {
            progressDialog = new ProgressDialog(ShowWebView.this);
            progressDialog.setMessage("Loading...");
            progressDialog.hide();
        }
    }

    // Called when all page resources loaded
    public void onPageFinished(WebView view, String url) {
        webView.loadUrl("javascript:(function(){ " +
                "document.getElementById('android-app').style.display='none';})()");

        try {
            // Close progressDialog
            if (progressDialog.isShowing()) {
                progressDialog.dismiss();
                progressDialog = null;
            }
        } catch (Exception exception) {
            exception.printStackTrace();
        }
    }
}

如果您使用的是HTTPS url,则调用“onReceivedSslError”方法来覆盖代码中的SSL错误。希望这能解决您的问题。

© www.soinside.com 2019 - 2024. All rights reserved.