【项目中】关于webView上遇到的各种问题集锦

11 篇文章 0 订阅
9 篇文章 0 订阅

webView的相关设置:

 //允许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); //取消滚动条白边效果  

1、android与js交互

参考:http://blog.csdn.net/it1039871366/article/details/46372207


2、在Android的webview中定制js的alert,confirm和prompt对话框的方法

参考:http://gundumw100.iteye.com/blog/1158719

1.首先继承android.webkit.WebChromeClient实现MyWebChromeClient。

2.在MyWebChromeClient.java中覆盖onJsAlert,onJsConfirm,onJsPrompt三个方法。

3.在初始化Webview时设置调用webview.setWebChromeClient(new MyWebChromeClient());

4.在Webview载入的html中使用window.alert,window.confirm,window.prompt方法,系统弹出的将是自定义实现的对应对话框。

MyWebChromeClient.java的代码如下:

import android.app.AlertDialog;  
import android.content.DialogInterface;  
import android.content.DialogInterface.OnCancelListener;  
import android.content.DialogInterface.OnClickListener;  
import android.content.DialogInterface.OnKeyListener;  
import android.graphics.Bitmap;  
import android.os.Message;  
import android.util.Log;  
import android.view.KeyEvent;  
import android.webkit.JsPromptResult;  
import android.webkit.JsResult;  
import android.webkit.WebChromeClient;  
import android.webkit.WebView;  
import android.widget.EditText;  
  
/** 
 * http://618119.com/archives/2010/12/20/199.html 
 */  
  
//****************************************************************************  
public class MyWebChromeClient extends WebChromeClient {  
    @Override  
    public void onCloseWindow(WebView window) {  
        super.onCloseWindow(window);  
    }  
  
    @Override  
    public boolean onCreateWindow(WebView view, boolean dialog,  
            boolean userGesture, Message resultMsg) {  
        return super.onCreateWindow(view, dialog, userGesture, resultMsg);  
    }  
  
    /**  
     * 覆盖默认的window.alert展示界面,避免title里显示为“:来自file:”  
     */  
    public boolean onJsAlert(WebView view, String url, String message,  
            JsResult result) {  
        final AlertDialog.Builder builder = new AlertDialog.Builder(view.getContext());  
                  
        builder.setTitle("对话框")  
                .setMessage(message)  
                .setPositiveButton("确定", null);  
                  
        // 不需要绑定按键事件  
        // 屏蔽keycode等于84之类的按键  
        builder.setOnKeyListener(new OnKeyListener() {  
            public boolean onKey(DialogInterface dialog, int keyCode,KeyEvent event) {  
                Log.v("onJsAlert", "keyCode==" + keyCode + "event="+ event);  
                return true;  
            }  
        });  
        // 禁止响应按back键的事件  
        builder.setCancelable(false);  
        AlertDialog dialog = builder.create();  
        dialog.show();  
        result.confirm();// 因为没有绑定事件,需要强行confirm,否则页面会变黑显示不了内容。  
        return true;  
        // return super.onJsAlert(view, url, message, result);  
    }  
  
    public boolean onJsBeforeUnload(WebView view, String url,  
            String message, JsResult result) {  
        return super.onJsBeforeUnload(view, url, message, result);  
    }  
  
    /** 
     * 覆盖默认的window.confirm展示界面,避免title里显示为“:来自file:” 
     */  
    public boolean onJsConfirm(WebView view, String url, String message,  
            final JsResult result) {  
        final AlertDialog.Builder builder = new AlertDialog.Builder(view.getContext());  
        builder.setTitle("对话框")  
                .setMessage(message)  
                .setPositiveButton("确定",new OnClickListener() {  
                            public void onClick(DialogInterface dialog,int which) {  
                                result.confirm();  
                            }  
                        })  
                .setNeutralButton("取消", new OnClickListener() {  
                    public void onClick(DialogInterface dialog, int which) {  
                        result.cancel();  
                    }  
                });  
        builder.setOnCancelListener(new OnCancelListener() {  
            @Override  
            public void onCancel(DialogInterface dialog) {  
                result.cancel();  
            }  
        });  
  
        // 屏蔽keycode等于84之类的按键,避免按键后导致对话框消息而页面无法再弹出对话框的问题  
        builder.setOnKeyListener(new OnKeyListener() {  
            @Override  
            public boolean onKey(DialogInterface dialog, int keyCode,KeyEvent event) {  
                Log.v("onJsConfirm", "keyCode==" + keyCode + "event="+ event);  
                return true;  
            }  
        });  
        // 禁止响应按back键的事件  
        // builder.setCancelable(false);  
        AlertDialog dialog = builder.create();  
        dialog.show();  
        return true;  
        // return super.onJsConfirm(view, url, message, result);  
    }  
  
