概述

在Android开发中获取图片主要包括如下两种方式:

打开相机拍照

从图库中选择图片

一、打开相机拍照

打开相机拍照主要包括如下几个部分:

权限申请

打开摄像头

拍照后传回数据处理

1. 权限申请

如果需要打开相机,则需要申请摄像头使用权限,在AndroidManifest.xml文件中添加如下代码:

如果拍完照片后需要存储图片,则还需要文件读写的权限.

注意权限申请在Android 6.0以上需要动态申请权限,在此不再赘述。

注意:

Android 10及以上,系统对文件读写的控制更加严格,如果想要粗暴的实现可读写效果,可以在AndroidManifest.xml中下配置如下代码达到效果:

android:requestLegacyExternalStorage="true"

2. 打开摄像头

打开摄像头可以通过设置intent来实现,示例如下:

private fun openCamera() {

if (PermissionUtils.instance.checkPermission(this, Manifest.permission.CAMERA)) {

//为intent指定Action

val intent = Intent(MediaStore.ACTION_IMAGE_CAPTURE)

startActivityForResult(intent, IntentUtil.instance.requestCameraPermissionCode)

} else {

ActivityCompat.requestPermissions(this, arrayOf(Manifest.permission.CAMERA), IntentUtil.instance.requestCameraPermissionCode)

}

}

通过为intent指定摄像头Action:MediaStore.ACTION_IMAGE_CAPTURE,然后直接通过startActivityForResult的方式启动Intent即可启动摄像头。

3. 拍照后传回数据处理

在拍照结束后,我们可以对拍照结束后的回传的intent及携带的数据进行处理,例如可以将传回的图片以文件的形式保存起来或者直接加载在ImageView中,示例如下:

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

super.onActivityResult(requestCode, resultCode, data)

if (resultCode == Activity.RESULT_OK) {

when (requestCode) {

IntentUtil.instance.requestCameraPermissionCode -> {

var extra = data?.extras

var photo = extra?.get("data") as Bitmap?

if (photo != null) {

var path = FileUtils.instance.getAppDir()

if (path != null) {

ImageUtils.instance.saveBitmapToFile(photo, System.currentTimeMillis().toString() + ".png",

"TestImg", this)

}

imgQRCode?.setImageBitmap(photo)

}

}

else -> {

}

}

}

}

通过在onActivityResult方法中获取到了intent对象,从其中获取到图片bitmap数据,然后进行对应的图片操作。

二、从相册中选取到图片

从相册中选取图片的实现主要包括如下几个步骤:

权限申请

打开相册选择图片

针对回传的图片uri地址去查询和获取到对应的文件的真实URI

根据文件URI获取到图片

1. 权限申请

从相册中选取图片所需要的权限主要包括文件读权限,在AndroidManifest.xml中添加如下代码:

Android 6.0及以上需要注意动态权限的申请,在此不再赘述。

Android 10及以上的处理同上。

2. 打开相册

和打开相机相似,打开相册也可以通过intent启动进行打开,示例代码如下:

private fun openImageUtils() {

val intent: Intent

if (Build.VERSION.SDK_INT < 19) {

intent = Intent(Intent.ACTION_GET_CONTENT)

intent.type = "image/*"

} else {

intent = Intent(

Intent.ACTION_PICK,

MediaStore.Images.Media.EXTERNAL_CONTENT_URI)

}

startActivityForResult(intent, IntentUtil.instance.openImageGalleryCode)

}

3. 针对回传数据进行处理

通过startActivityForResult启动intent,可以在onActivityResult中得到回传结果,因此可以通过回传的intent得到选择的图片的uri数据,示例代码如下:

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

super.onActivityResult(requestCode, resultCode, data)

if (resultCode == Activity.RESULT_OK) {

when (requestCode) {

IntentUtil.instance.openImageGalleryCode -> {

var uri = data?.data

if (data != null && uri != null) {

var imgPath = if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) {

ImageUtils.instance.handleImageBeforeKitKat(data, this)

} else {

ImageUtils.instance.handleImageOnKitKat(data, this)

}

displayImage(imgPath)

}

}

else -> {

}

}

}

}

