Android10以上版本调用相机拍照

2024-04-06 18:20

本文主要是介绍Android10以上版本调用相机拍照,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

1、拍照功能

界面

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:orientation="vertical"android:layout_width="match_parent"android:layout_height="match_parent" ><Buttonandroid:id="@+id/takePhotoBtn"android:layout_width="match_parent"android:layout_height="wrap_content"android:text="Take Photo" /><ImageViewandroid:id="@+id/imageView"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_gravity="center_horizontal"android:contentDescription="图片" />
</LinearLayout>

逻辑处理

package com.jpc.cameraalbumtestimport android.app.Activity
import android.content.Intent
import android.graphics.Bitmap
import android.graphics.BitmapFactory
import android.graphics.Matrix
import android.media.ExifInterface
import android.net.Uri
import android.os.Build
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.provider.MediaStore
import android.widget.Button
import android.widget.ImageView
import androidx.core.content.FileProvider
import java.io.File/*** 首先这里创建了一个File对象,用于存放摄像头拍下的图片,这里我们把图片命名为* output_image.jpg,并存放在手机SD卡的应用关联缓存目录下。什么叫作应用关联缓存目录* 呢?就是指SD卡中专门用于存放当前应用缓存数据的位置,调用getExternalCacheDir()* 方法可以得到这个目录,具体的路径是/sdcard/Android/data/<package name>/cache。* 那么为什么要使用应用关联缓存目录来存放图片呢?因为从Android 6.0系统开始,读写SD卡* 被列为了危险权限,如果将图片存放在SD卡的任何其他目录,都要进行运行时权限处理才行,* 而使用应用关联目录则可以跳过这一步。另外,从Android 10.0系统开始,公有的SD卡目录已* 经不再允许被应用程序直接访问了,而是要使用作用域存储才行*/
class MainActivity : AppCompatActivity() {private val takePhoto = 1private lateinit var imageUri: Uri//private lateinit var outputImage: File// 为了解决outputImage为空的问题,这里将outputImage声明为可空类型private var outputImage: File ?= nullprivate lateinit var imageView: ImageViewoverride fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)setContentView(R.layout.activity_main)val btnTakePhoto = findViewById<Button>(R.id.takePhotoBtn)imageView = findViewById(R.id.imageView)btnTakePhoto.setOnClickListener{// 创建File对象,用于存储拍照后的图片val outputImage = File(externalCacheDir, "output_image.jpg")if(outputImage.exists()){outputImage.delete()}outputImage.createNewFile()// 一般要检查一下版本imageUri = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {FileProvider.getUriForFile(this, "com.jpc.cameraalbumtest.fileprovider", outputImage)}else{Uri.fromFile(outputImage)}// 启动相机程序val intent = Intent("android.media.action.IMAGE_CAPTURE")intent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri)startActivityForResult(intent, takePhoto)}}override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {super.onActivityResult(requestCode, resultCode, data)when(requestCode) {takePhoto -> {if(resultCode == Activity.RESULT_OK){// 将拍摄的照片显示出来val bitmap =BitmapFactory.decodeStream(contentResolver.openInputStream(imageUri))imageView.setImageBitmap(rotateIfRequired(bitmap))}}}}/*** 调用照相机程序去拍照有可能会在一些手机上发生照片旋转的情况。这是因为* 这些手机认为打开摄像头进行拍摄时手机就应该是横屏的,因此回到竖屏的情况下就会发生90* 度的旋转。为此,这里我们又加上了判断图片方向的代码,如果发现图片需要进行旋转,那么* 就先将图片旋转相应的角度,然后再显示到界面上*/private fun rotateIfRequired(bitmap: Bitmap): Bitmap {// 这里使用let函数,如果outputImage不为空,就执行let函数中的代码val exif = outputImage?.let { ExifInterface(it.path) }val orientation = exif?.getAttributeInt(ExifInterface.TAG_ORIENTATION,ExifInterface.ORIENTATION_NORMAL)return when (orientation) {ExifInterface.ORIENTATION_ROTATE_90 -> rotateBitmap(bitmap, 90)ExifInterface.ORIENTATION_ROTATE_180 -> rotateBitmap(bitmap, 180)ExifInterface.ORIENTATION_ROTATE_270 -> rotateBitmap(bitmap, 270)else -> bitmap}}private fun rotateBitmap(bitmap: Bitmap, degree: Int): Bitmap {val matrix = Matrix()matrix.postRotate(degree.toFloat())val rotatedBitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.width, bitmap.height,matrix, true)bitmap.recycle() // 将不再需要的Bitmap对象回收return rotatedBitmap}
}
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools"><!-- 声明权限--><uses-featureandroid:name="android.hardware.camera"android:required="false" /><uses-permission android:name="android.permission.CAMERA" /><applicationandroid:allowBackup="true"android:dataExtractionRules="@xml/data_extraction_rules"android:fullBackupContent="@xml/backup_rules"android:icon="@mipmap/ic_launcher"android:label="@string/app_name"android:roundIcon="@mipmap/ic_launcher_round"android:supportsRtl="true"android:theme="@style/Theme.CameraAlbumTest"tools:targetApi="31"><activityandroid:name=".MainActivity"android:exported="true"><intent-filter><action android:name="android.intent.action.MAIN" /><category android:name="android.intent.category.LAUNCHER" /></intent-filter></activity><providerandroid:name="androidx.core.content.FileProvider"android:authorities="com.jpc.cameraalbumtest.fileprovider"android:exported="false"android:grantUriPermissions="true"><meta-dataandroid:name="android.support.FILE_PROVIDER_PATHS"android:resource="@xml/file_paths" /></provider></application></manifest>

