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

相关文章

mac安装nvm(node.js)多版本管理实践步骤

《mac安装nvm(node.js)多版本管理实践步骤》:本文主要介绍mac安装nvm(node.js)多版本管理的相关资料,NVM是一个用于管理多个Node.js版本的命令行工具,它允许开发者在... 目录NVM功能简介MAC安装实践一、下载nvm二、安装nvm三、安装node.js总结NVM功能简介N

Java中将异步调用转为同步的五种实现方法

《Java中将异步调用转为同步的五种实现方法》本文介绍了将异步调用转为同步阻塞模式的五种方法:wait/notify、ReentrantLock+Condition、Future、CountDownL... 目录异步与同步的核心区别方法一:使用wait/notify + synchronized代码示例关键

Python调用Orator ORM进行数据库操作

《Python调用OratorORM进行数据库操作》OratorORM是一个功能丰富且灵活的PythonORM库,旨在简化数据库操作,它支持多种数据库并提供了简洁且直观的API,下面我们就... 目录Orator ORM 主要特点安装使用示例总结Orator ORM 是一个功能丰富且灵活的 python O

Java调用DeepSeek API的最佳实践及详细代码示例

《Java调用DeepSeekAPI的最佳实践及详细代码示例》:本文主要介绍如何使用Java调用DeepSeekAPI,包括获取API密钥、添加HTTP客户端依赖、创建HTTP请求、处理响应、... 目录1. 获取API密钥2. 添加HTTP客户端依赖3. 创建HTTP请求4. 处理响应5. 错误处理6.

Deepseek R1模型本地化部署+API接口调用详细教程(释放AI生产力)

《DeepseekR1模型本地化部署+API接口调用详细教程(释放AI生产力)》本文介绍了本地部署DeepSeekR1模型和通过API调用将其集成到VSCode中的过程,作者详细步骤展示了如何下载和... 目录前言一、deepseek R1模型与chatGPT o1系列模型对比二、本地部署步骤1.安装oll

一分钟带你上手Python调用DeepSeek的API

《一分钟带你上手Python调用DeepSeek的API》最近DeepSeek非常火,作为一枚对前言技术非常关注的程序员来说,自然都想对接DeepSeek的API来体验一把,下面小编就来为大家介绍一下... 目录前言免费体验API-Key申请首次调用API基本概念最小单元推理模型智能体自定义界面总结前言最

JAVA调用Deepseek的api完成基本对话简单代码示例

《JAVA调用Deepseek的api完成基本对话简单代码示例》:本文主要介绍JAVA调用Deepseek的api完成基本对话的相关资料,文中详细讲解了如何获取DeepSeekAPI密钥、添加H... 获取API密钥首先,从DeepSeek平台获取API密钥,用于身份验证。添加HTTP客户端依赖使用Jav

java中不同版本JSONObject区别小结

《java中不同版本JSONObject区别小结》本文主要介绍了java中不同版本JSONObject区别小结,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们... 目录1. FastjsON2. Jackson3. Gson4. org.json6. 总结在Jav

redis防止短信恶意调用的实现

《redis防止短信恶意调用的实现》本文主要介绍了在场景登录或注册接口中使用短信验证码时遇到的恶意调用问题,并通过使用Redis分布式锁来解决,具有一定的参考价值,感兴趣的可以了解一下... 目录1.场景2.排查3.解决方案3.1 Redis锁实现3.2 方法调用1.场景登录或注册接口中,使用短信验证码场

使用C/C++调用libcurl调试消息的方式

《使用C/C++调用libcurl调试消息的方式》在使用C/C++调用libcurl进行HTTP请求时,有时我们需要查看请求的/应答消息的内容(包括请求头和请求体)以方便调试,libcurl提供了多种... 目录1. libcurl 调试工具简介2. 输出请求消息使用 CURLOPT_VERBOSE使用 C