標籤:整合 log pos val 測試 圖庫 inpu 好的 err
這周遇到一個比較棘手的問題,需要在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開啟本地檔案瀏覽器的功能