最近在为公司的几个H5项目做app打包,然后就踩到这个坑了。
项目中有 h5调用相册选择图片,然后上传这个功能,测试说上传不了图片。然后搜了不少资料,折腾了一下午,终于搞好了,特此记录下。
坑1:
原生WebView 的选择文件功能需要我们自己实现,代码如下:
[代码]java代码:
010203040506070809101112131415161718192021222324252627282930313233343536wv_main.setWebChromeClient(
new
WebChromeClient() {
// Andorid 4.1----4.4
public
void
openFileChooser(ValueCallback<uri> uploadFile, String acceptType, String capture) {
mFilePathCallback = uploadFile;
handle(uploadFile);
}
// for 5.0+
@Override
public
boolean
onShowFileChooser(WebView webView, ValueCallback<uri[]> filePathCallback, FileChooserParams fileChooserParams) {
if
(mFilePathCallbackArray !=
null
) {
mFilePathCallbackArray.onReceiveValue(
null
);
}
mFilePathCallbackArray = filePathCallback;
handleup(filePathCallback);
return
true
;
}
});
}
private
void
handle(ValueCallback<uri> uploadFile) {
Intent intent =
new
Intent(Intent.ACTION_PICK);
intent.setType(
"image/*"
);
startActivityForResult(intent, PICK_REQUEST);
}
private
void
handleup(ValueCallback<uri[]> uploadFile) {
Intent intent =
new
Intent(Intent.ACTION_PICK);
intent.setType(
"image/*"
);
startActivityForResult(intent, PICK_REQUEST);
}
</uri[]></uri></uri[]></uri>
然后在Activity的onActivityResult 方法里处理回调,代码如下:
[代码]java代码:
01020304050607080910111213141516171819@Override
protected
void
onActivityResult(
int
requestCode,
int
resultCode, 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
*/
private
void
handleCallback(Uri uri) {
if
(Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
if
(mFilePathCallbackArray !=
null
) {
if
(uri !=
null
) {
mFilePathCallbackArray.onReceiveValue(
new
Uri[]{uri});
}
else
{
mFilePathCallbackArray.onReceiveValue(
null
);
}
mFilePathCallbackArray =
null
;
}
}
else
{
if
(mFilePathCallback !=
null
) {
if
(uri !=
null
) {
String url = getFilePathFromContentUri(uri, getContentResolver());
Uri u = Uri.fromFile(
new
File(url));
mFilePathCallback.onReceiveValue(u);
}
else
{
mFilePathCallback.onReceiveValue(
null
);
}
mFilePathCallback =
null
;
}
}
}
坑2:记得一定要释放,不然点取消之后,就再调不起来了(一下午主要就填这个坑了)
[代码]java代码:
12344.1
-
4.4
mFilePathCallback.onReceiveValue(
null
);
5.0
mFilePathCallbackArray.onReceiveValue(
null
);
坑3:4.4以下,返回的Uri 是content: 开头的,h5端识别不了,需要转成绝对路径
[代码]java代码:
01020304050607080910111213141516public
static
String 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();
int
columnIndex = cursor.getColumnIndex(filePathColumn[
0
]);
filePath = cursor.getString(columnIndex);
cursor.close();
return
filePath;
}