Android 内嵌 webView 与H5交互的问题和总结
先实现效果android 内嵌WebView 与H5 交互;
先webView 的WebViewClient 中重写 shouldOverrideUrlLoading 方法 通过拦截Url(拦截的协议需要跟H5协调 方式:< a href="xxxx "></ a> 注:xxxx是定义的拦截标识),实现 调用Android 原生拍照或者相册, 然后把获取的图片转成Base64 传给H5 ,H5
在调用头像裁剪的方法 上传到服务器;核核心代码:
webView.setWebViewClient(new WebViewClient() {
@Override
public void onPageStarted(WebView view, String url, Bitmap favicon) {
// TODO Auto-generated method stub
super.onPageStarted(view, url, favicon);
//输出要加载路径
Log.e("sss", url);
}
@Override
public boolean shouldOverrideUrlLoading(WebView view, String scheme) {
//同样的道理在jsp 页面中 < a href="xxxx "></ a> 拦截下来做指定的跳转
// 判断url链接中是否含有某个字段,如果有就执行指定的跳转(不执行跳转url链接),如果没有就加载url链接
String url = AppUtile.spiltURL(scheme);
if (url.contains("native")) {
String[] spilte = url.split("-", 3);
if (spilte[1].equals("cancel")) {
finish();
}
} else {
if (scheme.contains("tel:")) { //拦截打电话
String[] stel = scheme.split("tel:");
call(context, stel[1]);
return true;
}
if (scheme.contains("img")) {// 拦截拍照
selectImage();
return true;
}
if (scheme.contains("https://mclient.alipay.com/cashier/mobilepay.htm")) {//支付宝支付
Intent intent = new Intent(context,H5PayDemoActivity.class);
Bundle extras = new Bundle();
String urlsss =scheme;
extras.putString("url", urlsss);
intent.putExtras(extras);
context.startActivity(intent);
return true;
}
if(scheme.startsWith("alipays:") || scheme.startsWith("alipay")) {
try {
context.startActivity(new Intent("android.intent.action.VIEW", Uri.parse(scheme)));
} catch (Exception e) {
new AlertDialog.Builder(context)
.setMessage("未检测到支付宝客户端,请安装后重试。")
.setPositiveButton("立即安装", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
Uri alipayUrl = Uri.parse("https://d.alipay.com");
context.startActivity(new Intent("android.intent.action.VIEW", alipayUrl));
}
}).setNegativeButton("取消", null).show();
}
return true;
}
//重定向URL
if (scheme.contains("?")) {
view.loadUrl(scheme + "&appType=FAFA_SOFT_3D&source=FAFA_SOFT_3D_ANDROID");
} else {
view.loadUrl(scheme + "?appType=FAFA_SOFT_3D&source=FAFA_SOFT_3D_ANDROID");
}
}
return true;
}
关于shouldOverrideUrlLoading()方法的返回值问题,该方法的返回值有三种:
1.返回true,即根据代码逻辑执行相应操作,webview不加载该url,返回true 表示拦截<a /a>成功;
2.返回false,除执行相应代码外,webview加载该url, false则失效;
3.返回super.shouldOverrideUrlLoading(),点进父类中,我们可以看到,返回的还是false。
//通过onActivityResult获取 照片的绝对路径
@Override
protected void onActivityResult(int requestCode, int resultCode,
Intent intent) {
// TODO Auto-generated method stub
super.onActivityResult(requestCode, resultCode, intent);
if (requestCode == REQUEST_CODE_PICK_IMAGE) {// 拍照
if (resultCode==Activity.RESULT_OK) {
// PhotoBitmapUtils.amendRotatePhoto 解决个别手机拍完照片 角度旋转的问题
String filepath = PhotoBitmapUtils.amendRotatePhoto(photoPath,
context);
Bitmap mpBitmap = AppUtile.getSmallBitmap(filepath);
Bitmap bitmap2 = AppUtile.ratio(mpBitmap, 1080, 1920);
String base64ImageUrl = AppUtile.bitmapTo(bitmap2);
if (webView != null) {
webView.loadUrl("javascript:setPhoto('"
+ "data:image/jpeg;base64," + base64ImageUrl + "')");
}
}else{
Toast.makeText(context, "取消操作", Toast.LENGTH_SHORT).show();
}
} else if (requestCode == FILECHOOSER_RESULTCODE) {
// 相册
if (resultCode==Activity.RESULT_OK) {
String title = "";
if (intent != null) {
String imgFile = RxPhotoTool.getImageAbsolutePath(context,
intent.getData());
String filepath = PhotoBitmapUtils.amendRotatePhoto(imgFile,
context);
if (imgFile.contains(".png")) {
title = "data:image/png;base64,";
} else if (imgFile.contains(".icon")) {
title = "data:image/icon;base64,";
} else if (imgFile.contains(".gif")) {
title = "data:image/gif;base64,";
} else if (imgFile.contains(".jpg")) {
title = "data:image/jpeg;base64,";
}
Bitmap mpBitmap = AppUtile.getSmallBitmap(filepath);
Bitmap bitmap2 = AppUtile.ratio(mpBitmap, 1080, 1920);
String base64ImageUrl = AppUtile.bitmapTo(bitmap2);
if (webView != null) {
webView.loadUrl("javascript:setPhoto('" + title
+ base64ImageUrl + "')");
}
}else{
Toast.makeText(context, "图片格式错误", Toast.LENGTH_SHORT).show();
}
} else {
Toast.makeText(context, "取消操作", Toast.LENGTH_SHORT).show();
}
} else {
Toast.makeText(context, "取消操作", Toast.LENGTH_SHORT).show();
}
}
网上有很多去H5 传值的例子 比如在高版本上重写onShowFileChooser
通过 ValueCallback<Uri[]> filePathCallback 这个回调对象
@Override
public boolean onShowFileChooser(WebView webView,
ValueCallback<Uri[]> filePathCallback,
WebChromeClient.FileChooserParams fileChooserParams) {
}
filePathCallback.onReceiveValue(results); 给Url传值参考链接如下:
http://blog.****.net/gaoyongshuo/article/details/71425573 这种实现方式在个别手机上存在问题,还有在低版本上
onShowFileChooser 没有这个方法
所以用了另一种方法 webView.loadUrl("javascript:setPhoto('" +base64ImageUrl + "')");
调用javascript 的一种方法给他们传一个String ,调用这种方法存在一种弊端,如果图片过大 转Base64 有限制,
给H5 传不过去了,所以要进行对图片进行压缩;
注:这里只提供解决问题的思路
有问题请咨询QQ:1070398201