相关文章

Android 仿微信加载H5页面进度条实现

Android WebView系列(二)Android和JS互调,BridgeWebView的使用。

前言

Android中通过WebViewH5页面进行交互,有时候会有其他需求比如H5页面需要从手机本地文件中选择图片。本篇以BridgeWebView介绍功能的实现。

1.自定义ProgressWebView

class ProgressWebView(context: Context, attr: AttributeSet) : BridgeWebView(context, attr) {        private var progressBar: ProgressBar? = null        private var hasComplate: Boolean = false        private var listener: OnImageSelectorListener? = null        init {                progressBar = ProgressBar(context, null, android.R.attr.progressBarStyleHorizontal)                progressBar!!.progressDrawable = context.resources.getDrawable(R.drawable.webview_hori_progress)                val layoutParams = FrameLayout.LayoutParams(LayoutParams.MATCH_PARENT, 6, 0)                 progressBar!!.layoutParams = layoutParams                 addView(progressBar)                 webChromeClient = object : WebChromeClient() {                      override fun onProgressChanged(view: WebView?, newProgress: Int) {                super.onProgressChanged(view, newProgress)                                  if (progress == 100) {                    hasComplate = true                    progressBar!!.visibility = View.GONE                } else {                    if (!hasComplate) {                        progressBar!!.visibility = View.VISIBLE                                                progressBar!!.progress = progress                    }                                         hasComplate = false                }            }                           fun openFileChooser(valueCallback: android.webkit.ValueCallback<Uri>, acceptType: String, capture: String) {                 listener!!.chooseImageFromSys4(valueCallback)            }                        override fun onShowFileChooser(webView: WebView?, filePathCallback: android.webkit.ValueCallback<Array<Uri>>?, fileChooserParams: FileChooserParams?): Boolean {                listener!!.chooseImageFromSys(filePathCallback)                return true            }        }    }    interface OnImageSelectorListener {                fun chooseImageFromSys(filePathCallback: ValueCallback<Array<Uri>>?)                  fun chooseImageFromSys4(valueCallback: android.webkit.ValueCallback<Uri>)    }    fun setOnSelectListener(listener: OnImageSelectorListener) {        this.listener = listener    }}

之前有篇博客介绍了仿微信加载H5进度条的实现,以此为基础,之前在加载csdn网站时,出现了一个现象,监听页面加载progress时,已经到了100后,进度又会重新加载一次,具体产生原因不知,猜测是加载页面后网址进行了重定向。所以这里做了一个小优化,加载完成后设置标志位让进度条不再显示。

openFileChooseronShowFileChooser 这两个方式是WebView辅助类WebChromeClient用来监听JS中事件,事件用来调用系统文件。当监听到后回调到Activity进行选择图片操作。

ValueCallback,这个类的作用是,将我们选择的图片回调给JS。而回调的类型是图片的UriValueCallback提供了一个方法.onReceiveValue(uri)

2.XML声明自定义的View

<com.xxx.yyyyy.widget.ProgressWebView     android:id="@+id/progressWebView"     android:layout_width="match_parent"     android:layout_height="match_parent" />

3.设置WebView,选择图片回调

3-1.配置WebView

这里是WebView几个重要必要的配置选项,其他配置根据自己情况而定

val setting = progressWebView!!.settingssetting!!.allowFileAccess = truesetting.javaScriptEnabled = truesetting.cacheMode = WebSettings.LOAD_CACHE_ELSE_NETWORKsetting.userAgentString = setting.userAgentString + "penglaiapp"if (Build.VERSION.SDK_INT > Build.VERSION_CODES.LOLLIPOP) {      setting.mixedContentMode = WebSettings.MIXED_CONTENT_ALWAYS_ALLOW}progressWebView!!.setDefaultHandler(MyHadlerCallBack())private inner class MyHadlerCallBack : DefaultHandler() {        override fun handler(data: String?, function: CallBackFunction?) {            if (function != null) {                Toast.makeText(this@IssueInvoiceActivity, "自定义类继承DefaultHandler:" + data!!, Toast.LENGTH_SHORT).show()            }        }    }        val params = HashMap<String, Any>()params["token"] = "token"params["money"] = invoiceMoneyparams["invoiceflag"] = invoiceTypeprogressWebView.callHandler("invoice", Gson().toJson(params)) {}progressWebView!!.registerHandler("goBack") { _, _ ->        finish()}        progressWebView!!.loadUrl(invoiceUrl)

3-2.WebView回调Activity

WebView回调选择图片操作在Activity里进行。

progressWebView!!.setOnSelectListener(object : ProgressWebView.OnImageSelectorListener {            /*4.0以上系统*/            override fun chooseImageFromSys4(valueCallback: ValueCallback) {                uploadMessage = valueCallback                chooseImageFromSys()            }            /*5.0以上系统*/            override fun chooseImageFromSys(filePathCallback: ValueCallback>?) {                uploadMessageAboveL = filePathCallback                chooseImageFromSys()            }        })

这里是自定义的弹窗选择拍照或者相册方式。