获取到URI之后便可以对URI进行处理并获取到图片,但是需要注意的是Android在4.4前后通过图库选择得到的图片的URI并不是一致的,因此需要分开处理。

Android在4.4之前获取到的URI是真实文件路径,因此不需要做过多的处理。

Android在4.4之后获取到URI并不是文件的真实路径,可能是类似于下面这种路径,因此需要重新对此URI进行解析以拿到真正的文件路径。

com.android.providers.media.documents.image%3A11111

解析代码示例如下:

/**

* 从相册中读取图片,在4.4之后

* @param data:打开图片选择后返回的intent

* @param context

* @return

*/

fun handleImageOnKitKat(data: Intent, context: Context?): String? {

var imagePath: String? = null

val uri = data.data

if (DocumentsContract.isDocumentUri(context, uri)) {

// 如果是document类型的Uri,则通过document id处理

val docId = DocumentsContract.getDocumentId(uri)

if ("com.android.providers.media.documents" == uri!!.authority) {

val id = docId.split(":").toTypedArray()[1] // 解析出数字格式的id

val selection = MediaStore.Images.Media._ID + "=" + id

LogUtils.instance.getLogPrint("id=$id,selection=$selection")

imagePath = getImagePath(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, selection, context)

} else if ("com.android.providers.downloads.documents" == uri.authority) {

val contentUri = ContentUris.withAppendedId(Uri.parse("content://downloads/public_downloads"), java.lang.Long.valueOf(docId))

imagePath = getImagePath(contentUri, null, context)

}

} else if ("content".equals(uri!!.scheme, ignoreCase = true)) {

// 如果是content类型的Uri,则使用普通方式处理

imagePath = getImagePath(uri, null, context)

} else if ("file".equals(uri.scheme, ignoreCase = true)) {

// 如果是file类型的Uri,直接获取图片路径即可

imagePath = uri.path

}

return imagePath

}

/**

* 4.4版本以前,直接获取真实路径

* @param data

* @return

*/

fun handleImageBeforeKitKat(data: Intent, context: Context?): String? {

val uri = data.data

return getImagePath(uri, null, context)

}

/**

* 查询图库中是否存在有指定路径的图片

* @param uri:路径URI

* @param selection:筛选条件

* @param context

* @return

*/

private fun getImagePath(uri: Uri?, selection: String?, context: Context?): String? {

var path: String? = null

// 通过Uri和selection来获取真实的图片路径

val cursor: Cursor? = context?.contentResolver?.query(uri!!, null, selection, null, null)

if (cursor != null) {

LogUtils.instance.getLogPrint("cursor不为null $selection")

var i = 0

while (i < cursor.columnCount) {

var ss = cursor.getColumnName(i)

LogUtils.instance.getLogPrint("$i $ss")

i++

}

if (cursor.moveToFirst()) {

path = cursor.getString(cursor.getColumnIndex(MediaStore.Images.Media.DATA))

LogUtils.instance.getLogPrint("get path= $path")

}

cursor.close()

}

return path

}

最终通过cursor进行查询并获取到具体的图片文件地址。

4. 获取图片并处理

经过上步之后,我们可以获取到对应图片文件地址,可以通过过文件操作获取文件并添加到ImageView等操作,示例如下:

private fun displayImage(imgPath: String?) {

if (imgPath != null && FileUtils.instance.isFileExist(imgPath)) {

var bitmap = BitmapFactory.decodeFile(imgPath)

imgQRCode?.setImageBitmap(bitmap)

}

}

总结

获取图片的两种方式在实现上有相似的思路,都是经过如下几步:

申请权限

设置对应的intent Action,通过intent跳转到对应界面

在ActivityResults中处理返回的数据结果,获取到b图片对象。

需要主要的内容包括如下几点:

权限申请需要注意6.0以上的权限申请以及Android 10以上对于文件读写的控制。

打开图库选取照片要注意你当前从intent中获取的uri的格式,不仅仅需要考虑Android sdk版本的不同,同时对于不同的手机机型也有可能返回不同的uri路径,因此存在有单独适配的情况。

备注:

