公司的某个项目中有调用摄像头拍照的功能,在开发过程中使用了类似小米mix2(Miui12.0.1基于Android9) 华为Nova2s(EMUI9.1.0基于Android9)中测试均无问题,但是好巧不巧吧领导在使用时点击对应功能按钮无反应(无法调用摄像头),后面拿到领导的手机发现有钱人用的那是高端大气的Sony并且系统是Android11.
- 实现代码
<!--相机权限-->
<uses-permission android:name="android.permission.CAMERA" />
<!--读写文件权限-->
<uses-permission
android:name="android.permission.WRITE_EXTERNAL_STORAGE"
tools:ignore="ScopedStorage" /> <!-- 用于写入缓存数据到扩展存储卡 -->
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
~~~kotlin
private var currentPhotoPath= "" // 保存文件路径
private lateinit var photoUri: Uri // 保存照片的uri
@SuppressLint("QueryPermissionsNeeded")
private fun takePicture() {
Intent(MediaStore.ACTION_IMAGE_CAPTURE).also { takePictureIntent ->
takePictureIntent.resolveActivity(packageManager)?.also {
val photoFile: File = createImageFile()
photoFile.also {
photoUri = FileProvider.getUriForFile( // 根据文件创建uri
this,
"com.imowfms.uploadcertinfo.fileprovider", // 在清单文件声明的权限全称
it
)
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoUri) // 传入目标uri
startActivityForResult(takePictureIntent,CAMERA_RESULT_CODE)
}
}
}
}
private fun createImageFile(): File {
val storageDir: File? = this.filesDir // 目标存储在 files 文件夹内
return File.createTempFile(
"JPEG_${System.currentTimeMillis()}_", // 文件名
".jpg", // 后缀
storageDir // 存储文件夹
).apply {
currentPhotoPath = absolutePath
}
}
@SuppressLint("SetTextI18n")
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
when (requestCode) {
CAMERA_RESULT_CODE -> {
val imageFile = File(currentPhotoPath)
if (resultCode == RESULT_OK){
// 判断文件是否存在
// 不存在则提示
if (!imageFile.exists()){
Toast.makeText(this, "图片文件不存在", Toast.LENGTH_SHORT).show()
return
}
// 存在则转为bitmap显示
val photo = imageSizeCompress(photoUri)
// println("bitmap大小: ${photo!!.byteCount}")
certPicture.setImageBitmap(photo) // 这里是显示图片,控件按照自己的来
} else if (resultCode == RESULT_CANCELED){ // 拒绝了
// 未拍摄则提示
if (FileSizeUtil.getFileSize(imageFile) == 0.toLong()){
Toast.makeText(this, "图片未拍摄", Toast.LENGTH_SHORT).show()
// 删除本地空文件
imageFile.delete()
certPicture.isVisible = false
return
}
}
}
}
}
- 兼容Android 11 需要在权限文件增加
<!--android11无此代码则无法调用摄像头 -->
<queries>
<intent>
<action android:name="android.media.action.IMAGE_CAPTURE" />
</intent>
</queries>