Android拉起系统相机拍照的两种方式及陷阱

简介: 在Android中我们可以通过Camera Api在应用内拍照,也可以拉起系统相机进行拍照。拉起系统相机拍照有两种方式。

前言


在Android中我们可以通过Camera Api在应用内拍照,也可以拉起系统相机进行拍照。拉起系统相机拍照有两种方式。


Bitmap形式


这种方式会直接返回Bitmap对象 通过ACTION_IMAGE_CAPTURE这个action调用即可


var intent = Intent(MediaStore.ACTION_IMAGE_CAPTURE)
startActivityForResult(intent, code)
复制代码


结果处理如下:


override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
    super.onActivityResult(requestCode, resultCode, data)
    if(requestCode == code && data != null) {
        var bitmap = data?.extras?.get("data") as Bitmap
        imageView.setImageBitmap(bitmap)
    }
}
复制代码


在intent中直接返回Bitmap对象,所以我们可以直接进行处理


文件形式


这种方式会将图片保存为预定的文件,所以在调用的时候需要传入保存的路径MediaStore.EXTRA_OUTPUT


var intent = Intent(MediaStore.ACTION_IMAGE_CAPTURE)
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
    file = File(cacheDir, "2.jpg")
    file?.parentFile?.mkdirs()
    intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
    uri = FileProvider.getUriForFile(this, "包名.fileprovider", file!!)
}
else {
    uri = Uri.fromFile(File(Environment.getExternalStorageDirectory(), "1.jpg"))
}
intent.putExtra(MediaStore.EXTRA_OUTPUT, uri)
startActivityForResult(intent, code)
复制代码


这里由于涉及到7.0系统对文件添加了一层安全措施,所以要区别处理。在7.0以下,直接获取uri即可,但是在7.0以上则需要使用FileProvider。

想要使用FileProvider,上面的代码还不够,我们还需要创建一个xml,在res目录下新建xml目录(如果已有则忽略),在其下新建一个文件file_provider_paths.xml


<?xml version="1.0" encoding="utf-8"?>
<paths>
    <cache-path
        name="picture"
        path="."/>
</paths>
复制代码


然后在manifest中添加


<provider
    android:name="android.support.v4.content.FileProvider"
    android:authorities="包名.fileprovider"
    android:exported="false"
    android:grantUriPermissions="true">
    <meta-data
        android:name="android.support.FILE_PROVIDER_PATHS"
        android:resource="@xml/file_provider_paths" />
</provider>
复制代码


这里exported和grantUriPermissions是必须的。 然后添加对应的存储权限。


注意:

代码中FileProvider.getUriForFile的第二个参数的值要与authorities一样。

为intent添加一个Intent.FLAG_GRANT_READ_URI_PERMISSION的flag。

文件的路径要与xml中配置的一致,比如例子中是cache-path,path是"."即本目录,所以代码中的文件路径应该是Context.getCacheDir() + 文件名

如果是6.0以上手机,还需要进行动态权限申请

有关FileProvider这里就不细说了.


结果处理就比较简单,如下:


override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
    super.onActivityResult(requestCode, resultCode, data)
    if(requestCode == code) {
        var bitmap = MediaStore.Images.Media.getBitmap(contentResolver, uri)
        //var bitmap = BitmapFactory.decodeFile(file!!.absolutePath)
        imageView.setImageBitmap(bitmap)
    }
}
复制代码


可以通过uri或file两种方式来获取bitmap使用



通过FileProvider形式拉起相机还需要注意一个问题,在部分手机上外置存储卡的空间不能被应用随意使用。 比如:


<?xml version="1.0" encoding="utf-8"?>
<paths>
    <external-path
        name="picture"
        path="."/>
</paths>
复制代码


代码中则是:


file = File(Environment.getExternalStorageDirectory(), "2.jpg")
file?.mkdirs()
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
uri = FileProvider.getUriForFile(this, "包名.fileprovider", file!!)
复制代码


在部分手机上拉起相机拍照后无法保存到该路径下,所以在处理结果的时候会报FileNotFoundException 或 No such file or directory这种错误。即使允许了存储权限也不可以。

这种情况就不能使用外置存储,尽量使用应用本身的存储空间,比如例子中的CacheDir


目录
相关文章
|
3月前
|
XML Java Android开发
微信虚拟视频插件安卓,微信虚拟相机替换拍照,java源码分享
完整的相机应用项目包含三个主要文件:主活动实现、布局文件和清单文件。代码实现了相机预览、
|
1月前
|
Linux 测试技术 语音技术
【车载Android】模拟Android系统的高负载环境
本文介绍如何将Linux压力测试工具Stress移植到Android系统,用于模拟高负载环境下的CPU、内存、IO和磁盘压力,帮助开发者优化车载Android应用在多任务并发时的性能问题,提升系统稳定性与用户体验。
163 6
|
1月前
|
Java 数据库 Android开发
基于Android的电子记账本系统
本项目研究开发一款基于Java与Android平台的开源电子记账系统,采用SQLite数据库和Gradle工具,实现高效、安全、便捷的个人财务管理,顺应数字化转型趋势。
|
3月前
|
Android开发 数据安全/隐私保护
手机微信虚拟视频聊天,安卓免root虚拟摄像头,免root虚拟hook相机
以上代码实现了一个完整的免root虚拟摄像头方案,通过Hook系统摄像头服务和微信视频通话接口
|
3月前
|
Java Android开发
安卓虚拟摄像头过人脸,免root虚拟hook相机,虚拟相机hook版【jar】
两种Hook Android相机的方法:Xposed模块和Frida脚本。Xposed模块需要安装在已root的设备
|
11月前
|
人工智能 搜索推荐 物联网
Android系统版本演进与未来展望####
本文深入探讨了Android操作系统从诞生至今的发展历程,详细阐述了其关键版本迭代带来的创新特性、用户体验提升及对全球移动生态系统的影响。通过对Android历史版本的回顾与分析,本文旨在揭示其成功背后的驱动力,并展望未来Android可能的发展趋势与面临的挑战,为读者呈现一个既全面又具深度的技术视角。 ####
|
6月前
|
安全 搜索推荐 Android开发
Android系统SELinux安全机制详解
如此看来,SELinux对于大家来说,就像那位不眠不休,严阵以待的港口管理员,守护我们安卓系统的平安,维护这片海港的和谐生态。SELinux就这样,默默无闻,却卫士如山,给予Android系统一份厚重的安全保障。
228 18
|
11月前
|
算法 JavaScript Android开发
|
11月前
|
IDE Java 开发工具
移动应用与系统:探索Android开发之旅
在这篇文章中,我们将深入探讨Android开发的各个方面,从基础知识到高级技术。我们将通过代码示例和案例分析,帮助读者更好地理解和掌握Android开发。无论你是初学者还是有经验的开发者,这篇文章都将为你提供有价值的信息和技巧。让我们一起开启Android开发的旅程吧!
|
12月前
|
缓存 Java Shell
Android 系统缓存扫描与清理方法分析
Android 系统缓存从原理探索到实现。
439 15
Android 系统缓存扫描与清理方法分析