一次Android WebView使用的苦逼体验之旅
Posted 小熊vip
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了一次Android WebView使用的苦逼体验之旅相关的知识,希望对你有一定的参考价值。
有时候有这么样的需求,我们想在自己的原生android app中嵌入其它功能模块,而这些模块的实现往往早就有BS模式的了,所以简单期间,直接拿过来用吧。
多亏了webView控件,让我们的app可以充当浏览器的功能浏览网页,如果网页已经是屏幕自适应的(各种框架bootstrap啊,amazeui啊,不拉不拉不拉的),那么效果更好!
那么问题来了,我们要怎么使用webView呢?
版本1:
【首先webView控件准备好,其次<uses-permission android:name="android.permission.INTERNET" /> 也不要忘了!】
WebView webView= (WebView) findViewById(R.id.webview);
webView.loadUrl(http://www.baidu.com);
哈哈哈哈,代码太简单了,是不是马上就有效果了。
高兴得太早了!
怎么有些按钮点了没效果,网页显示出来好像和预想的差太多!!!!
版本2:【添加一些设置项】
//允许JS执行
webView.getSettings().setjavascriptEnabled(true);
类似的还有如下这些设置【用到的时候查文档吧!】
//设置WebView的一些缩放功能点
webView.setScrollBarStyle(WebView.SCROLLBARS_OUTSIDE_OVERLAY);
webView.setHorizontalScrollBarEnabled(false);
webView.getSettings().setSupportZoom(true);
//设置WebView可触摸放大缩小
webView.getSettings().setBuiltInZoomControls(true);
webView.setInitialScale(70);
webView.setHorizontalScrollbarOverlay(true);
//WebView双击变大,再双击后变小,当手动放大后,双击可以恢复到原始大小
//webView.getSettings().setUseWideViewPort(true);
//提高渲染的优先级
webView.getSettings().setRenderPriority(RenderPriority.HIGH);
//把图片加载放在最后来加载渲染
//webView.getSettings().setBlockNetworkImage(true);
//用WebView将字符串以html的形式显示出来
webView.loadDataWithBaseURL("fake://not/needed", <p>zzz</p>, "text/html", "utf-8", "");
//listview,webview中滚动拖动到顶部或者底部时的阴影
webView.setOverScrollMode(View.OVER_SCROLL_NEVER);
webView.getSettings().setCacheMode(WebSettings.LOAD_CACHE_ELSE_NETWORK);//使用缓存
WebView.getSettings().setCacheMode(WebSettings.LOAD_NO_CACHE); //默认不使用缓存!
webView.setScrollBarStyle(View.SCROLLBARS_INSIDE_OVERLAY); //取消滚动条白边效果
好了,大致满足我们的需求了。
等等,怎么点击超链接都是用的外部浏览器打开的啊,我还是想继续用webView打开!!!
下面介绍一个东西:webview.setWebViewClient(new WebViewClient());
WebViewClient就是帮助WebView处理各种通知、请求事件的,我们可以自定义WebViewClient,并重写里面的方法
常见的如下:
版本3:
webview1.setWebViewClient(new WebViewClient()
public boolean shouldOverrideUrlLoading(WebView view, String url)
view.loadUrl(url);
return true;
);
当点击超链接时会触发该方法,返回true表明还是在webView中进行跳转不会跳到浏览器打开!
等等,我的页面有个按钮不起作用了:
<a href="tel:110">110报警!</a>
试了一下用浏览器打开可以直接掉出拨号软件,怎么放到webView中就GG了呢?
版本4:
webview1.setWebViewClient(new MyWebViewClient());
//自定义 WebViewClient 辅助WebView设置处理关于页面跳转,页面请求等操作
private class MyWebViewClient extends WebViewClient
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url)
if(url.trim().startsWith("tel"))//特殊情况tel,调用系统的拨号软件拨号【<a href="tel:1111111111">1111111111</a>】
Intent i = new Intent(Intent.ACTION_VIEW);
i.setData(Uri.parse(url));
startActivity(i);
else
view.loadUrl(url);
return true;
这样就可以控制tel协议了。
既然到了这一步其实还可以做更多控制,比如我就遇到过这种:有一个按钮对应的超链接偏偏就不要用webView打开,而是用手机自带的浏览器打开!
【具体原因就不细说了,总之就是webView和浏览器还是有一定的差距的,正好我当时要实现的东西就被卡在那个节骨眼上了。。。。。】
不过处理起来也不是很难:
版本5:
webview1.setWebViewClient(new MyWebViewClient());
//自定义 WebViewClient 辅助WebView设置处理关于页面跳转,页面请求等操作【处理tel协议和视频通讯请求url的拦截转发】
private class MyWebViewClient extends WebViewClient
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url)
if(url.trim().startsWith("tel"))//特殊情况tel,调用系统的拨号软件拨号【<a href="tel:1111111111">1111111111</a>】
Intent i = new Intent(Intent.ACTION_VIEW);
i.setData(Uri.parse(url));
startActivity(i);
else
String port = url.substring(url.lastIndexOf(":")+1,url.lastIndexOf("/"));//尝试要拦截的视频通讯url格式(808端口):【http://domainName:808/?roomName】
if(port.equals("808"))//特殊情况【若打开的链接是视频通讯地址格式则调用系统浏览器打开】
Intent i = new Intent(Intent.ACTION_VIEW);
i.setData(Uri.parse(url));
startActivity(i);
else //其它非特殊情况全部放行
view.loadUrl(url);
return true;
其实就是利用了这条url和其它url相比的独特性(端口号不同),当然大家可能遇到的情况得根据实际情况来定。
写到这里是不是就玩完了呢?
no no no,好戏还在后头!
玩着玩着发现又有问题了,又有一个按钮不起作用。。。。。。
<input type="file">文件上传</input>
我的天哪,怎么总是有这么多破事。
下面再介绍一个东西
webView.setWebChromeClient(new WebChromeClient());
说明:WebChromeClient主要辅助WebView处理Javascript的对话框、网站图标、网站title、加载进度等比等,不过它还能处理文件上传操作
下面借用一下别人的代码:.
版本6:
webView.setWebChromeClient(new MyChromeWebClient());
//自定义 WebChromeClient 辅助WebView处理图片上传操作【<input type=file> 文件上传标签】
public class MyChromeWebClient extends WebChromeClient
// For Android 3.0-
public void openFileChooser(ValueCallback<Uri> uploadMsg)
Log.d(TAG, "openFileChoose(ValueCallback<Uri> uploadMsg)");
mUploadMessage = uploadMsg;
Intent i = new Intent(Intent.ACTION_GET_CONTENT);
i.addCategory(Intent.CATEGORY_OPENABLE);
i.setType("*/*");
MainActivity.this.startActivityForResult(Intent.createChooser(i, "File Chooser"), FILECHOOSER_RESULTCODE);
// For Android 3.0+
public void openFileChooser( ValueCallback uploadMsg, String acceptType )
Log.d(TAG, "openFileChoose( ValueCallback uploadMsg, String acceptType )");
mUploadMessage = uploadMsg;
Intent i = new Intent(Intent.ACTION_GET_CONTENT);
i.addCategory(Intent.CATEGORY_OPENABLE);
i.setType("*/*");
MainActivity.this.startActivityForResult(
Intent.createChooser(i, "File Browser"),
FILECHOOSER_RESULTCODE);
//For Android 4.1
public void openFileChooser(ValueCallback<Uri> uploadMsg, String acceptType, String capture)
Log.d(TAG, "openFileChoose(ValueCallback<Uri> uploadMsg, String acceptType, String capture)");
mUploadMessage = uploadMsg;
Intent i = new Intent(Intent.ACTION_GET_CONTENT);
i.addCategory(Intent.CATEGORY_OPENABLE);
i.setType("*/*");
MainActivity.this.startActivityForResult( Intent.createChooser( i, "File Browser" ), MainActivity.FILECHOOSER_RESULTCODE );
// For Android 5.0+
public boolean onShowFileChooser (WebView webView, ValueCallback<Uri[]> filePathCallback, WebChromeClient.FileChooserParams fileChooserParams)
Log.d(TAG, "onShowFileChooser(ValueCallback<Uri> uploadMsg, String acceptType, String capture)");
mUploadCallbackAboveL = filePathCallback;
Intent i = new Intent(Intent.ACTION_GET_CONTENT);
i.addCategory(Intent.CATEGORY_OPENABLE);
i.setType("*/*");
MainActivity.this.startActivityForResult(
Intent.createChooser(i, "File Browser"),
FILECHOOSER_RESULTCODE);
return true;
最后来个大杂烩吧:
版本7:
public class MainActivity extends AppCompatActivity
private final static String TAG = "MainActivity";
private WebView webView;
private ValueCallback<Uri> mUploadMessage;
private ValueCallback<Uri[]> mUploadCallbackAboveL;
private final static int FILECHOOSER_RESULTCODE = 1;
private final static String url = "http://xxxx.com";
//初始化webView
private void initWebView()
//从布局文件中扩展webView
webView=(WebView)this.findViewById(R.id.webView);
WebSettings settings = webView.getSettings();
settings.setUseWideViewPort(true);
settings.setLoadWithOverviewMode(true);
settings.setDefaultTextEncodingName("UTF-8");
//开启JavaScript支持
settings.setJavaScriptEnabled(true);
// 支持缩放
settings.setSupportZoom(true);
//辅助WebView设置处理关于页面跳转,页面请求等操作
webView.setWebViewClient(new MyWebViewClient());
//辅助WebView处理图片上传操作
webView.setWebChromeClient(new MyChromeWebClient());
//加载地址
webView.loadUrl(url);
@Override
protected void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initWebView();
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data)
super.onActivityResult(requestCode, resultCode, data);
if(requestCode==FILECHOOSER_RESULTCODE)
if (null == mUploadMessage && null == mUploadCallbackAboveL) return;
Uri result = data == null || resultCode != RESULT_OK ? null : data.getData();
if (mUploadCallbackAboveL != null)
onActivityResultAboveL(requestCode, resultCode, data);
else if (mUploadMessage != null)
mUploadMessage.onReceiveValue(result);
mUploadMessage = null;
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
private void onActivityResultAboveL(int requestCode, int resultCode, Intent data)
if (requestCode != FILECHOOSER_RESULTCODE
|| mUploadCallbackAboveL == null)
return;
Uri[] results = null;
if (resultCode == Activity.RESULT_OK)
if (data == null)
else
String dataString = data.getDataString();
ClipData clipData = data.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);
mUploadCallbackAboveL.onReceiveValue(results);
mUploadCallbackAboveL = null;
return;
//自定义 WebViewClient 辅助WebView设置处理关于页面跳转,页面请求等操作【处理tel协议和视频通讯请求url的拦截转发】
private class MyWebViewClient extends WebViewClient
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url)
if(url.trim().startsWith("tel"))//特殊情况tel,调用系统的拨号软件拨号【<a href="tel:1111111111">1111111111</a>】
Intent i = new Intent(Intent.ACTION_VIEW);
i.setData(Uri.parse(url));
startActivity(i);
else
String port = url.substring(url.lastIndexOf(":")+1,url.lastIndexOf("/"));//尝试要拦截的视频通讯url格式(808端口):【http://xxxx:808/?roomName】
if(port.equals("808"))//特殊情况【若打开的链接是视频通讯地址格式则调用系统浏览器打开】
Intent i = new Intent(Intent.ACTION_VIEW);
i.setData(Uri.parse(url));
startActivity(i);
else //其它非特殊情况全部放行
view.loadUrl(url);
return true;
//自定义 WebChromeClient 辅助WebView处理图片上传操作【<input type=file> 文件上传标签】
public class MyChromeWebClient extends WebChromeClient
// For Android 3.0-
public void openFileChooser(ValueCallback<Uri> uploadMsg)
Log.d(TAG, "openFileChoose(ValueCallback<Uri> uploadMsg)");
mUploadMessage = uploadMsg;
Intent i = new Intent(Intent.ACTION_GET_CONTENT);
i.addCategory(Intent.CATEGORY_OPENABLE);
i.setType("*/*");
MainActivity.this.startActivityForResult(Intent.createChooser(i, "File Chooser"), FILECHOOSER_RESULTCODE);
// For Android 3.0+
public void openFileChooser( ValueCallback uploadMsg, String acceptType )
Log.d(TAG, "openFileChoose( ValueCallback uploadMsg, String acceptType )");
mUploadMessage = uploadMsg;
Intent i = new Intent(Intent.ACTION_GET_CONTENT);
i.addCategory(Intent.CATEGORY_OPENABLE);
i.setType("*/*");
MainActivity.this.startActivityForResult(
Intent.createChooser(i, "File Browser"),
FILECHOOSER_RESULTCODE);
//For Android 4.1
public void openFileChooser(ValueCallback<Uri> uploadMsg, String acceptType, String capture)
Log.d(TAG, "openFileChoose(ValueCallback<Uri> uploadMsg, String acceptType, String capture)");
mUploadMessage = uploadMsg;
Intent i = new Intent(Intent.ACTION_GET_CONTENT);
i.addCategory(Intent.CATEGORY_OPENABLE);
i.setType("*/*");
MainActivity.this.startActivityForResult( Intent.createChooser( i, "File Browser" ), MainActivity.FILECHOOSER_RESULTCODE );
// For Android 5.0+
public boolean onShowFileChooser (WebView webView, ValueCallback<Uri[]> filePathCallback, WebChromeClient.FileChooserParams fileChooserParams)
Log.d(TAG, "onShowFileChooser(ValueCallback<Uri> uploadMsg, String acceptType, String capture)");
mUploadCallbackAboveL = filePathCallback;
Intent i = new Intent(Intent.ACTION_GET_CONTENT);
i.addCategory(Intent.CATEGORY_OPENABLE);
i.setType("*/*");
MainActivity.this.startActivityForResult(
Intent.createChooser(i, "File Browser"),
FILECHOOSER_RESULTCODE);
return true;
参考
http://blog.saymagic.cn/2015/11/08/webview-upload.html?utm_source=tuicool&utm_medium=referral
以上是关于一次Android WebView使用的苦逼体验之旅的主要内容,如果未能解决你的问题,请参考以下文章