这篇“Android无需权限调用系统相机拍照怎么实现”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“Android无需权限调用系统相机拍照怎么实现”文章吧。
正文
在进行一些小型APP的开发,或者是对拍照界面没有自定义要求时,我们可以用调起系统相机的方式快速完成拍照需求
和不需读写权限进行读写操作的方案一样,都是通过Intent启动系统的activity让用户进行操作,系统再将用户操作的结果告诉我们,因为过程对APP是完全透明的,所以不会侵犯用户隐私。
有两种方法可以调起系统相机拍照获取图片,我们先讲比较简单的一种
1、直接获取用户拍照结果
val launcher = registerForActivityResult(ActivityResultContracts.TakePicturePreview()) {bitmap-> bitmap ?: return@registerForActivityResult vm.process(bitmap) } launcher.launch("image/*")
这个在旧版本的API中就等于
startActivityForResult(Intent(MediaStore.ACTION_IMAGE_CAPTURE),CODE)
等到用户完成拍照,返回我们的activity时,我们就可以得到一张经过压缩的bitmap。这个方法很简单,它的缺点就是获得的bitmap像素太低了,如果对图片像素有要求的话需要使用第二种方法
2、用户拍照之后指定相机将未压缩的图片存放到我们指定的目录
var uri: Uri? = null val launcher = registerForActivityResult(ActivityResultContracts.TakePicture()) { if(it){ uri?.let { it1 -> vm.process(it1) } } } val picture = File(externalCacheDir?.path, "picture") picture.mkdirs() uri = FileProvider.getUriForFile( this, "${BuildConfig.APPLICATION_ID}.fileprovider", File(picture, "cache") ) launcher.launch(uri)
这里我逐行进行解释:
首先,我们需要指定拍摄的照片要存到哪,所以我们先指定图片的存放路径为externalCacheDir.path/picture/cache 注意这张图片在文件系统中的名字就叫做cache了(没有文件后缀)。
然后我们通过FileProvider构建一个有授权的Uri给系统相机,相机程序拿到我们的临时授权,才有权限将文件存放到APP的私有目录。
系统相机拍照完成之后就会走到回调,如果resultCode为RESULT_OK才说明用户成功拍照并保存图片了。这样我们就能得到一张系统相机拍出来的原图的Uri,这样我们就可以用这张图片去处理业务了。
注意:使用方法二需要用到FileProvider,所以我们还要在AndroidManifest里声明
<provider android:name="androidx.core.content.FileProvider" android:authorities="${applicationId}.fileprovider" android:exported="false" android:grantUriPermissions="true"> <meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/provider_paths" /> </provider>
@xml/provider_paths是我们授权访问的文件路径,这里我写的是
<paths xmlns:android="http://schemas.android.com/apk/res/android"> <external-path name="external_files" path="."/> </paths>
关于这个"path.xml",其实还有一些可以补充说明的,后面有空会补上,这里我简单说明一下:
因为我们创建临时文件的时候,文件指定的目录是externalCacheDir?.path,对应的path就是external-cache-path,表示我们要临时授权的目录是externalCacheDir,如果文件目录指定的是其他路径,那path节点也需要改成代表对应文件夹的节点,这样其他应用才能访问到我们APP的私有目录。