setResult is ignored when user presses the back button - android

In my application, I defined 2 activities in the Manifest file like this:
<activity android:name=".event.EventDetailsActivity"
android:launchMode="singleTop"
android:parentActivityName=".main.MainActivity"
android:theme="#style/AppTheme.WithActionBar"/>
<activity
android:name=".main.MainActivity"
android:launchMode="singleTop"/>
In the MainActivity, I have 4 fragments. In one fragment, I start the EventDetailsActivity in one fragment using:
Intent intent = new Intent(new Intent(getContext(), EventDetailsActivity.class));
intent.putExtra(EventDetailsActivity.ID_KEY, id);
intent.putExtra(EventDetailsActivity.TYPE_KEY, true);
startActivityForResult(intent, DETAILS_REQUEST);
How I handle the back navigation in EventDetailsActivity:
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
NavUtils.navigateUpFromSameTask(this);
return true;
}
return super.onOptionsItemSelected(item);
}
#Override
public boolean onSupportNavigateUp() {
Log.d(TAG, "Navigate up");
onBackPressed();
return true;
}
#Override
public void onBackPressed() {
Log.d(TAG, "Back pressed " + isChanged);
if (isChanged) {
Log.d(TAG, "Set result");
setResult(RESULT_OK);
finish();
}
super.onBackPressed();
}
The problem is onActivityResult get called in the calling Fragment but the result code is always 0 (RESULT_CANCELED). Also, onSupportNavigateUp never gets called if I press the back arrow button. Is there any workaround for this problem?

Remove : android:launchMode="singleTop"
and remove super.onBackpressed in on onBackpressed function
because you used finish()

As you're getting the onActivityResult callback from your Fragment correctly I assume the problem is about setting the proper result to the starting Activity. So here's I'm proposing some edit you might consider in your code.
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
setResult(RESULT_OK);
return true;
}
return super.onOptionsItemSelected(item);
}
// No longer necessary
/* #Override
public boolean onSupportNavigateUp() {
Log.d(TAG, "Navigate up");
onBackPressed();
return true;
} */
/* #Override
public void onBackPressed() {
// Super call needs to be the first line
super.onBackPressed();
if (isChanged) {
setResult(RESULT_OK);
}
} */
So I've omitted the onBackPressed function because by default, if the user presses the back button, the result will be Activity.RESULT_CANCELED.
So there's a hacky solution here is to implement the key event callback listener like this.
#Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if ((keyCode == KeyEvent.KEYCODE_BACK)) {
setResult(RESULT_OK);
finish();
}
return super.onKeyDown(keyCode, event);
}
Hope that helps!

Related

Back button pressed on parent activity

in action bar when back button is pressed how do I know in the previous activity that back button was pressed , onCreate() does not get called when back button is pressed
I know from the code below that on current activity that back button was pressed but I need to know on previous activity that back button was pressed
#Override
public boolean onOptionsItemSelected(#NonNull MenuItem item) {
if (item.getItemId() == android.R.id.home) {
this.finish();
return true;
}
return super.onOptionsItemSelected(item);
}
You can navigate between activities using registerForActivityResult() API, and put some extra data in the returned intent that can show you from where it came from.
At source activity:
ActivityResultLauncher<Intent> launcher = registerForActivityResult(
new ActivityResultContracts.StartActivityForResult(),
result -> {
if (result.getResultCode() == AppCompatActivity.RESULT_OK) {
if (result.getData() != null) {
String data = result.getData().getStringExtra("ACTIVITY_FROM");
if (data != null)
switch (data) {
case "ACTIVITY2":
// Returned from Activity2
Log.d(TAG, "onCreate: Returned from Activity2");
break;
case "ACTIVITY3":
// Returned from Activity3
Log.d(TAG, "onCreate: Returned from Activity3");
break;
}
}
}
}
);
// Go to Activity 2:
auncher.launch(new Intent(this, Activity2.class));
At the destination activity:
Then put the data when you need to return back from Activity2:
#Override
public boolean onOptionsItemSelected(#NonNull MenuItem item) {
if (item.getItemId() == android.R.id.home) {
setIntent();
this.finish();
return true;
}
return super.onOptionsItemSelected(item);
}
#Override
public void onBackPressed() {
setIntent();
finish();
super.onBackPressed();
}
private void setIntent() {
Intent intent = new Intent();
intent.putExtra("ACTIVITY_FROM", "ACTIVITY2");
setResult(Activity.RESULT_OK, intent);
}

how to emulate home button on back button pressed

I'm trying to make my app not close when the user pressed the back button and remain in the same state at least for a while, like the home button. I searched and some people suggested to do this.
#Override
public void onBackPressed() {
super.onBackPressed();
this.moveTaskToBack(true);
}
but this didn't help. I have to mention the activity I'm using this code on is not the LAUNCHER activity and before this activity, there is a splash screen.
what am I doing wrong?
Try my code in your activity.
#Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
Log.d(TAG, "onKeyDown: ");
if(keyCode == KeyEvent.KEYCODE_BACK){
goHome();
return true;
}
return super.onKeyDown(keyCode, event);
}
private void goHome() {
Intent i = new Intent(Intent.ACTION_MAIN);
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
i.addCategory(Intent.CATEGORY_HOME);
startActivity(i);
}
Do start the home screen when key back down.
You should not call super method in onBackPressed(). It should be simply like this
#Override
public void onBackPressed() {
moveTaskToBack(true);
}

OnBackBressed not called

