Onactivityresult Method Is Deprecated, What Is the Alternative

OnActivityResult method is deprecated, what is the alternative?

A basic training is available at developer.android.com.

Here is an example on how to convert the existing code with the new one:

The old way:

public void openSomeActivityForResult() {
Intent intent = new Intent(this, SomeActivity.class);
startActivityForResult(intent, 123);
}

@Override
protected void onActivityResult (int requestCode, int resultCode, Intent data) {
if (resultCode == Activity.RESULT_OK && requestCode == 123) {
doSomeOperations();
}
}

The new way (Java):

public void openSomeActivityForResult() {
Intent intent = new Intent(this, SomeActivity.class);
someActivityResultLauncher.launch(intent);
}

// You can do the assignment inside onAttach or onCreate, i.e, before the activity is displayed
ActivityResultLauncher<Intent> someActivityResultLauncher = registerForActivityResult(
new ActivityResultContracts.StartActivityForResult(),
new ActivityResultCallback<ActivityResult>() {
@Override
public void onActivityResult(ActivityResult result) {
if (result.getResultCode() == Activity.RESULT_OK) {
// There are no request codes
Intent data = result.getData();
doSomeOperations();
}
}
});

The new way (Kotlin):

fun openSomeActivityForResult() {
val intent = Intent(this, SomeActivity::class.java)
resultLauncher.launch(intent)
}

var resultLauncher = registerForActivityResult(StartActivityForResult()) { result ->
if (result.resultCode == Activity.RESULT_OK) {
// There are no request codes
val data: Intent? = result.data
doSomeOperations()
}
}

EDIT. A better approach would be to make it more generalised so that we can reuse it. The snippet below is used in one of my projects but beware that it's not well-tested and may not cover all the cases.

BetterActivityResult.java

import android.content.Intent;
import androidx.activity.result.ActivityResult;
import androidx.activity.result.ActivityResultCaller;
import androidx.activity.result.ActivityResultLauncher;
import androidx.activity.result.contract.ActivityResultContract;
import androidx.activity.result.contract.ActivityResultContracts;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

public class BetterActivityResult<Input, Result> {
/**
* Register activity result using a {@link ActivityResultContract} and an in-place activity result callback like
* the default approach. You can still customise callback using {@link #launch(Object, OnActivityResult)}.
*/
@NonNull
public static <Input, Result> BetterActivityResult<Input, Result> registerForActivityResult(
@NonNull ActivityResultCaller caller,
@NonNull ActivityResultContract<Input, Result> contract,
@Nullable OnActivityResult<Result> onActivityResult) {
return new BetterActivityResult<>(caller, contract, onActivityResult);
}

/**
* Same as {@link #registerForActivityResult(ActivityResultCaller, ActivityResultContract, OnActivityResult)} except
* the last argument is set to {@code null}.
*/
@NonNull
public static <Input, Result> BetterActivityResult<Input, Result> registerForActivityResult(
@NonNull ActivityResultCaller caller,
@NonNull ActivityResultContract<Input, Result> contract) {
return registerForActivityResult(caller, contract, null);
}

/**
* Specialised method for launching new activities.
*/
@NonNull
public static BetterActivityResult<Intent, ActivityResult> registerActivityForResult(
@NonNull ActivityResultCaller caller) {
return registerForActivityResult(caller, new ActivityResultContracts.StartActivityForResult());
}

/**
* Callback interface
*/
public interface OnActivityResult<O> {
/**
* Called after receiving a result from the target activity
*/
void onActivityResult(O result);
}

private final ActivityResultLauncher<Input> launcher;
@Nullable
private OnActivityResult<Result> onActivityResult;

private BetterActivityResult(@NonNull ActivityResultCaller caller,
@NonNull ActivityResultContract<Input, Result> contract,
@Nullable OnActivityResult<Result> onActivityResult) {
this.onActivityResult = onActivityResult;
this.launcher = caller.registerForActivityResult(contract, this::callOnActivityResult);
}

public void setOnActivityResult(@Nullable OnActivityResult<Result> onActivityResult) {
this.onActivityResult = onActivityResult;
}

/**
* Launch activity, same as {@link ActivityResultLauncher#launch(Object)} except that it allows a callback
* executed after receiving a result from the target activity.
*/
public void launch(Input input, @Nullable OnActivityResult<Result> onActivityResult) {
if (onActivityResult != null) {
this.onActivityResult = onActivityResult;
}
launcher.launch(input);
}

/**
* Same as {@link #launch(Object, OnActivityResult)} with last parameter set to {@code null}.
*/
public void launch(Input input) {
launch(input, this.onActivityResult);
}

private void callOnActivityResult(Result result) {
if (onActivityResult != null) onActivityResult.onActivityResult(result);
}
}

With the above approach, you still have to register it before or during launching the activity or fragment attachment. Once defined, it can be reused within the activity or fragment. For example, if you need to start new activities in most of the activity, you can define a BaseActivity and register a new BetterActivityResult like this:

BaseActivity.java

public class BaseActivity extends AppCompatActivity {
protected final BetterActivityResult<Intent, ActivityResult> activityLauncher = BetterActivityResult.registerActivityForResult(this);
}

After that, you can simply launch an activity from any child activities like this:

public void openSomeActivityForResult() {
Intent intent = new Intent(this, SomeActivity.class);
activityLauncher.launch(intent, result -> {
if (result.getResultCode() == Activity.RESULT_OK) {
// There are no request codes
Intent data = result.getData();
doSomeOperations();
}
})
}

Since you can set the callback function along with the Intent, you can reuse it for any activities.

Similarly, you can also use other activity contracts using the other two constructors.

