webview之webSettings

WebSettings

WebSettings mSettings = this.getSettings();

1、JavaScript设置

开启javascript:h5页要一般都有js,设置为true才允许h5页面执行js,但开启js非常耗内存,经常会导致oom,为了解决这个问题,可以在onstart方法中开启,在onStop中关闭。

mSettings.setJavaScriptEnabled(true);

但对于调用手机文件选择的,即使开启了js,也不一定拿得到文件路径。h5想要获取手机的文件,首先需要打开文件选择器,但是不同的android版本,js和native交互的方式不一样;而且在5.0发布后,回调的不是openFileChooser方法,而是onShowFileChooser方法,并且上文提到的ValueCallback参数里包裹着不再是Uri,而是Uri数组。因此,我们需要继承WebChromeClient,给不同的版本做相应的处理。

// For Android 3.0以下
public void openFileChooser(ValueCallback<Uri> uploadMsg) {
 	mUploadMessage = uploadMsg;
	Intent i = new Intent(Intent.ACTION_GET_CONTENT);
	i.addCategory(Intent.CATEGORY_OPENABLE);
 	i.setType("image/*");
	if (mContext instanceof Activity) {
    	((Activity) mContext).startActivityForResult(Intent.createChooser(i, "Image Chooser"), FILECHOOSER_RESULTCODE);
	 }
}

// For Android 3.0+
public void openFileChooser(ValueCallback uploadMsg, String acceptType) {
	openFileChooser(uploadMsg);
}

//For Android 4.1+
public void openFileChooser(ValueCallback<Uri> uploadMsg, String acceptType, String capture) {
	openFileChooser(uploadMsg);
}

// android 5.0+
public boolean onShowFileChooser(WebView webView, ValueCallback<Uri[]> filePathCallback, FileChooserParams fileChooserParams) {
 	if (mFilePathCallback != null) {
    	mFilePathCallback.onReceiveValue(null);
	}
	mFilePathCallback = filePathCallback;

	Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
	if (takePictureIntent.resolveActivity(mContext.getPackageManager()) != null) {
    	// Create the File where the photo should go
    	File photoFile = null;
    	try {
        	photoFile = createImageFile();
        	takePictureIntent.putExtra("PhotoPath", mCameraPhotoPath);
   	 	} catch (Exception ex) {
        	// Error occurred while creating the File
        	ex.printStackTrace();
    	}

    	// Continue only if the File was successfully created
    	if (photoFile != null) {
        	mCameraPhotoPath = "file:" + photoFile.getAbsolutePath();
        	takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT,
                Uri.fromFile(photoFile));
    	} else {
        	takePictureIntent = null;
    	}
	}

	Intent contentSelectionIntent = new Intent(Intent.ACTION_GET_CONTENT);
	contentSelectionIntent.addCategory(Intent.CATEGORY_OPENABLE);
	contentSelectionIntent.setType("image/*");

	Intent[] intentArray;
	if (takePictureIntent != null) {
    	intentArray = new Intent[]{takePictureIntent};
	} else {
    	intentArray = new Intent[0];
	}

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

	if (mContext instanceof Activity) {
    	((Activity) mContext).startActivityForResult(chooserIntent, INPUT_FILE_REQUEST_CODE);
	}

	return true;
}

@SuppressLint("SdCardPath")
private File createImageFile() {
	//mCameraPhotoPath="/mnt/sdcard/tmp.png";
	File file = new File(Environment.getExternalStorageDirectory() + "/", "tmp.png");
	mCameraPhotoPath = file.getAbsolutePath();
	if (!file.exists()) {
    	try {
        	file.createNewFile();
    	} catch (IOException e) {
        	e.printStackTrace();
    	}
	}
	return file;
}

我们知道,从activity打开文件选择器,文件信息是在onActivityResult里返回来了,因为在5.0发布后,ValueCallback参数里包裹着不再是Uri,而是Uri数组。所以在给h5回调的时候还需要给5.0+做相应的回调。

