我使用registerForActivityResult
就像:
package com.example.livedata
import android.Manifest
import android.app.Activity
import android.app.AlertDialog
import android.app.Dialog
import android.content.ActivityNotFoundException
import android.content.Intent
import android.graphics.Bitmap
import android.net.Uri
import android.os.Bundle
import android.provider.Settings
import android.view.View
import android.widget.Toast
import androidx.activity.result.contract.ActivityResultContracts
import androidx.appcompat.app.AppCompatActivity
import com.example.livedata.databinding.ActivityAddBinding
import com.example.livedata.databinding.DialogCustomImageSelectionBinding
class AddActivity : AppCompatActivity(), View.OnClickListener {
private lateinit var binding: ActivityAddBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityAddBinding.inflate(layoutInflater)
setContentView(binding.root)
setupActionBar()
binding.photoAdd.setOnClickListener(this)
}
private fun setupActionBar() {
setSupportActionBar(binding.toolbar)
supportActionBar?.setDisplayHomeAsUpEnabled(true)
binding.toolbar.setNavigationOnClickListener { onBackPressed() }
}
override fun onClick(v: View?) {
if (v != null) {
when (v.id) {
R.id.photo_add -> {
imageDialog()
return
}
}
}
}
private fun imageDialog() {
val dialog = Dialog(this)
val dialogBinding: DialogCustomImageSelectionBinding =
DialogCustomImageSelectionBinding.inflate(layoutInflater)
dialog.setContentView(dialogBinding.root)
dialog.show()
dialogBinding.impCamera.setOnClickListener {
registerForActivityResult(ActivityResultContracts.TakePicturePreview()) {
if (it != null) {
Toast.makeText(this@AddActivity, "TakePicturePreview", Toast.LENGTH_SHORT).show()
}
}.launch(null).apply { arrayOf(
Manifest.permission.READ_EXTERNAL_STORAGE,
Manifest.permission.WRITE_EXTERNAL_STORAGE,
Manifest.permission.CAMERA) }
dialog.dismiss()
}
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if (requestCode == 1 && resultCode == Activity.RESULT_OK) {
data?.let {
val bp = data.getParcelableExtra<Bitmap>("data")
binding.imageView.setImageBitmap(bp)
}
}
}
private fun showPermissions() {
AlertDialog.Builder(this).setMessage("Applay Permissions!")
.setPositiveButton("Go to Settings") { _, _ ->
try {
val intel = Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS)
val uri = Uri.fromParts("package", packageName, null)
intel.data = uri
startActivity(intel)
} catch (e: ActivityNotFoundException) {
e.printStackTrace()
}
}.setNegativeButton("Cancel") { dialog, _ ->
dialog.dismiss()
}.show()
}
}
但它不起作用,并在这里抛出了一个例外:
2021-07-16 15:38:50.472 29885-29885/com.example.livedata E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.livedata, PID: 29885
java.lang.IllegalStateException: LifecycleOwner com.example.livedata.AddActivity@9fc53b9 is attempting to register while current state is RESUMED. LifecycleOwners must call register before they are STARTED.
at androidx.activity.result.ActivityResultRegistry.register(ActivityResultRegistry.java:123)
at androidx.activity.ComponentActivity.registerForActivityResult(ComponentActivity.java:659)
at androidx.activity.ComponentActivity.registerForActivityResult(ComponentActivity.java:668)
at com.example.livedata.AddActivity.imageDialog$lambda-3(AddActivity.kt:68)
at com.example.livedata.AddActivity.lambda$N7K_EbTML-ycmUwpA7-i8b_L-Sw(Unknown Source:0)
at com.example.livedata.-$$Lambda$AddActivity$N7K_EbTML-ycmUwpA7-i8b_L-Sw.onClick(Unknown Source:4)
at android.view.View.performClick(View.java:7281)
at android.view.View.performClickInternal(View.java:7255)
at android.view.View.access$3600(View.java:828)
at android.view.View$PerformClick.run(View.java:27925)
at android.os.Handler.handleCallback(Handler.java:900)
at android.os.Handler.dispatchMessage(Handler.java:103)
at android.os.Looper.loop(Looper.java:219)
at android.app.ActivityThread.main(ActivityThread.java:8393)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:513)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1055)
2021-07-16 15:38:50.539 1689-2062/? E/InputDispatcher: channel 'ba7a009 com.example.livedata/com.example.livedata.AddActivity (server)' ~ Channel is unrecoverably broken and will be disposed!
如何使用registerForActivityResult而不是不推荐使用的方法来完成此任务?我们非常感谢所有的帮助。
您正试图在单击侦听器中调用registerForActivityResult
。这是行不通的,因为在交付结果之前,您的Activity
可能会被销毁并重新创建。重新创建的Activity
不会被注册以接收结果,因为它只在您单击按钮时注册,并且该按钮只在原始Activity
中单击。
要解决此问题,您需要无条件地调用registerForActivityResult
,并将结果存储在一个变量中:
class MyActivity : AppCompatActivity() {
private val activityLauncher = registerForActivityResult(...
这样,重新创建的Activity
将被注册以接收结果。然后使用activityLauncher
变量从按钮点击监听器启动它。
有关更多信息,请参阅官方指南。
Kotlin-在下面的代码中,这个方法给出结果并返回一个值,而不是startActivityForResult
弃用。
val resultLauncher = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result ->
when (result.resultCode) {
Activity.RESULT_OK -> {
// logic
}
else -> {
// logic
}
}
}
这是Java代码版本-使用ActivityResultLauncher
In Activity A : Launch Activity B, eg: if you using a Button View onSetClickListener
按钮btn
=findViewById(enter button view id name here
(
-
调用btn.setOnClickListener并将此代码放在按钮的onClick((方法中
mStartForResult.launch(new Intent(MainActivity.this, DestinationActivity.class));
-
调用ActivityResultLauncher API并使用Intent&ResultCode。
`
ActivityResultLauncher<Intent>mStartForResult = registerForActivityResult(new ActivityResultContracts.StartActivityForResult(),new ActivityResultCallback<ActivityResult>()
{
if(result.getResultCode()== Activity.RESULT_OK)
{
Intent intent = result.getData();
'enter your code here'
}
});
您可能希望使用共享首选项将数据从ActivityB保存和检索到
在活动B中:调用btn.setOnClickListener并将此代码放在按钮的onClick((-方法中:
`Intent intent = new Intent(DestinationActivity.this,MainActivity.class);` intent.putExtra(EXTRA, `enter your input(int or String) here`); setResult(RESULT_OK, intent); finish();