[h5呼叫ios相册]

电脑杂谈  发布时间:2020-03-20 18:32:52  来源:网络整理

ios调用相机和相册_ios 相机相册_ios 相机相册权限

在开发中,H5有时用于调用本地图片或照相机. 例如,第三方实名认证,客户服务等都需要上传图片. H5仅需要由调用ios调用相机和相册,可以实现ios,并且不需要自己处理它,除非客户端压缩图片,但是Android需要自己处理它. 过程和遇到的问题.

H5主要通过输入标签获取图像

 <input class="upload-input"  accept="image/*" multiple required type="file" @change="chooseImg">

ios调用相机和相册_ios 相机相册权限_ios 相机相册

通过WebView加载h5页面,侦听WebView的相应方法,并实现自己的逻辑.

WebView初始化ios调用相机和相册,释放相应的权限

private fun initWebView() {
        val settings = mWebView.settings
        settings.javaScriptEnabled = true
        settings.javaScriptCanOpenWindowsAutomatically = true
        //自适应屏幕
        settings.layoutAlgorithm = SINGLE_COLUMN
        settings.loadWithOverviewMode = true
        settings.domStorageEnabled = true
        settings.databaseEnabled = true
        settings.setSupportZoom(false)
        mWebView.isHorizontalScrollBarEnabled = false
        mWebView.isVerticalScrollBarEnabled = false
        mWebView.webViewClient = webViewClient
        mWebView.webChromeClient = webViewChromeClient
}

设置WebChromeClient

单击输入标签后,将调用WebChromeClient的onShowFileChooser()方法(5.0+)或openFileChooser()方法(3.0+)处理此方法中的逻辑. 这是一个本机选择框,会弹出以从相册中进行选择. 仍要拍照才能拍照.

ios调用相机和相册_ios 相机相册权限_ios 相机相册

private val webViewChromeClient = object : WebChromeClient() {
      override fun onShowFileChooser(webView: WebView, filePathCallback: ValueCallback<Array<Uri>>,
                                     fileChooserParams: FileChooserParams): Boolean {
          mFilePathCallback = filePathCallback
          val acceptTypes = fileChooserParams.acceptTypes
          //判断文件类型
          if (acceptTypes.contains("image/*")) {
              showSelectDialog()
          }
          return true
      }
}

ValueCallbacks由WebView组件提供给我们. 它包含一个或一组Uri,然后将Uri传递给onActivityResult()中ValueCallbacks的OnReceiveValue()方法,因此文件被传递回H5端.

注意: 在这里您将遇到onShowFileChooser()仅被调用一次的问题,即第二次单击按钮时不再调用该方法,因为每次调用该方法时,都需要设置回调,无论是否选中“照片”,否则返回null

/**
 * 显示相册/拍照选择对话框
 */
private fun showSelectDialog() {
    if (mSelectPhotoDialog == null) {
        mSelectPhotoDialog = SelectDialog(this, View.OnClickListener { view ->
            when (view.id) {
                R.id.tv_camera -> startCamera()
                R.id.tv_photo -> startAlbum()
                //不管选择还是不选择,必须有返回结果,否则就会调用一次
                R.id.tv_cancel -> {
                    mFilePathCallback?.onReceiveValue(null)
                    mFilePathCallback = null
                }
            }
        })
    }
    mSelectPhotoDialog?.show()
}

拍照和打开相册的功能封装在PhotoUtils工具类中.

ios 相机相册权限_ios 相机相册_ios调用相机和相册

/**
 * 拍照
 * @param context Activity
 */