public void onActivityResult(int requestCode, int resultCode, Intent data) {
	if (requestCode == FILECHOOSER_RESULTCODE && mUploadMessage != null) {
    	Uri result = null;
    	if (resultCode == Activity.RESULT_OK && data != null) {
        	result = data.getData();
        	if (result != null) {
            	String imagePath = ImagePathUtil.getPath(mContext, result);
            	if (!TextUtils.isEmpty(imagePath)) {
                	result = Uri.parse("file:///" + imagePath);
            	}
        	}
    	}
    	mUploadMessage.onReceiveValue(result);
    	mUploadMessage = null;
	} else if (requestCode == INPUT_FILE_REQUEST_CODE && mFilePathCallback != null) {
    	// 5.0的回调
    	Uri[] results = null;
    	// Check that the response is a good one
    	if (resultCode == Activity.RESULT_OK) {
        	if (data == null) {
            	// If there is not data, then we may have taken a photo
            	if (mCameraPhotoPath != null) {
                	results = new Uri[]{Uri.parse(mCameraPhotoPath)};
            	}
        	} else {
            	String dataString = data.getDataString();
            	if (dataString != null) {
                	results = new Uri[]{Uri.parse(dataString)};
            	}
        	}
    	}
    	mFilePathCallback.onReceiveValue(results);
    	mFilePathCallback = null;
	}
}

2、Dom

开启本地DOM存储。应该是Html 5中的localStorage(可以使用Android4.4手机和Chrome Inspcet Device联调),用于持久化的本地存储,除非主动删除数据,否则数据是永远不会过期的,绝大多数的浏览器都是支持 localStorage 的,但是鉴于它的安全特性(任何人都能读取到它,尽管有相应的限制,将敏感数据存储在这里依然不是明智之举),Android 默认是关闭该功能的。

//Sets whether the DOM storage API is enabled. The default value is false. 
mSettings.setDomStorageEnabled(true);//开启DOM

3、音视频自动播放

在打开一个h5页面时,如果h5页面需要自动播放一个音视频时,为了在android端能够自动播放,h5需要在js中调用autoPlay方法来播放多媒体,但是在android4.2以后版本,对于这种非用户手势促发的播放,默认是不允许的。

// 设置4.2以后版本支持autoPlay,非用户手势促发
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
    mSettings.setMediaPlaybackRequiresUserGesture(false);
}

4、混合内容

Mixed Content问题发生在HTTPS页面中通过HTTP方式引用资源。
对于安卓,WebView有配置可以设定Mixed Content的行为。
产生这种行为的原因是在安卓21之前,这种行为默认是被允许的,而21之后,Mixed Content被视为不安全的行为被默认禁止。

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
  	mSettings.setMixedContentMode(WebSettings.MIXED_CONTENT_ALWAYS_ALLOW);
}

5、userAgent

userAgent 属性是一个只读的字符串,声明了浏览器用于 HTTP 请求的用户代理头的值。

mSettings.setUserAgentString(mSettings.getUserAgentString() + " QLChat/" + VersionInfoUtil.getVersionCode());

6、开启debug

有时候需要调试webview页面,但在android4.4以后,默认就不允许了。

//Enables debugging of web contents (HTML / CSS / JavaScript)
if (BuildConfig.DEVELOPMENT_ENV) {
    setWebContentsDebuggingEnabled(true);
}

7、其它设置

//设置字符编码
mSettings.setDefaultTextEncodingName("utf-8");
//设置web页面
mSettings.setAllowFileAccess(true);//设置支持文件流
mSettings.setSupportZoom(false);// 支持缩放
mSettings.setBuiltInZoomControls(false);// 支持缩放
mSettings.setUseWideViewPort(true);// 调整到适合webview大小
mSettings.setLoadWithOverviewMode(true);// 调整到适合webview大小
mSettings.setDefaultZoom(WebSettings.ZoomDensity.FAR);// 屏幕自适应网页,如果没有这个,在低分辨率的手机上显示可能会异常
mSettings.setRenderPriority(WebSettings.RenderPriority.HIGH);
//提高网页加载速度,暂时阻塞图片加载,然后网页加载好了,在进行加载图片
mSettings.setBlockNetworkImage(true);
mSettings.setAppCacheEnabled(false);//开启缓存机制

猜你喜欢

转载自blog.csdn.net/u012587024/article/details/82970395