/**
* webView 基类,做好了大部分配置,子类根据需要重写方法
*/
abstract class BaseWebViewActivity : BaseActivity() {
lateinit var mWebView: WebView
var uploadMessage: ValueCallback<Uri>? = null
var uploadMessageArray: ValueCallback<Array<Uri>>? = null
val REQ_CAMERA = 0x1221
val REQ_ALBUM = 0x1222
val REQ_FILE = 0x1223
val DCIMPATH = "${Environment.getExternalStorageDirectory()}/DCIM"
var imageName: String = ""
/**
* 初始化WebView
*/
open fun initWebView(mWebView: WebView) {
this.mWebView = mWebView
val webSettings = mWebView.settings
//如果访问的页面中要与Javascript交互,则webview必须设置支持Javascript
webSettings.javaScriptEnabled = true
//支持插件
webSettings.pluginState = WebSettings.PluginState.ON
//设置自适应屏幕,两者合用 这样会使加载文本时 文字变小
webSettings.useWideViewPort = true; //将图片调整到适合webview的大小
webSettings.loadWithOverviewMode = true; // 缩放至屏幕的大小
webSettings.setRenderPriority(WebSettings.RenderPriority.HIGH)//提高渲染的优先级
//缩放操作
webSettings.setSupportZoom(true) //支持缩放,默认为true。是下面那个的前提。
webSettings.builtInZoomControls = true //设置内置的缩放控件。若为false,则该WebView不可缩放
webSettings.displayZoomControls = false //隐藏原生的缩放控件
//开启DomStorage缓存
webSettings.domStorageEnabled = true
//启用数据库
webSettings.databaseEnabled = true
// //设置定位的数据库路径
// String dir = this.getApplicationContext().getDir("database", Context.MODE_PRIVATE).getPath();
// webSettings.setGeolocationDatabasePath(dir);
//其他细节操作
webSettings.cacheMode = WebSettings.LOAD_NO_CACHE //不使用缓存
webSettings.allowFileAccess = true //设置可以访问文件
webSettings.javaScriptCanOpenWindowsAutomatically = true //支持通过JS打开新窗口
webSettings.loadsImagesAutomatically = true //支持自动加载图片
webSettings.defaultTextEncodingName = "utf-8"//设置编码格式
//支持内容重新布局
webSettings.layoutAlgorithm = WebSettings.LayoutAlgorithm.SINGLE_COLUMN
//这个是加载的地址是https的,一些资源文件使用的是http方法的,
// 从安卓4.4之后对webview安全机制有了加强,webview里面加载https url的时候,
// 如果里面需要加载http的资源或者重定向的时候,webview会block页面加载。需要设置MixedContentMode
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
webSettings.mixedContentMode = WebSettings.MIXED_CONTENT_ALWAYS_ALLOW
}
setWebViewClient(mWebView)
setWebChromeClient(mWebView)
setDownloadListener(mWebView)
}
/**
* 下载监听
*/
open fun setDownloadListener(mWebView: WebView) {
mWebView.setDownloadListener { url, userAgent, contentDisposition, mimetype, contentLength ->
try {
val intent = Intent()
intent.action = Intent.ACTION_VIEW
intent.data = Uri.parse(url)
startActivity(intent)
} catch (e: Exception) {
e.printStackTrace()
}
}
}
/**
* 子类需要时可重写
*/
open fun setWebViewClient(mWebView: WebView) {
mWebView.webViewClient = object : WebViewClient() {
override fun shouldOverrideUrlLoading(view: WebView?, url: String?): Boolean {
view!!.loadUrl(url)
return true
}
@RequiresApi(Build.VERSION_CODES.LOLLIPOP)
override fun shouldOverrideUrlLoading(view: WebView?, request: WebResourceRequest?): Boolean {
view!!.loadUrl(request!!.url.toString())
return true
}
}
}
/**
* 子类需要时可重写
*/
open fun setWebChromeClient(mWebView: WebView) {
mWebView.webChromeClient = object : WebChromeClient() {
/**
* 16(Android 4.1.2) <= API <= 20(Android 4.4W.2)回调此方法
*/
fun openFileChooser(valueCallback: ValueCallback<Uri>, acceptType: String, capture: String) {
uploadMessage = valueCallback
fileChooser(acceptType)
}
/**
* API >= 21(Android 5.0.1)回调此方法
*/
@RequiresApi(LOLLIPOP)
override fun onShowFileChooser(
webView: WebView?,
filePathCallback: ValueCallback<Array<Uri>>?,
fileChooserParams: FileChooserParams?
): Boolean {
uploadMessageArray = filePathCallback!!
fileChooser(fileChooserParams!!.acceptTypes[0])
return true//这里要返回true 不然选择文件时会crash
// return super.onShowFileChooser(webView, filePathCallback, fileChooserParams)
}
}
}
/**
* 根据类型选取文件
*/
open fun fileChooser(acceptType: String) {
LogUtil.debug("acceptType=" + acceptType)
when (acceptType) {
"image/*" -> {
val selectPicTypeStr = arrayOf("拍摄", "从相册中选择")
AlertDialog.Builder(this)
.setOnCancelListener { onReceiveValue(null) }
.setItems(selectPicTypeStr) { dialog, which ->
when (which) {
0 -> {
openCamera()
}
1 -> {
selectImage(REQ_ALBUM)
}
}
}.show()
}
"video/*" -> {
selectVideo(REQ_ALBUM)
}
else -> {
selectFile(REQ_FILE)
}
}
}
/**
* 打开摄像头拍照
*/
fun openCamera() {
val intent = Intent(MediaStore.ACTION_IMAGE_CAPTURE)
imageName = System.currentTimeMillis().toString() + ".png"
val file = File(DCIMPATH)
if (!file.exists()) {
file.mkdirs()
}
intent.putExtra(
MediaStore.EXTRA_OUTPUT, FileUtil.createFileUri(this, File(DCIMPATH, imageName))
)
startActivityForResult(intent, REQ_CAMERA)
}
/**
* 选择图片
*/
fun selectImage(requestCode: Int) {
if (!FileUtil.hasSDcard(this)) {
onReceiveValue(null)
return
}
val intent = Intent()
intent.type = "image/*"
intent.action = Intent.ACTION_PICK
intent.data = android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI;//使用以上这种模式,并添加以上两句
startActivityForResult(intent, requestCode)
}
/**
* 选择视频文件
*/
fun selectVideo(requestCode: Int) {
if (!FileUtil.hasSDcard(this)) {
onReceiveValue(null)
return
}
val intent = Intent()
intent.action = Intent.ACTION_PICK
intent.type = "video/*"
startActivityForResult(Intent.createChooser(intent, "选择要导入的视频"), requestCode)
}
/**
* 为空的时候就 就统一选择文件
*/
fun selectFile(requestCode: Int) {
if (!FileUtil.hasSDcard(this)) {
onReceiveValue(null)
return
}
val intent = Intent()
intent.action = Intent.ACTION_PICK
intent.type = "*/*"
startActivityForResult(Intent.createChooser(intent, "选择要导入的文件"), requestCode)
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if (resultCode !== Activity.RESULT_OK) {
onReceiveValue(null)
return
}
when (requestCode) {
REQ_CAMERA -> {
val fileCamera = File(DCIMPATH, imageName)
handleFile(fileCamera)
}
REQ_ALBUM -> {
val uri = data!!.data
if (uri != null) {
val absolutePath = FileUtil.getRealFilePath(this, uri)
if (absolutePath != null) {
val fileAlbum = File(absolutePath)
handleFile(fileAlbum)
}
}
}
REQ_FILE -> {
val uri = data!!.data
if (uri != null) {
val absolutePath = FileUtil.getRealFilePath(this, uri)
if (absolutePath != null) {
val fileAlbum = File(absolutePath)
handleFile(fileAlbum)
}
}
}
}
}
private fun handleFile(file: File) {
if (file.isFile()) {
onReceiveValue(file)
} else {
onReceiveValue(null)
}
}
/**
* 接受参数结束
*/
fun onReceiveValue(file: File?) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
if (uploadMessageArray != null) {
if (file == null) {
uploadMessageArray!!.onReceiveValue(null)
} else {
val uri = Uri.fromFile(file)
val uriArray = arrayOf(uri)
uploadMessageArray!!.onReceiveValue(uriArray)
uploadMessageArray = null
}
}
} else {
if (uploadMessage != null) {
if (file == null) {
uploadMessageArray!!.onReceiveValue(null)
} else {
val uri = Uri.fromFile(file)
uploadMessage!!.onReceiveValue(uri)
uploadMessage = null
}
}
}
}
//处理返回键
override fun onKeyDown(keyCode: Int, event: KeyEvent?): Boolean {
if (keyCode == KeyEvent.KEYCODE_BACK) {
if (this.mWebView.canGoBack()) {
this.mWebView.goBack()
return true
}
}
return super.onKeyDown(keyCode, event)
}
public override fun onResume() {
super.onResume()
mWebView.onResume()
}
public override fun onPause() {
super.onPause()
mWebView.onPause()
}
}