private fun chooseImageFromSys() {    SelectorDialog.Builder(this)           .addItem(1, resources.getString(R.string.camera))           .addItem(2, resources.getString(R.string.gallery))           .setCancelable(false).setOnSelectedListener { id, name ->               when (id) {                   /*选择相机拍照 这里默认已经获取权限*/                   1 ->                         onPickFromCameraClicked()                   /*相册选择*/                   2 ->                        onPickFromGaleryClicked()                   /*ValueCallback对象置空,否则无法再次获取JS事件*/                        -1 -> {                        /*取消按钮*/                          if (Build.VERSION.SDK_INT > Build.VERSION_CODES.LOLLIPOP) {                            uploadMessageAboveL!!.onReceiveValue(null)                            uploadMessageAboveL = null                        } else {                            uploadMessage!!.onReceiveValue(null)                            uploadMessage = null                           }                        }            }      }.build().show()}

3-3.相册选择与相机拍照

3-3-1.相册选择图片

 private val PICK_IMAGE_FROM_GALERY = 0x0002//相册选择RequestCode private fun onPickFromGaleryClicked() {        val intent = Intent(Intent.ACTION_PICK)        intent.setDataAndType(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, "image/*")        startActivityForResult(intent, PICK_IMAGE_FROM_GALERY)    }

3-3-2.调用相机拍照

private var imageUri: Uri? = null           //拍照Uri对象private var tempCameraFile: File? = null    //拍照获取File文件对象private val PICK_IMAGE_FROM_CAMERA = 0x0001 //拍照RequestCodeprivate fun openCamera() {       tempCameraFile = File(externalCacheDir, getString(R.string.cache__image, System.currentTimeMillis()))       //7.0以上 FileProvider 获取Uri       imageUri = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {            //通过FileProvider创建一个content类型的Uri            FileProvider.getUriForFile(this, "com.xxx.yyyy.fileProvider", tempCameraFile)        } else {            Uri.fromFile(tempCameraFile)        }        val intent = Intent()        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {            //添加这一句表示对目标应用临时授权该Uri所代表的文件            intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)        }        //设置Action为拍照        intent.action = MediaStore.ACTION_IMAGE_CAPTURE        //将拍取的照片保存到指定URI        intent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri)        startActivityForResult(intent, PICK_IMAGE_FROM_CAMERA)    }

3-4.选择图片回调

override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {        super.onActivityResult(requestCode, resultCode, data)                if (resultCode == RESULT_CANCELED) {                        if (Build.VERSION.SDK_INT > Build.VERSION_CODES.LOLLIPOP) {                uploadMessageAboveL!!.onReceiveValue(null)                uploadMessageAboveL = null            } else {                uploadMessage!!.onReceiveValue(null)                uploadMessage = null            }        }        when (requestCode) {                        PICK_IMAGE_FROM_GALERY -> {                tempCropFile = File(externalCacheDir,                        "pl_cover" + System.currentTimeMillis() + ".jpg")                                        handleImageOnKitKat(data)            }                        PICK_IMAGE_FROM_CAMERA-> {                if (tempCameraFile!!.exists()) {                    if (Build.VERSION.SDK_INT > Build.VERSION_CODES.LOLLIPOP) {                          uploadMessageAboveL!!.onReceiveValue(arrayOf(Uri.fromFile(tempCameraFile)))                        uploadMessageAboveL = null                    } else {                                                uploadMessage!!.onReceiveValue(Uri.fromFile(tempCameraFile))                        uploadMessage = null                    }                }            }        }    }
  //相册选择 获取uri  private fun handleImageOnKitKat(data: Intent?) {        imagePath = null        if (data != null) {            imageUri = data.data            if (Build.VERSION.SDK_INT > Build.VERSION_CODES.LOLLIPOP) {               uploadMessageAboveL!!.onReceiveValue(arrayOf(imageUri))                uploadMessageAboveL = null            } else {                uploadMessage!!.onReceiveValue(imageUri)                uploadMessage = null            }      }}

效果图

结尾

本篇介绍了WebView中选择图片功能实现。目前已经测试可用,大家也可以做参考。也有功能需要完善比如图片剪裁压缩等功能等。

更多相关文章

  1. Android(安卓)Studio App设置TextView文字内容大小颜色
  2. Android(安卓)TextView 中如何使用第三方字体
  3. Android项目运行提示
  4. android studio学习日记
  5. 日历视图的XML属性
  6. 安卓017ListView & GridView & ScrollView
  7. android中layout_gravity 和 gravity的区别
  8. Android黑科技动态加载(四)之动态启动插件Activity
  9. 【Android进阶】android:configChanges属性总结

随机推荐

  1. Android 虚拟多开系列二——技术原理
  2. Android的多媒体(Media Sever Framework )
  3. Android Studio上非常棒的插件
  4. Android 热敏打印机打印二维码
  5. 《Android移动应用基础教程》(Android Stu
  6. Android(安卓)版本兼容 — Android(安卓)
  7. Android kotlin学习之----kotlin+recycle
  8. 面向UDP的Android——PC双向通信(一):实现An
  9. Android基础入门教程——2.6 菜单(Menu)
  10. Android攻城狮面试指南