php拍照从手机相册中选择,Android获取图片:拍照和从相册中选择相关推荐

  1. android 图片拍照,Android获取图片拍照时间

    为什么写这篇文章是因为今早有个需求需要获取图片拍照时的时间进行一些处理,有些方法参数名忘记了,所以谷歌百度了一下,Android 图片 时间,Android 图片 拍照 时间,这几个关键字居然无法搜索 ...

  2. android 6.0获取手机imei,android获取手机信息大全,android获取大全,IMEI号,IESI号,...

    android获取手机信息大全,android获取大全,IMEI号,IESI号, IMEI号,IESI号,手机型号: [java] view plaincopyprint?private void g ...

  3. android自定义相册图片和视频教程,android把图片 视频 保存到相册

    //android把图片文件添加到相册 ContentResolver localContentResolver = getContentResolver(); ContentValues local ...

  4. android 获取图片上某一个文字位置_android 获取手机中的所有图片或某一目录下的图片方法...

    获取手机中的所有图片,并过滤获取某一目录下的图片.(注释掉的代码可以按照目录分组) private void getAllPhotoInfo() { new Thread(new Runnable() ...

  5. android通过访问相册获取图片并展示在ImageView中

    第一步:添加相应的权限以及属性: ①在manifest中设置权限 <uses-feature android:name="android.hardware.camera" / ...

  6. android访问图库,android通过访问相册获取图片并展示在ImageView中

    第一步:添加相应的权限以及属性: ①在manifest中设置权限 ②在中设置相应属性,这一步很关键,解决了我在这一方面最后的一个有关deny的权限问题 android:requestLegacyExt ...

  7. android相册功能 实现,Android开发实现的保存图片到相册功能示例

    本文实例讲述了Android开发实现的保存图片到相册功能.分享给大家供大家参考,具体如下: 废话不多说,先上效果: 点击图片 调用savephoto的SaveBitmapFromView(View v ...

  8. android 获取相机拍照保存到sqlite_OPPO助力谷歌CameraX计划,造福第三方相机应用用户...

    于本月10日,谷歌开发者大会GDD正式开办,如往年一样带来android相关的新鲜技术,而略有不同的是此次在会中谷歌方面就此前I/O 2019中提出的CameraX宣布合作名单,名单中包括有OPPO. ...

  9. android 擦除图片_在“提示”框中:停止自动运行,Android的电源板和安全DVD擦除...

    android 擦除图片 This week we're kicking off a new series here at How-To Geek focused on awesome reader ...

最新文章

  1. OpenCASCADE绘制测试线束:检查器命令之Inspector
  2. Jasmine里的describe,it和expect函数
  3. [蓝桥杯][2019年第十届真题c/c++B组]完全二叉树的权值
  4. centos7 split 切割文件_CentOS 大文件夹按固定块大小分割打包实验
  5. [2018.07.14 T1] B君的第四题
  6. 不用u盘安装linux真机,无需u盘和光盘安装linux
  7. office 2016 word文档另存为pdf之后文本内容显示不全
  8. 学习python量化分析
  9. 第一学:pytorch入门60min
  10. Windows10优化系统,优化达到30多项,速度大幅提升,
  11. 武汉云控系统,马云,王健林都惊艳了
  12. 中国最美丽地方排行榜及游览最佳时间
  13. WEB前端网页设计-Bootstrap4 信息提示框
  14. readline函数 读取一行数据
  15. 书读百遍,其意自现 --- 意境与语境的融合
  16. 计算机论文 内容要点 或提纲,论文提纲格式及写法要点 论文提纲格式
  17. html 修改下拉框样式,select下拉框option的样式修改
  18. windows 安装 企业QQ后,个人qq无法登录
  19. 产品经理的职业生涯规划是怎样的
  20. android aapt插件化,Android APK文件(三、AAPT2工具使用)

热门文章

  1. TypeScript基础入门 - 泛型 - 泛型类型
  2. 记一次支付系统的设计体验
  3. 动态调用WebService方法
  4. ScrollView中的LinearLayout不能使用android:layout_heig...
  5. Android 亲测源码分享
  6. SharePoint 2007 Features
  7. QLibrary 动态加载外部库文件
  8. shell脚本判断输入参数个数
  9. vue——组件之elementTable组件再封装
  10. POJ1149 PIGS