Android OnActivityResult方法已弃用,有什么替代方法?
我最近发现,Android OnActivityResult方法已弃用,有什么替代方法?,android,android-fragments,android-activity,onactivityresult,Android,Android Fragments,Android Activity,Onactivityresult,我最近发现,onActivityResult已被弃用。我们该怎么处理呢 有没有其他办法 在超类中,onActivityResult似乎不受欢迎,但在您的问题中,您没有提到超类名称和编译dkversion 在Java和Kotlin中,只要向每个类或方法添加@deprecated,每个类或方法都可以标记为deprecated,因此检查您的超类,您可能扩展了一个错误的类 当一个类被弃用时,它的所有方法也被弃用 要查看快速解决方案,请单击不推荐的方法,然后在Android studio中按Ctrl+Q,
onActivityResult
已被弃用。我们该怎么处理呢
有没有其他办法
在超类中,
onActivityResult
似乎不受欢迎,但在您的问题中,您没有提到超类名称和编译dkversion
在Java和Kotlin中,只要向每个类或方法添加@deprecated
,每个类或方法都可以标记为deprecated,因此检查您的超类,您可能扩展了一个错误的类
当一个类被弃用时,它的所有方法也被弃用
要查看快速解决方案,请单击不推荐的方法,然后在Android studio中按Ctrl+Q
,查看该方法的文档,应该有一个解决方案
在我使用
androidx
和API 29作为compileSdkVersion
的项目中,此方法在活动和片段onActivityResult
,startActivityForResult
,requestPermissions
中没有被弃用,和onRequestPermissionsResult
位于androidx.fragment
中的1.3.0-alpha04
,而不是android.app.Activity
相反,您可以与一起使用。在上提供基本培训
以下是如何将现有代码转换为新代码的示例:
老办法:
var resultLauncher = registerForActivityResult(StartActivityForResult()) { result ->
if (result.resultCode == Activity.RESULT_OK) {
// There are no request codes
val data: Intent? = result.data
doSomeOperations()
}
}
fun openSomeActivityForResult() {
val intent = Intent(this, SomeActivity::class.java)
resultLauncher.launch(intent)
}
var launchSomeActivity = registerForActivityResult(StartActivityForResult()) { result ->
if (result.resultCode == Activity.RESULT_OK) {
val data: Intent? = result.data
// your operation...
}
}
fun openYourActivity() {
val intent = Intent(this, SomeActivity::class.java)
launchSomeActivity.launch(intent)
}
// Create lanucher variable inside onAttach or onCreate or global
ActivityResultLauncher<Intent> launchSomeActivity = registerForActivityResult(
new ActivityResultContracts.StartActivityForResult(),
new ActivityResultCallback<ActivityResult>() {
@Override
public void onActivityResult(ActivityResult result) {
if (result.getResultCode() == Activity.RESULT_OK) {
Intent data = result.getData();
// your operation....
}
}
});
public void openYourActivity() {
Intent intent = new Intent(this, SomeActivity.class);
launchSomeActivity.launch(intent);
}
public void openSomeActivityForResult(){
意向意向=新意向(this,SomeActivity.class);
startActivityForResult(意图,123);
}
@凌驾
受保护的void onActivityResult(int请求代码、int结果代码、意图数据){
if(resultCode==Activity.RESULT_OK&&requestCode==123){
doSomeOperations();
}
}
新方式(Java):
var resultLauncher = registerForActivityResult(StartActivityForResult()) { result ->
if (result.resultCode == Activity.RESULT_OK) {
// There are no request codes
val data: Intent? = result.data
doSomeOperations()
}
}
fun openSomeActivityForResult() {
val intent = Intent(this, SomeActivity::class.java)
resultLauncher.launch(intent)
}
var launchSomeActivity = registerForActivityResult(StartActivityForResult()) { result ->
if (result.resultCode == Activity.RESULT_OK) {
val data: Intent? = result.data
// your operation...
}
}
fun openYourActivity() {
val intent = Intent(this, SomeActivity::class.java)
launchSomeActivity.launch(intent)
}
// Create lanucher variable inside onAttach or onCreate or global
ActivityResultLauncher<Intent> launchSomeActivity = registerForActivityResult(
new ActivityResultContracts.StartActivityForResult(),
new ActivityResultCallback<ActivityResult>() {
@Override
public void onActivityResult(ActivityResult result) {
if (result.getResultCode() == Activity.RESULT_OK) {
Intent data = result.getData();
// your operation....
}
}
});
public void openYourActivity() {
Intent intent = new Intent(this, SomeActivity.class);
launchSomeActivity.launch(intent);
}
//您可以在onAttach或onCreate内部执行分配,即在显示活动之前
ActivityResultLauncher someActivityResultLauncher=registerForActivityResult(
新ActivityResultContracts.StartActivityForResult(),
新ActivityResultCallback(){
@凌驾
ActivityResult上的公共无效(ActivityResult结果){
if(result.getResultCode()==Activity.result\u确定){
//没有请求代码
Intent data=result.getData();
doSomeOperations();
}
}
});
公开作废openSomeActivityForResult(){
意向意向=新意向(this,SomeActivity.class);
someActivityResultLauncher.launch(意图);
}
新方式(科特林):
var resultLauncher = registerForActivityResult(StartActivityForResult()) { result ->
if (result.resultCode == Activity.RESULT_OK) {
// There are no request codes
val data: Intent? = result.data
doSomeOperations()
}
}
fun openSomeActivityForResult() {
val intent = Intent(this, SomeActivity::class.java)
resultLauncher.launch(intent)
}
var launchSomeActivity = registerForActivityResult(StartActivityForResult()) { result ->
if (result.resultCode == Activity.RESULT_OK) {
val data: Intent? = result.data
// your operation...
}
}
fun openYourActivity() {
val intent = Intent(this, SomeActivity::class.java)
launchSomeActivity.launch(intent)
}
// Create lanucher variable inside onAttach or onCreate or global
ActivityResultLauncher<Intent> launchSomeActivity = registerForActivityResult(
new ActivityResultContracts.StartActivityForResult(),
new ActivityResultCallback<ActivityResult>() {
@Override
public void onActivityResult(ActivityResult result) {
if (result.getResultCode() == Activity.RESULT_OK) {
Intent data = result.getData();
// your operation....
}
}
});
public void openYourActivity() {
Intent intent = new Intent(this, SomeActivity.class);
launchSomeActivity.launch(intent);
}
编辑。更好的方法是使其更通用,以便我们可以重用它。下面的代码片段用于我的一个项目中,但请注意,它没有经过良好测试,可能无法涵盖所有情况
BetterActivityResult.java
导入android.content.Intent;
导入androidx.activity.result.ActivityResult;
导入androidx.activity.result.ActivityResultCaller;
导入androidx.activity.result.ActivityResultLauncher;
导入androidx.activity.result.contract.ActivityResultContract;
导入androidx.activity.result.contract.ActivityResultContracts;
导入androidx.annotation.NonNull;
导入androidx.annotation.Nullable;
公共类BetterActivityResult{
/**
*使用{@link ActivityResultContract}和类似的就地活动结果回调来注册活动结果
*默认方法。您仍然可以使用{@link#launch(Object,OnActivityResult)}自定义回调。
*/
@非空
公共静态BetterActivityResult注册表用于ActivityResult(
@非Null ActivityResultCaller调用方,
@非空ActivityResultContract合同,
@可为空的OnActivityResult OnActivityResult){
返回新的BetterActivityResult(调用方、合同、onActivityResult);
}
/**
*与{@link#registerForActivityResult(ActivityResultCaller、ActivityResultContract、OnActivityResult)相同,除了
*最后一个参数设置为{@code null}。
*/
@非空
公共静态BetterActivityResult注册表用于ActivityResult(
@非Null ActivityResultCaller调用方,
@非空ActivityResultContract(合同){
返回registerForActivityResult(调用者,契约,null);
}
/**
*开展新活动的专门方法。
*/
@非空
公共静态BetterActivityResult注册表ActivityForResult(
@非Null ActivityResultCaller(调用方){
返回registerForActivityResult(调用者,新ActivityResultContracts.StartActivityForResult());
}
/**
*回调接口
*/
ActivityResult上的公共接口{
/**
*从目标活动接收结果后调用
*/
无效的活动结果(O结果);
}
私人最终活动ResultLauncher launcher;
@可空
私有OnActivityResult OnActivityResult;
private BetterActivityResult(@NonNull ActivityResultCaller调用方,
@非空ActivityResultContract合同,
@可为空的OnActivityResult OnActivityResult){
this.onActivityResult=onActivityResult;
this.launcher=caller.registerForActivityResult(契约,this::callOnActivityResult);
}
public void setOnActivityResult(@Nullable-OnActivityResult-OnActivityResult){
this.onActivityResult=onActivityResult;
}
/**
*启动活动,与{@link ActivityResultLauncher#Launch(Object)}相同,只是它允许回调
*从目标活动接收结果后执行。
*/
公共无效启动(输入,@Nullable-OnActivityResult-OnActivityResult){
如果(onActivityResult!=null){
class MyFragment : Fragment(), OnActivityResultListener {
...
override fun onActivityResultFromLauncher(requestCode: Int, resultCode: Int, data: Intent?) {/*do somthing*/}
...
}
public class MyFragment extends Fragment implements OnActivityResultListener {
...
@Inject
ActivityResultLauncherWrapper activityResultLauncher;
//ActivityResultLauncherWrapper activityResultLauncher = new ActivityResultLauncherWrapper()
...
public void launnchActivity(@NotNull Intent intent) {
activityResultLauncher.launchIntentForResult(requireActivity(), intent, REQUEST_CODE_CONSTANT, this);
}
...
@Override
public void onActivityResultFromLauncher(int requestCode, int resultCode, Intent data) {/*do somthing*/}
...
}
ActivityResultLauncher<Intent> startActivityForResult = registerForActivityResult(
new ActivityResultContracts.StartActivityForResult(),
result -> {
if (result.getResultCode() == AppCompatActivity.RESULT_OK) {
Intent data = result.getData();
// ...
}
}
);
Intent intent = new Intent( ... );
startActivityForResult.launch(intent);
abstract class BaseActivity : AppCompatActivity()
{
private var requestCode: Int = -1
private var resultHandler: ActivityResultLauncher<Intent>? = null
override fun onCreate(savedInstanceState: Bundle?)
{
super.onCreate(savedInstanceState)
registerForActivityResult()
}
private fun registerForActivityResult()
{
if (shouldRegisterForActivityResult())
{
resultHandler = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result ->
onActivityResult(result.data, requestCode, result.resultCode)
this.requestCode = -1
}
}
}
fun startActivityForResult(requestCode: Int, intent: Intent)
{
this.requestCode = requestCode
resultHandler?.launch(intent)
}
protected open fun onActivityResult(data: Intent?, requestCode: Int, resultCode: Int)
{
// For sub activities
}
protected open fun shouldRegisterForActivityResult(): Boolean
{
// Sub activities that need the onActivityResult "mechanism", should override this and return true
return false
}
}
class SubActivity : BaseActivity()
{
companion object
{
private const val SOME_REQUEST_CODE = 300
}
private fun testActivityResult()
{
val intent = Intent(this, OtherActivity::class.java)
startActivityForResult(SOME_REQUEST_CODE, intent)
}
override fun shouldRegisterForActivityResult(): Boolean
{
return true
}
override fun onActivityResult(data: Intent?, requestCode: Int, resultCode: Int)
{
if (requestCode == SOME_REQUEST_CODE)
{
// Yes!
}
}
}
var launchSomeActivity = registerForActivityResult(StartActivityForResult()) { result ->
if (result.resultCode == Activity.RESULT_OK) {
val data: Intent? = result.data
// your operation...
}
}
fun openYourActivity() {
val intent = Intent(this, SomeActivity::class.java)
launchSomeActivity.launch(intent)
}
// Create lanucher variable inside onAttach or onCreate or global
ActivityResultLauncher<Intent> launchSomeActivity = registerForActivityResult(
new ActivityResultContracts.StartActivityForResult(),
new ActivityResultCallback<ActivityResult>() {
@Override
public void onActivityResult(ActivityResult result) {
if (result.getResultCode() == Activity.RESULT_OK) {
Intent data = result.getData();
// your operation....
}
}
});
public void openYourActivity() {
Intent intent = new Intent(this, SomeActivity.class);
launchSomeActivity.launch(intent);
}
class BetterActivityResult<Input, Result> private constructor(
caller : ActivityResultCaller,
contract : ActivityResultContract<Input, Result>,
var onActivityResult : ((Result) -> Unit)?,
) {
private val launcher : ActivityResultLauncher<Input> =
caller.registerForActivityResult(contract) { onActivityResult?.invoke(it) }
/**
* Launch activity, same as [ActivityResultLauncher.launch] except that it
* allows a callback
* executed after receiving a result from the target activity.
*/
/**
* Same as [.launch] with last parameter set to `null`.
*/
@JvmOverloads
fun launch(
input : Input,
onActivityResult : ((Result) -> Unit)? = this.onActivityResult,
) {
this.onActivityResult = onActivityResult
launcher.launch(input)
}
companion object {
/**
* Register activity result using a [ActivityResultContract] and an in-place
* activity result callback like
* the default approach. You can still customise callback using [.launch].
*/
fun <Input, Result> registerForActivityResult(
caller : ActivityResultCaller,
contract : ActivityResultContract<Input, Result>,
onActivityResult : ((Result) -> Unit)?,
) : BetterActivityResult<Input, Result> {
return BetterActivityResult(caller, contract, onActivityResult)
}
/**
* Same as [.registerForActivityResult] except
* the last argument is set to `null`.
*/
fun <Input, Result> registerForActivityResult(
caller : ActivityResultCaller,
contract : ActivityResultContract<Input, Result>,
) : BetterActivityResult<Input, Result> {
return registerForActivityResult(caller, contract, null)
}
/**
* Specialised method for launching new activities.
*/
fun registerActivityForResult(
caller : ActivityResultCaller,
) : BetterActivityResult<Intent, ActivityResult> {
return registerForActivityResult(caller, StartActivityForResult())
}
}
}
resultContract =
registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result ->
if (result.resultCode == Activity.RESULT_OK) {
// There are no request codes
val country = result.data?.getParcelableExtra<Country>("Country")
showLiveDemoDialogue(country)
}
}
val intent = Intent(this, CountriesListActivity::class.java)
resultContract.launch(intent)
attempting to register while current state is RESUMED. LifecycleOwners must call register before they are STARTED.
//random utils file
fun Fragment.buildGetContentRequest(function: (Uri) -> Unit): ActivityResultLauncher<String> {
return this.registerForActivityResult(ActivityResultContracts.GetContent()) {
function(it)
}
}
fun Fragment.buildTakePhotoRequest(function: (Boolean) -> Unit): ActivityResultLauncher<Uri> {
return this.registerForActivityResult(ActivityResultContracts.TakePicture()) {
function(it)
}
}
fun Fragment.buildSelectMultipleContentRequest(function: (MutableList<Uri>?) -> Unit): ActivityResultLauncher<String> {
return this.registerForActivityResult(ActivityResultContracts.GetMultipleContents()) {
function(it)
}
}
//your actual fragment logic
class YourFragment : Fragment() {
//we can assign our request in init process
private val mRequestSelectFiles = buildSelectMultipleContentRequest {
onFilesSelected(it)
}
fun onSelectFiles() {
val mime = "*/*"
mRequestSelectFiles.launch(mime)
}
fun onFilesSelected(list: MutableList<Uri>?) {
//your logic
}
}
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/*")
}
}
ActivityResultLauncher<Intent> someActivityResultLauncher = registerForActivityResult(
new ActivityResultContracts.StartActivityForResult(),
new ActivityResultCallback<ActivityResult>() {
@Override
public void onActivityResult(ActivityResult result) {
if (result.getResultCode() == Activity.RESULT_OK) {
}
}
});
resultLauncher=registerForActivityResult(ActivityResultContracts.StartActivityForResult()){result ->
// copy paste the code from the onActivityResult replacing resultcode to result.resultCode
if(result.resultcode==Activity.Result_OK){
val data=result.data // this data variable is of type intent and you can use it
}else{
//code if you do not get the data
}
}