startActivityForResult is deprecated, I'm trying to update my code

Replace startActivityForResult with Callback for for Activity Result

Intent chooserIntent = new Intent(Intent.ACTION_CHOOSER);
chooserIntent.putExtra(Intent.EXTRA_INTENT, contentSelectionIntent);
chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, intentArray);
startActivityIntent.launch(chooserIntent);

Callback for for Activity Result - startActivityIntent

ActivityResultLauncher<Intent> startActivityIntent = registerForActivityResult(
new ActivityResultContracts.StartActivityForResult(),
new ActivityResultCallback<ActivityResult>() {
@Override
public void onActivityResult(ActivityResult result) {
// Add same code that you want to add in onActivityResult method
}
});

For more info check official documentation.

onActivityResult deprecated, how to handle google signin in fragment for android(Java)?

As here said, you can get sign in intent by calling getSignInIntent

ActivityResultLauncher<Intent> exampleActivityResult= registerForActivityResult(
new ActivityResultContracts.StartActivityForResult(),
new ActivityResultCallback<ActivityResult>() {
@Override
public void onActivityResult(ActivityResult result) {
if (result.getResultCode() == Activity.RESULT_OK) {
Task<GoogleSignInAccount> task = GoogleSignIn.getSignedInAccountFromIntent(result.getData());
handleSignInResult(task);
}
}
});



//call
exampleActivityResult.launch(mGoogleSignInClient.getSignInIntent());

Update - 30-11-2021

here is the new method by google !

OnActivityResult method is deprecated, how do I use registerForActivityResult from a Menu's onOptionItemselected

I have found the Problem in my thinking. I just had to use the Intent I created before to launch the resultLauncher, that was shown on the previous question, instead of the Activity-changing Intent.

Also, I found, that the Value val resultLauncher, that was shown, had to be declared inside the class but outside the other functions, which was the part, where I got confused. Guess I got routine-blinded and should take more Breaks

Deprecated use of startActivityForResult (KOTLIN) (RESOLVED)

I resolved the code finally. Thanks for everyone trying to help. I am sure that a lot of people like me (beginner) are learning from old videos and will have this problem. I hope this helps!

Compare both codes and use it for your way.

class SharePhotograph : AppCompatActivity() {

private var pickedImage : Uri? = null
private var pickedBitmap : Bitmap? = null
private lateinit var storage : FirebaseStorage
private lateinit var auth : FirebaseAuth
private lateinit var database : FirebaseFirestore

private var resultLauncher = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result ->
if (result.resultCode == Activity.RESULT_OK) {
// There are no request codes
val data: Intent? = result.data
pickedImage = data?.data

if (pickedImage != null){
if (Build.VERSION.SDK_INT >= 28)
{
val source = ImageDecoder.createSource(this.contentResolver,pickedImage!!)
pickedBitmap = ImageDecoder.decodeBitmap(source)
val imageSelect = findViewById<ImageView>(R.id.imageView)
imageSelect.setImageBitmap(pickedBitmap)
}
else
{
pickedBitmap = MediaStore.Images.Media.getBitmap(this.contentResolver,pickedImage)
val imageSelect = findViewById<ImageView>(R.id.imageView)
imageSelect.setImageBitmap(pickedBitmap)
}
}
}
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_share_photograph)

val imageSelect = findViewById<ImageView>(R.id.imageView)
val butShare = findViewById<Button>(R.id.butShare)
val userCommentText = findViewById<TextView>(R.id.userCommentText)

storage = FirebaseStorage.getInstance()
auth = FirebaseAuth.getInstance()
database = FirebaseFirestore.getInstance()

imageSelect.setOnClickListener{
pickImage()
}

butShare.setOnClickListener{
//Storage Process
//UUID -> Universal Unique ID
val uuid = UUID.randomUUID()
val imageName = "${uuid}.jpg"

val reference = storage.reference
val imageReference = reference.child("images").child(imageName)

if (pickedImage != null){
imageReference.putFile(pickedImage!!).addOnSuccessListener {
val uploadedImageReference = FirebaseStorage.getInstance().reference.child("images").child(imageName)
uploadedImageReference.downloadUrl.addOnSuccessListener { uri ->
val downloadUrl = uri.toString()
val currentUserEmail = auth.currentUser!!.email.toString()
val userComment = userCommentText.text.toString()
val date = Timestamp.now()

//Database Process
val postHashMap = hashMapOf<String, Any>()
postHashMap["Image URL"] = downloadUrl
postHashMap["User Email"] = currentUserEmail
postHashMap["User Comment"] = userComment
postHashMap["Post Date"] = date

database.collection("Post").add(postHashMap).addOnCompleteListener { task ->
if(task.isSuccessful){
Toast.makeText(this,"Uploaded!",Toast.LENGTH_SHORT).show()
finish()
}
}.addOnFailureListener { exception ->
Toast.makeText(applicationContext,exception.localizedMessage,Toast.LENGTH_LONG).show()
}
}.addOnFailureListener { exception ->
Toast.makeText(applicationContext,exception.localizedMessage,Toast.LENGTH_LONG).show()
}
}
}
}
}
private fun pickImage(){
if(ContextCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
//No Permission
ActivityCompat.requestPermissions(this, arrayOf(Manifest.permission.READ_EXTERNAL_STORAGE),1)
}else {
openGallery()
}
}
private fun openGallery() {
val galleryIntent = Intent(Intent.ACTION_PICK,MediaStore.Images.Media.EXTERNAL_CONTENT_URI)
resultLauncher.launch(galleryIntent)
}

}



Related Topics



Leave a reply



Submit