Android: Kotlin se da cuenta de llamar a los recursos de la cámara para tomar fotos y mostrarlas

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
inserte la descripción de la imagen aquí
inserte la descripción de la imagen aquí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
inserte la descripción de la imagen aquí

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
    }
}

Supongo que te gusta

Origin blog.csdn.net/m0_56184347/article/details/129628216
Recomendado
Clasificación