1 Primero comprenda la solución a la expiración de startActivityForResult(intent, requestCode)
Regrese después de saltar a otra interfaz. Cuando se destruye la otra interfaz, desea obtener algunos valores de la interfaz. El método utilizado en este momento es startActivityForResult, pero como se muestra a continuación, muestra que el método ha expirado, así que use el recomendado a continuación registerForActivityResult
Use registerForActivityResult para resolver problemas de caducidad. Asegúrese de tener en cuenta que la posición de la declaración del parámetro se encuentra dentro de la clase Actividad; de lo contrario, se informará un error.
class CameraTest:AppCompatActivity() {
//实现回调函数,用于处理返回当前界面后的数据处理
val launcherCallback=ActivityResultCallback<ActivityResult>{
result ->
if(result.resultCode== Activity.RESULT_OK){
//在此处进行返回数据之后逻辑代码的处理
}
}
val intentLauncher=registerForActivityResult(ActivityResultContracts.StartActivityForResult(),launcherCallback)
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.camera_test)
//点击按钮之后进行界面的跳转
use_camera.setOnClickListener(){
val intent= Intent(this,Another::class.java)
intent.putExtra("key",value)
//startActivityForResult(intent,1)//这个方法过期了,,需要使用下面这个方法
intentLauncher.launch(intent)
}
}
2 Haga clic en el botón para llamar a la cámara y mostrar el resultado de tomar fotografías
1 Prepare el diseño xml para mostrar datos
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:id="@+id/use_camera"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="点击拍照"/>
<ImageView
android:id="@+id/show_image"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"/>
</LinearLayout>
2 Procesar la lógica de tomar fotografías y tomar fotografías
package com.njupt.kotlinlearn.notificationandmedia
import 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 android.os.Bundle
import android.provider.MediaStore
import android.util.Log
import androidx.activity.result.ActivityResult
import androidx.activity.result.ActivityResultCallback
import androidx.activity.result.contract.ActivityResultContracts
import androidx.appcompat.app.AppCompatActivity
import androidx.core.content.FileProvider
import com.njupt.kotlinlearn.R
import kotlinx.android.synthetic.main.camera_test.*
import java.io.File
class CameraTest:AppCompatActivity() {
lateinit var imageUri:Uri
lateinit var outPutImage:File
//实现回调函数,当相机界面被销毁之后,图片会缓存到指定的地点,然后到指定的路径中去获取图片和显示即可
val launcherCallback=ActivityResultCallback<ActivityResult>{
result ->
Log.d("result","${
result.data}")
if(result.resultCode== Activity.RESULT_OK){
val bitMap=BitmapFactory.decodeStream(contentResolver.openInputStream(imageUri))
show_image.setImageBitmap(rotateIfRequired(bitMap))
}
}
val intentLauncher=registerForActivityResult(ActivityResultContracts.StartActivityForResult(),launcherCallback)
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.camera_test)
use_camera.setOnClickListener(){
//创建一个file对象,指明照片的存储路径是缓存的目录和为拍下的照片取名为output_image.jpg
outPutImage=File(externalCacheDir,"output_image.jpg")
if(outPutImage.exists()){
outPutImage.delete()
}
outPutImage.createNewFile()
//如果版本低于7,就用uri将file对象转化成uri对象,否则就封装成uri对象
imageUri=if(Build.VERSION.SDK_INT>=Build.VERSION_CODES.N){
//FileProvider是一种特殊的ContentProvider
FileProvider.getUriForFile(this,"com.example.cameraalbumtest.fileprovider",outPutImage)
}else{
Uri.fromFile(outPutImage)
}
val intent= Intent("android.media.action.IMAGE_CAPTURE")
//调用指定了图片输出的地址,当相机被调用的时候,指定了拍照之后的存储地址
intent.putExtra(MediaStore.EXTRA_OUTPUT,imageUri)
//startActivityForResult(intent,1)//这个方法过期了,,需要使用下面这个方法
intentLauncher.launch(intent)
}
}
//处理照片拍照的旋转问题
private fun rotateIfRequired(bitmap:Bitmap):Bitmap{
val exif =ExifInterface(outPutImage.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()
return rotatedBitmap
}
}
3 Agregue el proveedor y la ruta de acceso a los datos requeridos por el programa en xml
<provider
android:authorities="com.example.cameraalbumtest.fileprovider"
android:name="androidx.core.content.FileProvider"
android:exported="false"
android:grantUriPermissions="true"
>
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/file_path"/>
</provider>
Cree una nueva carpeta llamada xml en el directorio res y luego cree un nuevo archivo xml llamado file_path en la carpeta xml, seleccione las rutas a continuación,
<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<external-path
name="my_images"
path="/"/>
</paths>
Haga clic en el botón para ejecutar y aparecerá el resultado de tomar fotografías
3 Resuelva el problema de utilizar el valor de retorno de resultado de registerForActivityResult cuando una interfaz accede a varias interfaces
Use múltiples funciones de devolución de llamada y múltiples lanzadores para procesar los resultados
class CameraTest:AppCompatActivity() {
lateinit var imageUri:Uri
lateinit var outPutImage:File
//实现回调函数,当相机界面被销毁之后,图片会缓存到指定的地点,然后到指定的路径中去获取图片和显示即可
val launcherCallback=ActivityResultCallback<ActivityResult>{
result ->
if(result.resultCode== Activity.RESULT_OK){
val bitMap=BitmapFactory.decodeStream(contentResolver.openInputStream(imageUri))
show_image.setImageBitmap(rotateIfRequired(bitMap))
}
}
//在写一个回调函数用来处理其他界面返回的请求
val launcherCallback2=ActivityResultCallback<ActivityResult>{
result ->
if(result.resultCode== Activity.RESULT_OK){
//要在这里面进行
result.data!!.data?.let{
uri->
//选择显示的图片
val bitmap=getBitMapFromUri(uri)
show_image.setImageBitmap(bitmap)
}
}
}
private fun getBitMapFromUri(uri: Uri)=contentResolver.openFileDescriptor(uri,"r")?.use {
BitmapFactory.decodeFileDescriptor(it.fileDescriptor) }
val intentLauncher=registerForActivityResult(ActivityResultContracts.StartActivityForResult(),launcherCallback)
val intentLauncher2=registerForActivityResult(ActivityResultContracts.StartActivityForResult(),launcherCallback2)
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.camera_test)
use_camera.setOnClickListener(){
//创建一个file对象,指明照片的存储路径是缓存的目录和为拍下的照片取名为output_image.jpg
outPutImage=File(externalCacheDir,"output_image.jpg")
if(outPutImage.exists()){
outPutImage.delete()
}
outPutImage.createNewFile()
//如果版本低于7,就用uri将file对象转化成uri对象,否则就封装成uri对象
imageUri=if(Build.VERSION.SDK_INT>=Build.VERSION_CODES.N){
//FileProvider是一种特殊的ContentProvider
FileProvider.getUriForFile(this,"com.example.cameraalbumtest.fileprovider",outPutImage)
}else{
Uri.fromFile(outPutImage)
}
val intent= Intent("android.media.action.IMAGE_CAPTURE")
//调用指定了图片输出的地址,当相机被调用的时候,指定了拍照之后的存储地址
intent.putExtra(MediaStore.EXTRA_OUTPUT,imageUri)
//startActivityForResult(intent,1)//这个方法过期了,,需要使用下面这个方法
intentLauncher.launch(intent)
}
select_photo_from_file.setOnClickListener(){
val intent=Intent(Intent.ACTION_OPEN_DOCUMENT)
intent.addCategory(Intent.CATEGORY_OPENABLE)
//显示image目录下的所有可以打开的文件
intent.type="image/*"
intentLauncher2.launch(intent)
}
}
private fun rotateIfRequired(bitmap:Bitmap):Bitmap{
val exif =ExifInterface(outPutImage.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()
return rotatedBitmap
}
}