1. 程式人生 > >關於webview適配H5上傳照片或者視訊檔案的方法

關於webview適配H5上傳照片或者視訊檔案的方法

一、需要實現的功能:

用H5實現的App中需要在H5獲取手機中的照片或者視訊檔案上傳到伺服器。

二、分析實現方法:

由於不懂前端開發,不知道H5中有 input file之類的標籤控制元件,可以用來選擇檔案,剛開始的思路還是想著native 端是否要通過提供inputstream流方式,將檔案內容傳遞給JS。後來和前端溝通之後,H5在電腦端都是用input 設定type為 file 來實現檔案選擇功能,於是才開始搜尋資料,發現時需要在webview中設定  setWebChromeClient ,其中有對input 的響應回撥:


三、具體實現:

前端程式碼

<input type="file" accept=
"*/*" name="choose file"> <br/><br/> <input type="file" accept="image/*" name="choose image"> <br/><br/> <input type="file" accept="video/*" name="choose video"> <br/><br/> <input type="file" accept="image/example" name="take photo and upload image"> <br/><br/>
<input type="file" accept="video/example" name="take video and upload video"> <br/><br/>

native端程式碼:

@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
@Override
public boolean onShowFileChooser(WebView webView,
ValueCallback<Uri[]> filePathCallback,
WebChromeClient.FileChooserParams fileChooserParams) {
    mFilePathCallbacks 
= filePathCallback; // TODO: 根據標籤中得接收型別,啟動對應的檔案型別選擇器 String[] acceptTypes = fileChooserParams.getAcceptTypes(); for (String type : acceptTypes) { Log.d(TAG, "acceptTypes=" + type); } // 針對拍照後馬上進入上傳狀態處理 if ((acceptTypes.length > 0) && acceptTypes[0].equals("image/example")) { Log.d(TAG, "onShowFileChooser takePhoto"); Intent it = CameraFunction.takePhoto(mContext); startActivityForResult(it, TAKE_PHOTO_AND_UPLOAD_REQUEST); return true; } // 針對錄影後馬上進入上傳狀態處理 if ((acceptTypes.length > 0) && acceptTypes[0].equals("video/example")) { Log.d(TAG, "onShowFileChooser record video"); Intent it = CameraFunction.recordVideo(mContext); startActivityForResult(it, RECORD_VIDEO_AND_UPLOAD_REQUEST); return true; } Intent intent = new Intent(Intent.ACTION_GET_CONTENT); intent.addCategory(Intent.CATEGORY_OPENABLE); if (acceptTypes.length > 0) { if (acceptTypes[0].contains("image")) { intent.setType("image/*"); } else if (acceptTypes[0].contains("video")) { intent.setType("video/*"); } else { intent.setType("*/*"); } } else { intent.setType("*/*"); } WebViewActivity.this.startActivityForResult(Intent.createChooser(intent, "File Chooser"), REQUEST_FILE_PICKER); return true; }

回撥設定uri

/**
 * 設定input 標籤出發的回撥選擇檔案路徑,優先使用path引數,
 * 其次使用uri引數
 * @param uriParam
* @param pathParam
*/
private void setFilePathCallback(Uri uriParam, String pathParam) {
    //都為空,則設定null
if (uriParam == null && pathParam == null) {
        if (mFilePathCallback != null) {
            mFilePathCallback.onReceiveValue(null);
}
        if (mFilePathCallbacks != null) {
            mFilePathCallbacks.onReceiveValue(null);
}
    } else if (null != pathParam) { // 優先使用path
if (mFilePathCallback != null) {
            Uri uri = Uri.fromFile(new File(pathParam));
mFilePathCallback.onReceiveValue(uri);
}
        if (mFilePathCallbacks != null) {
            Uri uri = Uri.fromFile(new File(pathParam));
mFilePathCallbacks.onReceiveValue(new Uri[] { uri });
}
    } else if (null != uriParam) { //其次使用uri
if (mFilePathCallback != null) {
            String path = UriUtils.getPath(getApplicationContext(), uriParam);
Uri uri = Uri.fromFile(new File(path));
mFilePathCallback.onReceiveValue(uri);
}
        if (mFilePathCallbacks != null) {
            String path = UriUtils.getPath(getApplicationContext(), uriParam);
Uri uri = Uri.fromFile(new File(path));
mFilePathCallbacks.onReceiveValue(new Uri[] { uri });
}
    }

    mFilePathCallback = null;
mFilePathCallbacks = null;
}

針對各個請求場景進行處理:

public void onActivityResult(int requestCode, int resultCode, Intent intent) {

總結:既然用H5開發APP,就需要了解前端,不懂就要問了。查詢方向要對,否則南轅北轍,方向有時候比努力重要!