存放路径

<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android"><external-path name="my_images" path="/" />
</paths>
2、从相册中选择图片的功能

在上面基本代码的基础之上添加

val fromAlbumBtn = findViewById<Button>(R.id.fromAlbumBtn)fromAlbumBtn.setOnClickListener{// 打开文件选择器val intent = Intent(Intent.ACTION_OPEN_DOCUMENT)intent.addCategory(Intent.CATEGORY_OPENABLE)// 指定只显示图片intent.type = "image/*"startActivityForResult(intent, fromAlbum)}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {super.onActivityResult(requestCode, resultCode, data)when(requestCode) {takePhoto -> {if(resultCode == Activity.RESULT_OK){// 将拍摄的照片显示出来val bitmap =BitmapFactory.decodeStream(contentResolver.openInputStream(imageUri))imageView.setImageBitmap(rotateIfRequired(bitmap))}}fromAlbum -> {if(resultCode == Activity.RESULT_OK && data != null){data.data?.let { uri ->// 将选择的图片显示val bitmap = getBitmapFromUri(uri)imageView.setImageBitmap(bitmap)}}}}}

这篇关于Android10以上版本调用相机拍照的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/880515

相关文章

Linux卸载自带jdk并安装新jdk版本的图文教程

《Linux卸载自带jdk并安装新jdk版本的图文教程》在Linux系统中,有时需要卸载预装的OpenJDK并安装特定版本的JDK,例如JDK1.8,所以本文给大家详细介绍了Linux卸载自带jdk并... 目录Ⅰ、卸载自带jdkⅡ、安装新版jdkⅠ、卸载自带jdk1、输入命令查看旧jdkrpm -qa

Tomcat版本与Java版本的关系及说明

《Tomcat版本与Java版本的关系及说明》:本文主要介绍Tomcat版本与Java版本的关系及说明,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录Tomcat版本与Java版本的关系Tomcat历史版本对应的Java版本Tomcat支持哪些版本的pythonJ

在C#中调用Python代码的两种实现方式

《在C#中调用Python代码的两种实现方式》:本文主要介绍在C#中调用Python代码的两种实现方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录C#调用python代码的方式1. 使用 Python.NET2. 使用外部进程调用 Python 脚本总结C#调

IDEA中Git版本回退的两种实现方案

《IDEA中Git版本回退的两种实现方案》作为开发者,代码版本回退是日常高频操作,IntelliJIDEA集成了强大的Git工具链,但面对reset和revert两种核心回退方案,许多开发者仍存在选择... 目录一、版本回退前置知识二、Reset方案:整体改写历史1、IDEA图形化操作(推荐)1.1、查看提

SpringCloud之LoadBalancer负载均衡服务调用过程

《SpringCloud之LoadBalancer负载均衡服务调用过程》:本文主要介绍SpringCloud之LoadBalancer负载均衡服务调用过程,具有很好的参考价值,希望对大家有所帮助,... 目录前言一、LoadBalancer是什么?二、使用步骤1、启动consul2、客户端加入依赖3、以服务

JDK多版本共存并自由切换的操作指南(本文为JDK8和JDK17)

《JDK多版本共存并自由切换的操作指南(本文为JDK8和JDK17)》本文介绍了如何在Windows系统上配置多版本JDK(以JDK8和JDK17为例),并通过图文结合的方式给大家讲解了详细步骤,具有... 目录第一步 下载安装JDK第二步 配置环境变量第三步 切换JDK版本并验证可能遇到的问题前提:公司常

nvm如何切换与管理node版本

《nvm如何切换与管理node版本》:本文主要介绍nvm如何切换与管理node版本问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录nvm切换与管理node版本nvm安装nvm常用命令总结nvm切换与管理node版本nvm适用于多项目同时开发,然后项目适配no

Vue 调用摄像头扫描条码功能实现代码

《Vue调用摄像头扫描条码功能实现代码》本文介绍了如何使用Vue.js和jsQR库来实现调用摄像头并扫描条码的功能,通过安装依赖、获取摄像头视频流、解析条码等步骤,实现了从开始扫描到停止扫描的完整流... 目录实现步骤:代码实现1. 安装依赖2. vue 页面代码功能说明注意事项以下是一个基于 Vue.js

Mybatis从3.4.0版本到3.5.7版本的迭代方法实现

《Mybatis从3.4.0版本到3.5.7版本的迭代方法实现》本文主要介绍了Mybatis从3.4.0版本到3.5.7版本的迭代方法实现,包括主要的功能增强、不兼容的更改和修复的错误,具有一定的参考... 目录一、3.4.01、主要的功能增强2、selectCursor example3、不兼容的更改二、

pytorch+torchvision+python版本对应及环境安装

《pytorch+torchvision+python版本对应及环境安装》本文主要介绍了pytorch+torchvision+python版本对应及环境安装,安装过程中需要注意Numpy版本的降级,... 目录一、版本对应二、安装命令(pip)1. 版本2. 安装全过程3. 命令相关解释参考文章一、版本对