}
});
(5) WebView调用手机系统相册来上传图片,开发过程中发现在很多机器上无法正常唤起系统相册来选择图片。怎么解决?
原因分析:
因为Google攻城狮们对setWebChromeClient的回调方法openFileChooser做了多次修改,5.0以下openFileChooser有几种重载方法,在5.0以上将回调方法该为了onShowFileChooser。
解决方案:
为了兼容各个版本,我们需要对openFileChooser()进行重载,同时针对5.0及以上重写onShowFileChooser()方法:
上一段示例代码,给大家看看:
public class MainActivity extends AppCompatActivity {
private ValueCallback uploadMessage;
private ValueCallback
private final static int FILE_CHOOSER_RESULT_CODE = 10000;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
WebView webview = (WebView) findViewById(R.id.web_view);
assert webview != null;
WebSettings settings = webview.getSettings();
settings.setUseWideViewPort(true);
settings.setLoadWithOverviewMode(true);
settings.setJavaScriptEnabled(true);
webview.setWebChromeClient(new WebChromeClient() {
// android 3.0以下:用的这个方法
public void openFileChooser(ValueCallback valueCallback) {
uploadMessage = valueCallback;
openImageChooserActivity();
}
// android 3.0以上,android4.0以下:用的这个方法
public void openFileChooser(ValueCallback valueCallback, String acceptType) {
uploadMessage = valueCallback;
openImageChooserActivity();
}
//android 4.0 - android 4.3 安卓4.4.4也用的这个方法
public void openFileChooser(ValueCallback valueCallback, String acceptType,
String capture) {
uploadMessage = valueCallback;
openImageChooserActivity();
}
//android4.4 无方法。。。
// Android 5.0及以上用的这个方法
@Override
public boolean onShowFileChooser(WebView webView, ValueCallback
filePathCallback, WebChromeClient.FileChooserParams fileChooserParams) {
uploadMessageAboveL = filePathCallback;
openImageChooserActivity();
return true;
}
});
String targetUrl = “file:///android_asset/up.html”;
webview.loadUrl(targetUrl);
}
private void openImageChooserActivity() {
Intent i = new Intent(Intent.ACTION_GET_CONTENT);
i.addCategory(Intent.CATEGORY_OPENABLE);
i.setType(“image/*”);
startActivityForResult(Intent.createChooser(i, “Image Chooser”),
FILE_CHOOSER_RESULT_CODE);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == FILE_CHOOSER_RESULT_CODE) {
if (null == uploadMessage && null == uploadMessageAboveL) return;
Uri result = data == null || resultCode != RESULT_OK ? null : data.getData();
if (uploadMessageAboveL != null) {
onActivityResultAboveL(requestCode, resultCode, data);
} else if (uploadMessage != null) {
uploadMessage.onReceiveValue(result);
uploadMessage = null;
}
}
}
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
private void onActivityResultAboveL(int requestCode, int resultCode, Intent intent) {
if (requestCode != FILE_CHOOSER_RESULT_CODE || uploadMessageAboveL == null)
return;
Uri[] results = null;
if (resultCode == Activity.RESULT_OK) {
if (intent != null) {
String dataString = intent.getDataString();
ClipData clipData = intent.getClipData();
if (clipData != null) {
results = new Uri[clipData.getItemCount()];
for (int i = 0; i < clipData.getItemCount(); i++) {
ClipData.Item item = clipData.getItemAt(i);
results[i] = item.getUri();
}
}
if (dataString != null)
results = new Uri[]{Uri.parse(dataString)};
}
}
uploadMessageAboveL.onReceiveValue(results);
uploadMessageAboveL = null;
}
重点坑:针对Android4.4,系统把openFileChooser方法去掉了,怎么解决?
详情请见博客
http://blog.csdn.net/xiexie758/article/details/52446937这里就不多说了。
(6) WebView调用手机系统相册来上传图片,处理好第六点说的方法,我们打好release包测试的时候却又发现还是没法选择图片了,怎么解决?
原因分析:
无奈去翻WebChromeClient的源码,发现openFileChooser()是系统API,我们的release包是开启了混淆的,所以在打包的时候混淆了openFileChooser(),这就导致无法回调openFileChooser()了。
解决方案
也很简单,直接不混淆openFileChooser()就好了。
-keepclassmembers class * extends android.webkit.WebChromeClient{
public void openFileChooser(…);
}
(7)怎么在 WebView 中长按保存图片?
1.给 WebView添加监听
mWebview.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
}
});
2.获取点击的图片地址
先获取类型,根据相应的类型来处理对应的数据。
//首先判断点击的类型
WebView.HitTestResult result = ((WebView) v).getHitTestResult();
int type = result.getType();
//获取具体信息,图片这里就是图片地址
String imgurl = result.getExtra();
type有这几种类型:
WebView.HitTestResult.UNKNOWN_TYPE 未知类型
WebView.HitTestResult.PHONE_TYPE 电话类型
WebView.HitTestResult.EMAIL_TYPE 电子邮件类型
WebView.HitTestResult.GEO_TYPE 地图类型
WebView.HitTestResult.SRC_ANCHOR_TYPE 超链接类型
WebView.HitTestResult.SRC_IMAGE_ANCHOR_TYPE 带有链接的图片类型
WebView.HitTestResult.IMAGE_TYPE 单纯的图片类型
WebView.HitTestResult.EDIT_TEXT_TYPE 选中的文字类型
3.操作图片
你可以弹出保存图片,或者点击之后跳转到显示图片的页面。
最后整理一下代码:
mWebView.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
WebView.HitTestResult result = ((WebView)v).getHitTestResult();
if (null == result)
return false;
int type = result.getType();
if (type == WebView.HitTestResult.UNKNOWN_TYPE)
return false;
// 这里可以拦截很多类型,我们只处理图片类型就可以了
switch (type) {
case WebView.HitTestResult.PHONE_TYPE: // 处理拨号
break;
case WebView.HitTestResult.EMAIL_TYPE: // 处理Email
break;
case WebView.HitTestResult.GEO_TYPE: // 地图类型
break;
case WebView.HitTestResult.SRC_ANCHOR_TYPE: // 超链接
break;
case WebView.HitTestResult.SRC_IMAGE_ANCHOR_TYPE:
break;
case WebView.HitTestResult.IMAGE_TYPE: // 处理长按图片的菜单项
// 获取图片的路径
String saveImgUrl = result.getExtra();
// 跳转到图片详情页,显示图片
Intent i = new Intent(MainActivity.this, ImageActivity.class);
i.putExtra(“imgUrl”, saveImgUrl);
startActivity(i);
break;
default:
break;
}
}
});
(8) WebView 开启硬件加速导致的问题?
WebView有很多问题,比如:不能打开pdf,播放视屏也只能打开硬件加速才能支持,在某些机型上会崩溃。
下面看一下硬件加速, 硬件加速分为四个级别:
Application级别
Activity级别
window级别(目前为止,Android还不支持在Window级别关闭硬件加速。)
getWindow().setFlags(
WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED,
WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED);
View级别
view.setLayerType(View.LAYER_TYPE_HARDWARE, null);
WebView开启硬件加速导致屏幕花屏问题的解决:
原因分析:
4.0以上的系统我们开启硬件加速后,WebView渲染页面更加快速,拖动也更加顺滑。但有个副作用就是,当WebView视图被整体遮住一块,然后突然恢复时(比如使用SlideMenu将WebView从侧边滑出来时),这个过渡期会出现白块同时界面闪烁。
解决方案:
在过渡期前将WebView的硬件加速临时关闭,过渡期后再开启,代码如下:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
webview.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
}
Android 4.0+ 版本中的EditText字符重叠问题:
做的软件,在一些机器上,打字的时候,EditText中的内容会出现重叠,而大部分机器没有,所以感觉不是代码的问题,一直没有头绪。
出现原因:JellyBean的硬件加速bug,在此我们关掉硬件加速即可。
解决方案:在EditText中加入一句:
android:layerType=”software”
图片无法显示:
做的程序里有的时候会需要加载大图,但是硬件加速中 OpenGL对于内存是有限制的。如果遇到了这个限制,LogCat只会报一个Warning: Bitmap too large to be uploaded into a texture (587x7696, max=2048x2048)
这时我们就需要把硬件加速关闭了。
但开始我是这样处理的,我关闭了整个应用的硬件加速:
android:allowBackup=“true” android:icon="@drawable/ic_launcher" android:hardwareAccelerated=“false” android:label="@string/app_name" android:theme="@style/AppTheme" > 随后我就发现,虽然图片可以显示了,但是ListView和WebView等控件显得特别的卡,这说明硬件加速对于程序的性能提升是很明显的。所以我就改为对于Activity的关闭。 android:name=“icyfox.webviewimagezoomertest.MainActivity” android:label="@string/app_name" android:hardwareAccelerated=“false” (9) ViewPager里非首屏WebView点击事件不响应是什么原因? 如果你的多个WebView是放在ViewPager里一个个加载出来的,那么就会遇到这样的问题。ViewPager首屏WebView的创建是在前台,点击时没有问题;而其他非首屏的WebView是在后台创建,滑动到它后点击页面会出现如下错误日志: 很多人在刚接触这个行业的时候或者是在遇到瓶颈期的时候,总会遇到一些问题,比如学了一段时间感觉没有方向感,不知道该从哪里入手去学习,对此我整理了一些资料,需要的可以免费分享给大家 我的【Github】会分享一些关于Android进阶方面的知识,也会分享一下最新的面试题~ 如果你熟练掌握GitHub中列出的知识点,相信将会大大增加你通过前两轮技术面试的几率!这些内容都供大家参考,互相学习。 ①「Android面试真题解析大全」PDF完整高清版+②「Android面试知识体系」学习思维导图压缩包——————可以在我的【Github】阅读下载,最后觉得有帮助、有需要的朋友可以点个赞 BC%80%E5%8F%91%E4%B8%8D%E4%BC%9A%E8%BF%99%E4%BA%9B%EF%BC%9F%E5%A6%82%E4%BD%95%E9%9D%A2%E8%AF%95%E6%8B%BF%E9%AB%98%E8%96%AA%EF%BC%81.md)会分享一些关于Android进阶方面的知识,也会分享一下最新的面试题~ 如果你熟练掌握GitHub中列出的知识点,相信将会大大增加你通过前两轮技术面试的几率!这些内容都供大家参考,互相学习。 ①「Android面试真题解析大全」PDF完整高清版+②「Android面试知识体系」学习思维导图压缩包——————可以在我的【Github】阅读下载,最后觉得有帮助、有需要的朋友可以点个赞 [外链图片转存中…(img-YDRafjnZ-1646481298733)] [外链图片转存中…(img-4ObYgW0Z-1646481298734)]写在最后