fun startCamera(context: Activity) {
    val intent = Intent(MediaStore.ACTION_IMAGE_CAPTURE)
    PATH_PHOTO = getSdCardDirectory(context) + "/temp.png"
    val temp = File(PATH_PHOTO)
    if (!temp.parentFile.exists()) {
        temp.parentFile.mkdirs()
    }
    if (temp.exists()) {
        temp.delete()
    }
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
        //添加这一句表示对目标应用临时授权该Uri所代表的文件
        intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
        intent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION)
        // 通过FileProvider创建一个content类型的Uri
        val uri: Uri = FileProvider.getUriForFile(context, context.packageName + ".fileprovider", temp)
        intent.putExtra(MediaStore.EXTRA_OUTPUT, uri)
    } else {
        intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(temp))
    }
    context.startActivityForResult(intent, RESULT_CODE_CAMERA)
}

注意: 您需要适应拍照. 否则,您将无法获取文件. Android 7.0和更高版本通过FileProvider在应用程序之间共享文件. 另外,拍照时请勿使用意图来获取数据. 获取路径,意图始终为空

<application
 ......
    <!-- Android7.0拍照权限适配 -->
    <provider
        android:name="androidx.core.content.FileProvider"
        android:authorities="com.gfd.h5pic.fileprovider"
        android:exported="false"
        android:grantUriPermissions="true">
        <meta-data
            android:name="android.support.FILE_PROVIDER_PATHS"
            android:resource="@xml/file_paths" />
    </provider>
</application>

file_paths.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <paths>
        <cache-path
            name="cache"
            path="" />
        <external-path
            name="sdcard_files"
            path="" />
        <external-path
            name="external"
            path="" />
        <external-files-path
            name="external_files"
            path="" />
        <external-cache-path
            name="external_cache"
            path="" />
        <root-path
            name="ex_sdcard_files"
            path="" />
        <!--相机相册裁剪-->
        <external-files-path
            name="camera_has_sdcard"
            path="file/" />
        <files-path
            name="camera_no_sdcard"
            path="" />
    </paths>
</resources>

ios调用相机和相册_ios 相机相册_ios 相机相册权限

从相册中选择

/**
 * 打开相册
 * @param context Activity
 */
fun startAlbum(context: Activity) {
    val albumIntent = Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI)
    albumIntent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
    albumIntent.setDataAndType(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, "image/*")
    context.startActivityForResult(albumIntent, RESULT_CODE_PHOTO)
}

意图通过onActivityResult()方法获取所选照片.

onActivityResult()方法处理

override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
    super.onActivityResult(requestCode, resultCode, data)
    if (requestCode == PhotoUtils.RESULT_CODE_CAMERA && resultCode == Activity.RESULT_OK) {
        //拍照并确定
        compressPicture(PhotoUtils.PATH_PHOTO)
    } else if (requestCode == PhotoUtils.RESULT_CODE_PHOTO && resultCode == Activity.RESULT_OK) {
        //相册选择并确定
        val result = data?.data
        val path = result?.let { PhotoUtils.getPath(this, it) }
        if (path == null) {
            mFilePathCallback?.onReceiveValue(null)
        } else {
            compressPicture(path)
        }
    } else {
        mFilePathCallback?.onReceiveValue(null)
    }
}

这里要注意确定resultCode,否则将拍照,选择不是确定而是取消,然后图片将被上传.

这是使用Luban压缩上传的

/**
 * 压缩图片
 */
private fun compressPicture(path: String) {
    PhotoUtils.compressPicture(this, path, object : PhotoUtils.OnPictureCompressListener() {
        override fun onSuccess(file: File) {
            //上传图片
            mFilePathCallback?.onReceiveValue(arrayOf(Uri.fromFile(file)))
        }
        override fun onError(e: Throwable) {
            mFilePathCallback?.onReceiveValue(null)
        }
    })
}

如果您看到此内容并认为文章写得不错,请赞美!欢迎大家发表评论和讨论!如果您认为有什么值得改进的地方,请给我留言. 我们一定会查询,纠正不足的情况,并定期免费共享技术干货. 谢谢!


本文来自电脑杂谈,转载请注明本文网址:
https://www.pc-fly.com/a/ruanjian/article-146295-1.html

    相关阅读
      发表评论  请自觉遵守互联网相关的政策法规,严禁发布、暴力、反动的言论

      热点图片
      拼命载入中...