    /** 
     * 覆盖默认的window.prompt展示界面,避免title里显示为“:来自file:” 
     * window.prompt('请输入您的域名地址', '618119.com'); 
     */  
    public boolean onJsPrompt(WebView view, String url, String message,  
            String defaultValue, final JsPromptResult result) {  
        final AlertDialog.Builder builder = new AlertDialog.Builder(view.getContext());  
                  
        builder.setTitle("对话框").setMessage(message);  
                  
        final EditText et = new EditText(view.getContext());  
        et.setSingleLine();  
        et.setText(defaultValue);  
        builder.setView(et)  
                .setPositiveButton("确定", new OnClickListener() {  
                    public void onClick(DialogInterface dialog, int which) {  
                        result.confirm(et.getText().toString());  
                    }  
          
                })  
                .setNeutralButton("取消", new OnClickListener() {  
                    public void onClick(DialogInterface dialog, int which) {  
                        result.cancel();  
                    }  
                });  
  
        // 屏蔽keycode等于84之类的按键,避免按键后导致对话框消息而页面无法再弹出对话框的问题  
        builder.setOnKeyListener(new OnKeyListener() {  
            public boolean onKey(DialogInterface dialog, int keyCode,KeyEvent event) {  
                Log.v("onJsPrompt", "keyCode==" + keyCode + "event="+ event);  
                return true;  
            }  
        });  
  
        // 禁止响应按back键的事件  
        // builder.setCancelable(false);  
        AlertDialog dialog = builder.create();  
        dialog.show();  
        return true;  
        // return super.onJsPrompt(view, url, message, defaultValue,  
        // result);  
    }  
  
    @Override  
    public void onProgressChanged(WebView view, int newProgress) {  
        super.onProgressChanged(view, newProgress);  
    }  
  
    @Override  
    public void onReceivedIcon(WebView view, Bitmap icon) {  
        super.onReceivedIcon(view, icon);  
    }  
  
    @Override  
    public void onReceivedTitle(WebView view, String title) {  
        super.onReceivedTitle(view, title);  
    }  
  
    @Override  
    public void onRequestFocus(WebView view) {  
        super.onRequestFocus(view);  
    }  
}  

3、Android WebView 上传文件支持

默认情况下情况下,使用Android的WebView是不能够支持上传文件的。因为Android的每个版本WebView的实现有差异,因此需要对不同版本去适配。花了一点时间,参考别人的代码,这个问题已经解决。

主要思路是重写WebChromeClient,然后在WebViewActivity中接收选择到的文件Uri,传给页面去上传就可以了。

创建一个WebViewActivity的内部类

    webView.setWebChromeClient(new WebChromeClient() {
				public void onProgressChanged(WebView view, int progress) {// 载入进度改变而触发
					if (progress == 100) {
						handler.sendEmptyMessage(1);// 如果全部载入,隐藏进度对话框
					}

					super.onProgressChanged(view, progress);
				}

				// 扩展支持alert事件
				@Override
				public boolean onJsAlert(WebView view, String url, String message, JsResult result) {
					AlertDialog.Builder builder = new AlertDialog.Builder(view.getContext());
					builder.setTitle("项目帮").setMessage(message).setPositiveButton("确定", null);
					builder.setCancelable(false);
					builder.setIcon(R.drawable.ic_launcher);
					AlertDialog dialog = builder.create();
					dialog.show();
					result.confirm();
					return true;
				}

				// 覆盖默认的window.confirm展示界面,避免title里显示为“:来自file:”
				@Override
				public boolean onJsConfirm(WebView view, String url, String message, final JsResult result) {
					final AlertDialog.Builder builder = new AlertDialog.Builder(view.getContext());
					builder.setTitle("项目帮").setMessage(message)
							.setNegativeButton("取消", new DialogInterface.OnClickListener() {

								@Override
								public void onClick(DialogInterface dialog, int which) {
									result.cancel();

								}
							}).setPositiveButton("确定", new DialogInterface.OnClickListener() {

								@Override
								public void onClick(DialogInterface dialog, int which) {
									result.confirm();

								}
							});

					builder.setOnCancelListener(new OnCancelListener() {
						@Override
						public void onCancel(DialogInterface dialog) {
							result.cancel();
						}
					});

					AlertDialog dialog = builder.create();
					dialog.show();
					return true;
					// return super.onJsConfirm(view, url, message, result);
				}

				// 扩展浏览器上传文件
				// 3.0++版本
				public void openFileChooser(ValueCallback<Uri> uploadMsg, String acceptType) {
					openFileChooserImpl(uploadMsg);
				}

				// 3.0--版本
				public void openFileChooser(ValueCallback<Uri> uploadMsg) {
					openFileChooserImpl(uploadMsg);
				}

				public void openFileChooser(ValueCallback<Uri> uploadMsg, String acceptType, String capture) {
					openFileChooserImpl(uploadMsg);
				}

				// For Android > 5.0
				public boolean onShowFileChooser(WebView webView, ValueCallback<Uri[]> uploadMsg,
						WebChromeClient.FileChooserParams fileChooserParams) {
					openFileChooserImplForAndroid5(uploadMsg);
					return true;
				}
			});

