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