我最近发现onActivityResult已弃用。我们该怎么处理呢?
有什么替代方案吗?
我最近发现onActivityResult已弃用。我们该怎么处理呢?
有什么替代方案吗?
当前回答
添加到muntashir akon和abhijeet的答案,你可以通过在意图中传递值来修改新格式,使其像旧格式一样工作,例如:
// calling class
....
val i = Intent(this@GEBShopActivity, BarcodeScannerActivity::class.java)
when(loadedFragment){
is ShopHomeFragment -> { i.putExtra("myapp.result.code", CODE_ACTIVITY_SCAN_LIST_MAINT) }
is ShopListFragment -> { i.putExtra("myapp.result.code", CODE_ACTIVITY_SCAN_LIST_MAINT) }
is ShopItemMaintFragment -> { i.putExtra("myapp.result.code", CODE_ACTIVITY_SCAN_ITEM_MAINT) }
is ShopPriceFragment -> { i.putExtra("myapp.result.code", CODE_ACTIVITY_PRICE_CAPTURE) }
is ShopCompareFragment -> { i.putExtra("myapp.result.code", CODE_ACTIVITY_PRICE_CAPTURE) }
}
shopFragmentLauncher.launch(i)
....
// called class
....
val resultIntent = Intent()
val bundle = Bundle()
bundle.putStringArrayList("scanned_barcodes", scanned_barcodes)
bundle.putInt("scan_count", scan_count)
resultIntent.putExtras(bundle)
resultIntent.putExtra("myapp.result.code", intent.getIntExtra("myapp.result.code", 0))
setResult(Activity.RESULT_OK, resultIntent)
....
这将允许您保持类的调用相同,只需要额外的一行来添加原始调用的结果代码。还允许您创建一个可重用的启动程序实例。
其他回答
似乎onActivityResult在超类中已弃用,但你在你的问题中没有提到超类名称和compileSdkVersion。
在Java和Kotlin中,只要添加@Deprecated,每个类或方法都可以标记为deprecated,所以检查你的超类,你可能扩展了一个错误的类。
当一个类被弃用时,它的所有方法也被弃用。
要看到一个快速的解决方案,点击弃用的方法,并按Ctrl+Q在Android工作室查看方法的文档,应该有一个解决方案。
在我使用androidx和API 29作为compileSdkVersion的项目中,此方法在活动和片段中不弃用
我想出了如何从Kotlin的片段中正确地做到这一点,以捕获图像并处理返回的位图。在其他情况下也是一样的。
首先,您必须注册片段以侦听活动结果。这必须在初始化片段之前完成,这意味着创建一个成员变量,而不是在onCreate函数中初始化。
class DummyFragment : Fragment() {
//registering fragment for camera listener
private val takePhoto = registerForActivityResult(
ActivityResultContracts.StartActivityForResult()
) {
if (it.resultCode == Activity.RESULT_OK) {
val imageBitmap = it.data?.extras?.get("data") as Bitmap
// do your thing with the obtained bitmap
}
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
}
}
然后,像你通常做的那样调用摄像机意图。并使用上面创建的变量来启动意图。
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
someRandomButton.setOnClickListener {
val takePictureIntent = Intent(MediaStore.ACTION_IMAGE_CAPTURE)
takePhoto.launch(takePictureIntent)
}
}
参考:Kotlin -从图库中选择图像
迄今为止我发现的最简单的Alernative
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.id.activity_main)
var ivPhoto = findViewById<ImageView>(R.id.ivPhoto)
var btnChoosePhoto = findViewById<Button>(R.id.btnChoosePhoto)
val getContent = registerForActivityResult(ActivityResultContracts.GetContent()) { uri: Uri? ->
ivPhoto.setImageURI(uri) // Handle the returned Uri
}
btnChoose.setOnClickListener {
getContent.launch("image/*")
}
}
下面我来解释一下这种新方法
private val scan =
registerForActivityResult(ActivityResultContracts.StartActivityForResult())
{ result: ActivityResult ->
if (result.resultCode == AppCompatActivity.RESULT_OK && result.data != null) {
var selected_hub = result!!.data!!.getParcelableExtra<ExtendedBluetoothDevice>(Utils.EXTRA_DEVICE)
Log.d(TAG,"RECONNECT PROCESS "+selected_hub!!.name)
reconnect(selected_hub!!)
}
}
从活动或片段调用此方法
private fun callScan() {
val intent = Intent(requireActivity(), ScanningMeshDevices::class.java)
scan.launch(intent)
}
在替换已弃用的方法startActivityForResult(…)时,需要遵循4个简单的步骤。
In place of overridden method onActivityResult(..) - ActivityResultLauncher<Intent> activityResultLaunch = registerForActivityResult( new ActivityResultContracts.StartActivityForResult(), new ActivityResultCallback<ActivityResult>() { @Override public void onActivityResult(ActivityResult result) { if (result.getResultCode() == 123) { // ToDo : Do your stuff... } else if(result.getResultCode() == 321) { // ToDo : Do your stuff... } } });
对于多个自定义请求,将条件附加为
if (result.getResultCode() == 123) {
..
} else if(result.getResultCode() == 131){
..
} // so on..
Imports : import androidx.activity.result.ActivityResult; import androidx.activity.result.ActivityResultCallback; import androidx.activity.result.ActivityResultLauncher; import androidx.activity.result.contract.ActivityResultContracts; In place of startActivityForResult(intent, 123), use Intent intent = new Intent(this, SampleActivity.class); activityResultLaunch.launch(intent); In SampleActivity.java class, while returning back to source activity, code will remain the same like - Intent intent = new Intent(); setResult(123, intent); finish();
编码快乐!:)