在需要跳转另一个界面后返回,当另一个界面进行销毁之后,希望获得界面的一些值,此时使用的方法是 startActivityForResult,但是如下所示,显示该方法已经过期了,因此下面使用推荐的registerForActivityResult
使用registerForActivityResult来解决过期问题。一定要注意参数声明的位置是在Activity类内,否则就会报错。
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)
}
}
<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>
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
}
}
<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>
在res目录下新建一个文件夹为xml,然后在xml文件夹下新建名为file_path的xml文件,下面选择paths,
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<external-path
name="my_images"
path="/"/>
paths>
使用多个回调函数和多个launcher处理结果即可
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
}
}