1. 程式人生 > >android webview處理h5打開本地文件瀏覽器的功能

android webview處理h5打開本地文件瀏覽器的功能

utility || 簡單的 mfile () 怎樣 測試的 params 後來

這周遇到一個比較棘手的問題,需要在android上邊集成h5頁面,並且在h5頁面上,需要用戶能夠上傳android本地的照片,一開始我以為webview會自動處理掉的,因此沒太留意,當真正集成時,才發現,h5界面上傳圖片無法打開本地android的圖庫,h5調用的方式是:

<input type = "file"/>

通過最為簡單的input菜單來選擇,於是我就百度了一波,找到了兩種比較好的解決方法,一種是h5編寫js代碼,調用android app實現的函數,來實現打開圖庫進行圖片選擇的功能,還有一種方法是,通過重寫webview中WebChromeClient類,然後來進行實現打開本地圖庫的功能。

在這主要講述第二種方法的實現。

我這先放上重寫的代碼:

public class OpenFileWebChromeClient extends WebChromeClient {
    public String TAG = "OpenFileWebChromeClient";
    public static final int REQUEST_FILE_PICKER = 1;
    public ValueCallback<Uri> mFilePathCallback;
    public ValueCallback<Uri[]> mFilePathCallbacks;
    private Activity mContext;
    private TextView textView;

    public OpenFileWebChromeClient(Activity mContext) {
        super();
        this.mContext = mContext;
    }

    /**
     * Android < 3.0 調用這個方法
     */
    public void openFileChooser(ValueCallback<Uri> filePathCallback) {
        mFilePathCallback = filePathCallback;
        Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
        intent.addCategory(Intent.CATEGORY_OPENABLE);
        intent.setType("image/*");
        mContext.startActivityForResult(Intent.createChooser(intent, "File Chooser"),
                REQUEST_FILE_PICKER);
    }

    /**
     * 3.0 + 調用這個方法
     */
    public void openFileChooser(ValueCallback filePathCallback,
                                String acceptType) {
        mFilePathCallback = filePathCallback;
        Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
        intent.addCategory(Intent.CATEGORY_OPENABLE);
        intent.setType("image/*");
        mContext.startActivityForResult(Intent.createChooser(intent, "File Chooser"),
                REQUEST_FILE_PICKER);
    }

    /**
     * js上傳文件的<input type="file" name="fileField" id="fileField" />事件捕獲
     */

    /**
     * Android > 4.1.1 調用這個方法
     */
    @Deprecated
    public void openFileChooser(ValueCallback<Uri> filePathCallback,
                                String acceptType, String capture) {
        mFilePathCallback = filePathCallback;
        Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
        intent.addCategory(Intent.CATEGORY_OPENABLE);
        intent.setType("image/*");
        mContext.startActivityForResult(Intent.createChooser(intent, "File Chooser"),
                REQUEST_FILE_PICKER);
    }

    @Override
    public boolean onShowFileChooser(WebView webView,
                                     ValueCallback<Uri[]> filePathCallback,
                                     WebChromeClient.FileChooserParams fileChooserParams) {
        mFilePathCallbacks = filePathCallback;
        Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
        intent.addCategory(Intent.CATEGORY_OPENABLE);
        intent.setType("image/*");
        mContext.startActivityForResult(Intent.createChooser(intent, "File Chooser"),
                REQUEST_FILE_PICKER);
        return true;
    }

}

這樣既可打開本地的圖庫,當然,這只是能夠打開了,選擇後的圖片又怎樣返回給h5頁面呢?

需要在activity中實現如下的代碼:

    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent intent) {
        if (requestCode == OpenFileWebChromeClient.REQUEST_FILE_PICKER) {
            if (mOpenFileWebChromeClient.mFilePathCallback != null) {
                Uri result = intent == null || resultCode != Activity.RESULT_OK ? null
                        : intent.getData();
                if (result != null) {
                    String path = MediaUtility.getPath(getApplicationContext(),
                            result);
                    Uri uri = Uri.fromFile(new File(path));
                    mOpenFileWebChromeClient.mFilePathCallback
                            .onReceiveValue(uri);
                } else {
                    mOpenFileWebChromeClient.mFilePathCallback
                            .onReceiveValue(null);
                }
            }
            if (mOpenFileWebChromeClient.mFilePathCallbacks != null) {
                Uri result = intent == null || resultCode != Activity.RESULT_OK ? null
                        : intent.getData();
                if (result != null) {
                    String path = MediaUtility.getPath(getApplicationContext(),
                            result);
                    Uri uri = Uri.fromFile(new File(path));
                    mOpenFileWebChromeClient.mFilePathCallbacks
                            .onReceiveValue(new Uri[] { uri });
                } else {
                    mOpenFileWebChromeClient.mFilePathCallbacks
                            .onReceiveValue(null);
                }
            }

            mOpenFileWebChromeClient.mFilePathCallback = null;
            mOpenFileWebChromeClient.mFilePathCallbacks = null;
        }
    }

這樣,返回的數據則是h5頁面需要的數據,這樣一來,h5就可以像在電腦上一樣的,對返回的數據進行操作,可以進行實時的預覽,上傳等功能。

但是對於以上的方法,我們在測試的時候發現,在android4.4上是不支持的,原因則是android4.4的webview沒有對onShowFileChooser和openFileChooser做任何的處理,因此不支持,這算是android上的一個坑吧。

最後,記得添加權限,因為要讀取本地的圖片,所以要獲取讀本地sdcard的權限!

  

android webview處理h5打開本地文件瀏覽器的功能