最近在为公司的几个H5项目做app打包,然后就踩到这个坑了。
项目中有 h5调用相册选择图片,然后上传这个功能,测试说上传不了图片。然后搜了不少资料,折腾了一下午,终于搞好了,特此记录下。
坑1:
原生WebView 的选择文件功能需要我们自己实现,代码如下:
[代码]java代码:
010203040506070809101112131415161718192021222324252627282930313233343536wv_main.setWebChromeClient(newWebChromeClient() {// Andorid 4.1----4.4publicvoidopenFileChooser(ValueCallback<uri> uploadFile, String acceptType, String capture) {mFilePathCallback = uploadFile;handle(uploadFile);}// for 5.0+@OverridepublicbooleanonShowFileChooser(WebView webView, ValueCallback<uri[]> filePathCallback, FileChooserParams fileChooserParams) {if(mFilePathCallbackArray !=null) {mFilePathCallbackArray.onReceiveValue(null);}mFilePathCallbackArray = filePathCallback;handleup(filePathCallback);returntrue;}});}privatevoidhandle(ValueCallback<uri> uploadFile) {Intent intent =newIntent(Intent.ACTION_PICK);intent.setType("image/*");startActivityForResult(intent, PICK_REQUEST);}privatevoidhandleup(ValueCallback<uri[]> uploadFile) {Intent intent =newIntent(Intent.ACTION_PICK);intent.setType("image/*");startActivityForResult(intent, PICK_REQUEST);}</uri[]></uri></uri[]></uri>然后在Activity的onActivityResult 方法里处理回调,代码如下:
[代码]java代码:
01020304050607080910111213141516171819@OverrideprotectedvoidonActivityResult(intrequestCode,intresultCode, Intent data) {super.onActivityResult(requestCode, resultCode, data);if(requestCode == PICK_REQUEST) {if(null!= data) {Uri uri = data.getData();handleCallback(uri);}else{// 取消了照片选取的时候调用handleCallback(null);}}else{// 取消了照片选取的时候调用handleCallback(null);}}[代码]java代码:
0102030405060708091011121314151617181920212223242526272829/*** 处理WebView的回调** @param uri*/privatevoidhandleCallback(Uri uri) {if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {if(mFilePathCallbackArray !=null) {if(uri !=null) {mFilePathCallbackArray.onReceiveValue(newUri[]{uri});}else{mFilePathCallbackArray.onReceiveValue(null);}mFilePathCallbackArray =null;}}else{if(mFilePathCallback !=null) {if(uri !=null) {String url = getFilePathFromContentUri(uri, getContentResolver());Uri u = Uri.fromFile(newFile(url));mFilePathCallback.onReceiveValue(u);}else{mFilePathCallback.onReceiveValue(null);}mFilePathCallback =null;}}}坑2:记得一定要释放,不然点取消之后,就再调不起来了(一下午主要就填这个坑了)
[代码]java代码:
12344.1-4.4mFilePathCallback.onReceiveValue(null);5.0mFilePathCallbackArray.onReceiveValue(null);
坑3:4.4以下,返回的Uri 是content: 开头的,h5端识别不了,需要转成绝对路径
[代码]java代码:
01020304050607080910111213141516publicstaticString getFilePathFromContentUri(Uri selectedVideoUri,ContentResolver contentResolver) {String filePath;String[] filePathColumn = {MediaStore.MediaColumns.DATA};Cursor cursor = contentResolver.query(selectedVideoUri, filePathColumn,null,null,null);// 也可用下面的方法拿到cursor// Cursor cursor = this.context.managedQuery(selectedVideoUri, filePathColumn, null, null, null);cursor.moveToFirst();intcolumnIndex = cursor.getColumnIndex(filePathColumn[0]);filePath = cursor.getString(columnIndex);cursor.close();returnfilePath;}
热门源码