1. 程式人生 > >android webview中上傳控制元件點選無效的解決辦法

android webview中上傳控制元件點選無效的解決辦法

一、介紹

當我們在使用webview控制元件開啟一個web網頁時,如果we頁面中帶有<input type="file" ...>的控制元件,在webview中能正常顯示這個上傳控制元件,但是你會發現無論你如何點選都無效果,這個是很讓人惱火的,一時也不知道如何下手去改,這裡阿湯哥會告訴你如何解決該問題,如果我的解決辦法能幫到你,請給我點掌聲,並給你自己點掌聲。

二、解決辦法

第一步:重寫WebChromeClient

webview的坑比較多,在這個上傳檔案的坑中遇到一個問題:

Android 5.0+ 重寫onShowFileChooser生效;

Android 4.4   重寫openFileChooser沒有生效;

Android 4.4- 重寫openFileChooser生效;

import android.net.Uri;
import android.webkit.ValueCallback;
import android.webkit.WebChromeClient;
import android.webkit.WebView;

/**
 * Created by tangbin on 16/5/12.
 */
public class MyWebChromeClient extends WebChromeClient {

    private WebCall webCall;

    public void setWebCall(WebCall webCall) {
        this.webCall = webCall;
    }

    // For Android 3.0+
    public void openFileChooser(ValueCallback<Uri> uploadMsg, String acceptType) {
        if (webCall != null)
            webCall.fileChose(uploadMsg);
    }

    // For Android < 3.0
    public void openFileChooser(ValueCallback<Uri> uploadMsg) {
        openFileChooser(uploadMsg, "");
    }

    // For Android > 4.1.1
    public void openFileChooser(ValueCallback<Uri> uploadMsg,
            String acceptType, String capture) {
        openFileChooser(uploadMsg, acceptType);
    }

    // For Android > 5.0
    @Override
    public boolean onShowFileChooser(WebView webView,
            ValueCallback<Uri[]> filePathCallback,
            FileChooserParams fileChooserParams) {
        if (webCall != null)
            webCall.fileChose5(filePathCallback);
        return super.onShowFileChooser(webView, filePathCallback,
                fileChooserParams);
    }

    public interface WebCall {
        void fileChose(ValueCallback<Uri> uploadMsg);

        void fileChose5(ValueCallback<Uri[]> uploadMsg);
    }

}


第二步:監聽ValueCallback

WebSettings webSettings = mWebView.getSettings();
        // 設定WebView屬性,能夠執行Javascript指令碼
        webSettings.setJavaScriptEnabled(true);
        // 設定可以訪問檔案
        webSettings.setAllowFileAccess(true);
        mWebView.setWebViewClient(new webViewClient());
    public final static int FILECHOOSER_RESULTCODE = 1;
    public final static int FILECHOOSER_RESULTCODE_FOR_ANDROID_5 = 2;
    public ValueCallback<Uri> mUploadMessage;
    public ValueCallback<Uri[]> mUploadMessageForAndroid5;

    @Override
    public void fileChose(ValueCallback<Uri> uploadMsg) {
        openFileChooserImpl(uploadMsg);
    }

    @Override
    public void fileChose5(ValueCallback<Uri[]> uploadMsg) {
        openFileChooserImplForAndroid5(uploadMsg);
    }

    private void openFileChooserImpl(ValueCallback<Uri> uploadMsg) {
        mUploadMessage = uploadMsg;
        Intent i = new Intent(Intent.ACTION_GET_CONTENT);
        i.addCategory(Intent.CATEGORY_OPENABLE);
        i.setType("image/*");
        startActivityForResult(Intent.createChooser(i, "File Chooser"),
                FILECHOOSER_RESULTCODE);
    }

    private void openFileChooserImplForAndroid5(ValueCallback<Uri[]> uploadMsg) {
        mUploadMessageForAndroid5 = uploadMsg;
        Intent contentSelectionIntent = new Intent(Intent.ACTION_GET_CONTENT);
        contentSelectionIntent.addCategory(Intent.CATEGORY_OPENABLE);
        contentSelectionIntent.setType("image/*");

        Intent chooserIntent = new Intent(Intent.ACTION_CHOOSER);
        chooserIntent.putExtra(Intent.EXTRA_INTENT, contentSelectionIntent);
        chooserIntent.putExtra(Intent.EXTRA_TITLE, "Image Chooser");

        startActivityForResult(chooserIntent,
                FILECHOOSER_RESULTCODE_FOR_ANDROID_5);
    }

第三步:建立onActivityResult

    @Override
    protected void onActivityResult(int requestCode, int resultCode,
            Intent intent) {
        if (requestCode == FILECHOOSER_RESULTCODE) {
            if (null == mUploadMessage)
                return;
            Uri result = intent == null || resultCode != RESULT_OK ? null
                    : intent.getData();
            mUploadMessage.onReceiveValue(result);
            mUploadMessage = null;

        } else if (requestCode == FILECHOOSER_RESULTCODE_FOR_ANDROID_5) {
            if (null == mUploadMessageForAndroid5)
                return;
            Uri result = (intent == null || resultCode != RESULT_OK) ? null
                    : intent.getData();
            if (result != null) {
                mUploadMessageForAndroid5.onReceiveValue(new Uri[] { result });
            } else {
                mUploadMessageForAndroid5.onReceiveValue(new Uri[] {});
            }
            mUploadMessageForAndroid5 = null;
        }
    }
搞定,最後就可以如願以償的完成檔案上傳了功能了