I have activity ActivityProfile, have getSupportActionBar().setDisplayHomeAsUpEnabled(true); implemented, onBackPressed() as well, search all over the internet and still no help.
#Override
public void onBackPressed() {
Toast.makeText(this, "OnBackpressed fired", Toast.LENGTH_SHORT).show();
super.onBackPressed();
}
#Override
public boolean onKeyDown(int keyCode, KeyEvent event)
{
//replaces the default 'Back' button action
if(keyCode== KeyEvent.KEYCODE_BACK) {
// something here
onBackPressed();
}
return true;
}
using the device's back button works, but not on the app...
To implement Up navigation, declare a parent of that particular activity in manifest and setDisplayHomeAsUpEnabled as true.
<activity
android:name="com.example.myfirstapp.DisplayMessageActivity"
android:label="#string/title_activity_display_message"
android:parentActivityName="com.example.myfirstapp.MainActivity" >
<!-- Parent activity meta-data to support 4.0 and lower -->
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value="com.example.myfirstapp.MainActivity" />
</activity>
Read More https://developer.android.com/training/implementing-navigation/ancestral.html
you should use onOptionItemSelected to handle click on the bottom on action bar :
#Override
public boolean onOptionsItemSelected(MenuItem item)
{
switch (item.getItemId())
{
case android.R.id.home:
finish();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
Try this
setSupportActionBar(toolbar);
toolbar.setNavigationOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
onBackPressed();
}
});
This should work
#Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == android.R.id.home) {
onBackPressed();
}
return super.onOptionsItemSelected(item);
}
hi add this code in your activity. when you press back button in toolbar following code execute.
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.your_view);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setHomeButtonEnabled(true);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()){
case android.R.id.home:
finish();
break;
default:
return super.onOptionsItemSelected(item);
}
return super.onOptionsItemSelected(item);
}

How to go back to previous activite(s)?

so i have Activity A,B, and C. Activity A & B both go to activity C. When i am on activity C and I press the back home button on mySupportActionBar, I want to return to the state of activity (from the state i left it in) I came from. How would i accomplish this?
Here is my onOptionsItemSelected(). So currently, it goes back to the designated parent activity i assigned in manifest to avoid my app from crashing. Because the parent activites require strings from intents.
#Override
public boolean onOptionsItemSelected(MenuItem item)
{
int id = item.getItemId();
if(id == android.R.id.home)
{
NavUtils.navigateUpFromSameTask(this);
}
return super.onOptionsItemSelected(item);
}
I would also love to accomplish this onBackPressed().
The back arrow button is the "home" button when you're in a inner activity so you could finish the inner activity or maybe just call the back button
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
onBackPressed();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
Use android.R.id.home
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
finish();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
You also can use setNavigationOnClickListener on toolbar to trigger back button.
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_filter_category);
setSupportActionBar(toolbar);
if (getSupportActionBar() != null) {
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setDisplayShowTitleEnabled(false);
//back button action
toolbar.setNavigationOnClickListener(view -> finish());
}
}

Toolbar back button does not close current Fragment

I have an activity that loads a Fragment onCreate. And I have a toolbar on that activity that has a button that when clicked will add a new Fragment on top of the one that got created first.
Now on that toolbar, when clicked, I want to remove the newer fragment so that it just displaces the fragment that is in the bottom (older one). I've searched and I kinda have figured it out except for one thing.
I did this so that it tries to see if the toolbar button is pressed:
#Override
public boolean onKeyUp(int keyCode, KeyEvent objEvent) {
if (keyCode == KeyEvent.KEYCODE_BACK) {
onBackPressed();
return true;
}
return super.onKeyUp(keyCode, objEvent);
}
#Override
public void onBackPressed() {
FragmentManager mFM = getSupportFragmentManager();
if(mFM.findFragmentByTag("NewFragment") != null){
mFM.beginTransaction().remove(mFM.findFragmentByTag("NewFragment")).commit();
}
}
The problem is, "keyCode" is only equals to KEYCODE_BACK when you click the "hardware's back button" and not the back button of the toolbar. What it gives me is keycode 58 and not 4 (KEYCODE_BACK).
I believe what your looking for is the NavigationListener for the Toolbar Widget:
mToolbar.setNavigationOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
onBackPressed();
}
});
but if your using a Theme with an ActionBar and setting a supportActionBar then do something :
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch(item.getItemId()){
case android.R.id.home:
onBackPressed();
break;
}
return true;
}
It's not clear from your question whether you're asking a Fragment management question (FragmentTransaction remove vs. replace), or a Toolbar button question. I assume the latter...
An Android Toolbar or ActionBar should have actions handled using:
#Override
public Boolean onOptionsItemSelected(MenuItem item)
{
switch (item.getItemId())
{
case MY_BACK_BUTTON:
myBackPressedHandler();
return (true);
}
return (false);
}
this assumes that your Back button is added as a MenuItem and was given an ID of MY_BACK_BUTTON.
For a Toolbar, you can use a MenuItemClickListener to handle the click events:
mToolbar.setOnMenuItemClickListener(MenuItem menuItem)
{
#Override
public Boolean onMenuItemClick(MenuItem menuItem)
{
// call onOptionsItemSelected, or handle the click here directly
return (thisFragment.onOptionsItemSelected(menuItem));
}
});
If you're referring to the "Up" button on the Toolbar/ActionBar, i.e. setDisplayHomeAsUpEnabled(true), this will have a getItemId() of android.R.id.home and can be handled in a similar fashion:
case android.R.id.home:
myBackPressedHandler();
return (true);

Categories

Resources