我最近发现onActivityResult已弃用。我们该怎么处理呢?

有什么替代方案吗?


当前回答

从现在开始,startActivityForResult()已经被弃用,所以使用new方法代替。

芬兰湾的科特林的例子

    fun openActivityForResult() {
        startForResult.launch(Intent(this, AnotherActivity::class.java))
    }


    val startForResult = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { 
    result: ActivityResult ->
        if (result.resultCode == Activity.RESULT_OK) {
            val intent = result.data
            // Handle the Intent
            //do stuff here
        }
    }

其他回答

这就是我如何替换多个requestCodes(把这段代码放在你的活动中):

    ActivityResultLauncher<Intent> launchCameraActivity = registerForActivityResult(
        new ActivityResultContracts.StartActivityForResult(),
        new ActivityResultCallback<ActivityResult>() {
            @Override
            public void onActivityResult(ActivityResult result) {
                if (result.getResultCode() == Activity.RESULT_OK) {
                    Intent data = result.getData();
                    Bitmap photoBitmap;
                    if(data != null && data.getExtras() != null){
                        photoBitmap = (Bitmap) data.getExtras().get("data");
                        if (photoBitmap != null) {
                            dataModel.setPhoto(ImageUtil.convert(photoBitmap));
                            imageTaken.setVisibility(View.VISIBLE);
                            imageTaken.setImageBitmap(photoBitmap);
                        }

                    }
                }
            }
        });

ActivityResultLauncher<Intent> launchCameraAndGalleryActivity = registerForActivityResult(
    new ActivityResultContracts.StartActivityForResult(),
    new ActivityResultCallback<ActivityResult>() {
        @Override
        public void onActivityResult(ActivityResult result) {
            if (result.getResultCode() == Activity.RESULT_OK) {
                
                Intent data = result.getData();
                Uri imageUri;
                if (data != null) {
                    imageUri = data.getData();
                    InputStream imageStream;
                    try {
                        imageStream = getContentResolver().openInputStream(imageUri);
                        Bitmap photoBitmap = BitmapFactory.decodeStream(imageStream);
                        dataModel.setOtherImage(ImageUtil.convert(photoBitmap));
                        documentImageTaken.setVisibility(View.VISIBLE);
                        documentImageTaken.setImageBitmap(photoBitmap);
                    }catch (FileNotFoundException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    });

我是这样开展活动的:

                    Intent photoIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
                launchCameraAndGalleryActivity.launch(photoIntent );

Intent galleryIntent= new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
    launchCameraActivity.launch(galleryIntent);

以下是我的解决方案:

在我们的项目中,我们有超过20次的startActivityForResult(和onActivityResult)。

我们希望尽可能少地更改代码(并继续使用请求代码),同时引入一个优雅的解决方案以供将来使用。

既然我们很多开发人员都使用BaseActivity概念——为什么不利用它呢?

下面是BaseActivity:

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

这是SubActivity:

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

希望它能帮助到别人

在Java 8中,它可以这样写:

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);

如果你像这样实现你的base Activity,你可以继续使用旧的startActivityForResult。 唯一的限制是你必须使用setResult(result, intent)在你的活动中设置结果。 关键是让结果将请求代码带回结果使用者。

public class MyBaseActivity extends AppCompatActivity {
    private ActivityResultLauncher<Intent> activityLauncher;
    protected static String ACTIVITY_REQUEST_CODE = "my.activity.request.code";
    protected _originalIntent; 

    public void launchActivityForResult(Intent intent, int requestCode){
        intent.putExtra(UGM_ACTIVITY_REQUEST_CODE, requestCode);
        activityLauncher.launch(intent);
    }

    //
    //In order to be signature compatible for the rest of derived activities, 
    //we will override the deprecated method with our own implementation!
    //
    @SuppressWarnings( "deprecation" )
    public void startActivityForResult(Intent intent, int requestCode){
        launchActivityForResult(intent, requestCode);
    }

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

    _originalIntent = getIntent();
        //set the default result
        setResult(Activity.RESULT_OK, _originalIntent);

        activityLauncher = registerForActivityResult(new ActivityResultContracts.StartActivityForResult(), new ActivityResultCallback<ActivityResult>() {
            @Override
            public void onActivityResult(ActivityResult result) {
                Intent intent = result.getData();
                int requestCode = intent.getIntExtra(ACTIVITY_REQUEST_CODE, -1);
                MyBaseActivity.this.onActivityResult(requestCode, result.getResultCode(), intent);
            }
        });
    }

}

在我的情况下,我试图使用意图,我直接移动到下一个活动,而不使用谷歌登录。

对我有用的是:

在OnCreate中为登录按钮设置onClickListener:

     btnSignIn.setOnClickListener {
        signIn()
        }

    private fun signIn() {
        val intent = client.signInIntent
        mainActivityResultLauncher.launch(intent)
    }

在上面的代码中,我写了去下一个活动的意图,但我必须写client.signInIntent

    var mainActivityResultLauncher = registerForActivityResult(ActivityResultContracts.StartActivityForResult()){ result ->

        if(result.resultCode == Activity.RESULT_OK){
            val data = result.data
            val task = GoogleSignIn.getSignedInAccountFromIntent(data)
            try {
                // Google Sign In was successful, authenticate with Firebase
                val account = task.getResult(ApiException::class.java)!!
                Log.d(TAG, "firebaseAuthWithGoogle:" + account.id)
                firebaseAuthWithGoogle(account.idToken!!)
            } catch (e: ApiException) {
                // Google Sign In failed, update UI appropriately
                Log.w(TAG, "Google sign in failed", e)
            }
        }
    }