写点什么

Android 11 适配指南之系统相机拍照、打开相册,Android 开发两年

用户头像
Android架构
关注
发布于: 刚刚

data?.data!!即是选择图片返回的Uri,可以直接使用,这里进行了下一步操作,剪裁

剪裁

private fun doCrop(sourceUri: Uri) {


Intrinsics.checkParameterIsNotNull(sourceUri, "资源为空")


UCrop.of(sourceUri, getDestinationUri())//当前资源,保存目标位置


.withAspectRatio(1f, 1f)//宽高比


.withMaxResultSize(500, 500)//宽高


.start(this)


}


为了方便,这里使用了一个三方库UCrop,使用简单方便。


getDestinationUri()是当前资源裁剪后保存的目标位置


private fun getDestinationUri(): Uri {


val fileName = String.format("fr_crop_%s.jpg", System.currentTimeMillis())


val cropFile = File(getExternalFilesDir(Environment.DIRECTORY_PICTURES), fileName)


return Uri.fromFile(cropFile)


}


UCrop的回调同样也在onActivityResult


override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {


super.onActivityResult(requestCode, resultCode, data)


if (resultCode == RESULT_OK) {


when (requestCode) {


REQUEST_CODE_ALBUM -> {


doCrop(data?.data!!)


}


UCrop.REQUEST_CROP -> {


val resultUri: Uri = UCrop.getOutput(data!!)!!


val bitmap = BitmapFactory.decodeStream(contentResolver.openInputStream(resultUri))


// todo


}


UCrop.RESULT_ERROR -> {


val error: Throwable = UCrop.getError(data!!)!!


ToastUtil.show("图片剪裁失败" + error.message)


}


}


}


}


UCrop.getOutput(data!!)!!,即是返回的 Uri,可以直接操作,也可以转成bitmap


ok,到这里打开相册就介绍完了。


接下来看重点,打开相机。


author:yechaoa


打开相机


===============================================================


打开相机的流程就要稍微复杂一点了。

权限

第一步不是打开,而是先检查是否有相机权限,这个在某些手机上是必须的,比如华为。


  • 配置文件添加:


<uses-permission android:name="android.permission.CAMERA" />


  • 代码:


private fun checkPermission() {


if (ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED) {


openCamera()


} else {


ActivityCompat.requestPermissions(this, arrayOf(Manifest.permission.CAMERA), REQUEST_CODE_PERMISSIONS)


}


}


  • 回调:


override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<out String>, grantResults: IntArray) {


super.onRequestPermissionsResult(requestCode, permissions, grantResults)


if (requestCode == REQUEST_CODE_PERMISSIONS) {


if (grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED) {


openCamera()


} else {


ToastUtil.show("拒绝会导致无法使用相机")


}


}


}


openCamera方法就是打开相机了。

打开前适配

private fun open


《Android学习笔记总结+最新移动架构视频+大厂安卓面试真题+项目实战源码讲义》
浏览器打开:qq.cn.hn/FTe 免费领取
复制代码


Camera() {


val intent = Intent(MediaStore.ACTION_IMAGE_CAPTURE)


photoUri = getDestinationUri()


photoUri = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {


//适配 Android 7.0 文件权限,通过 FileProvider 创建一个 content 类型的 Uri


FileProvider.getUriForFile(this, "$packageName.fileProvider", File(photoUri.path!!))


} else {


getDestinationUri()


}


//android11 以后强制分区存储,外部资源无法访问,所以添加一个输出保存位置,然后取值操作


intent.putExtra(MediaStore.EXTRA_OUTPUT, photoUri)


startActivityForResult(intent, REQUEST_CODE_CAMERA)


}


  • 适配一:


FileProvider.getUriForFile(this, "$packageName.fileProvider", File(photoUri.path!!))


7.0 以上,使用fileProvider的方式共享文件。


  • 适配二:


intent.putExtra(MediaStore.EXTRA_OUTPUT, photoUri)


android 11以后强制分区存储,外部资源无法访问,所以添加一个输出保存位置photoUri,然后取值操作

回调

override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {


super.onActivityResult(requestCode, resultCode, data)


if (resultCode == RESULT_OK) {


when (requestCode) {


REQUEST_CODE_ALBUM -> {


doCrop(data?.data!!)


}


REQUEST_CODE_CAMERA -> {


//从保存的位置取值


doCrop(photoUri)


}


UCrop.REQUEST_CROP -> {


val resultUri: Uri = UCrop.getOutput(data!!)!!


val bitmap = BitmapFactory.decodeStream(contentResolver.openInputStream(resultUri))


// todo


}


UCrop.RESULT_ERROR -> {


val error: Throwable = UCrop.getError(data!!)!!


ToastUtil.show("图片剪裁失败" + error.message)


}


}


}


这里注意,不是相册那样从data取值了,而是从我们保存的位置里取值。


后面剪裁跟相册都是一样的流程了。


总结


=============================================================


这个功能点最大的变动就是分区存储了,Android 10或许还能过度一下,但是Android 11以后就是强制执行分区存储了。


应用可以在不需要读写权限的情况下,访问自己的分区,执行读写操作,卸载之后分区文件也相应删除,所以就不能有把缓存文件放到竞品的文件夹下这种操作了,还是乖乖的吧。


在 Android 10 以下,还是要读写权限的,还是可以胡作非为的。


获取自己的分区地址:


getExternalFilesDir(Environment.DIRECTORY_PICTURES)

用户头像

Android架构

关注

还未添加个人签名 2021.10.31 加入

还未添加个人简介

评论

发布
暂无评论
Android 11适配指南之系统相机拍照、打开相册,Android开发两年