private void openFileChooserImpl(ValueCallback<Uri> uploadMsg) {
		mUploadMessage = uploadMsg;
		Intent i = new Intent(Intent.ACTION_GET_CONTENT);
		i.addCategory(Intent.CATEGORY_OPENABLE);
		i.setType("image/*");
		startActivityForResult(Intent.createChooser(i, "File Chooser"), FILECHOOSER_RESULTCODE);
	}

	private void openFileChooserImplForAndroid5(ValueCallback<Uri[]> uploadMsg) {
		mUploadMessageForAndroid5 = uploadMsg;
		Intent contentSelectionIntent = new Intent(Intent.ACTION_GET_CONTENT);
		contentSelectionIntent.addCategory(Intent.CATEGORY_OPENABLE);
		contentSelectionIntent.setType("image/*");

		Intent chooserIntent = new Intent(Intent.ACTION_CHOOSER);
		chooserIntent.putExtra(Intent.EXTRA_INTENT, contentSelectionIntent);
		chooserIntent.putExtra(Intent.EXTRA_TITLE, "Image Chooser");

		startActivityForResult(chooserIntent, FILECHOOSER_RESULTCODE_FOR_ANDROID_5);
	}


特别注意的是5.0以上的版本,我在网上用了其他很多别人推荐的方法都不可以,但是以上方法亲测没问题。

以上是打开响应的选择文件的界面,我们还需要处理接收到文件之后,传给网页来响应。因为我们前面是使用startActivityForResult来打开的选择页面,我们会onActivityResult

中接收到选择的结果。Show code:
@Override
	protected void onActivityResult(int requestCode, int resultCode, Intent intent) {
		if (requestCode == FILECHOOSER_RESULTCODE) {
			if (null == mUploadMessage)
				return;
			Uri result = intent == null || resultCode != RESULT_OK ? null : intent.getData();
			mUploadMessage.onReceiveValue(result);
			mUploadMessage = null;

		} else if (requestCode == FILECHOOSER_RESULTCODE_FOR_ANDROID_5) {
			if (null == mUploadMessageForAndroid5)
				return;
			Uri result = (intent == null || resultCode != RESULT_OK) ? null : intent.getData();
			if (result != null) {
				mUploadMessageForAndroid5.onReceiveValue(new Uri[] { result });
			} else {
				mUploadMessageForAndroid5.onReceiveValue(new Uri[] {});
			}
			mUploadMessageForAndroid5 = null;
		}
	}
以上代码主要就是调用ValueCallback的onReceiveValue方法,将结果传回web。

参考:http://blog.isming.me/2015/12/21/android-webview-upload-file/
            http://blog.csdn.net/zhtsuc/article/details/49154099   (主要参考)
            http://blog.csdn.net/u014424628/article/details/51559981


4、图片照片拍照

    参考:http://blog.csdn.net/djcken/article/details/46379929

    参考:http://www.cnblogs.com/ufreedom/p/4158081.html

   参考:http://stackoverflow.com/questions/4455558/allow-user-to-select-camera-or-gallery-for-image

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值