OnBackPress behaving differently in android - java

I have 3 activities: A,B,C. When I click on an item in RecyclerView in activity A activity B will be opened. There are a few String values which I have passed from A to B.
In activity B when I click on a button I go to activity C. In C when I press back button from my phone(android default back button) it comes back normally to activity B. But I have also put a back button in ToolBar using parent activity. When I press that button it shows me error that the String value trying to retrieve in activity B is null. I understand why the error is showing. It's obviously because there is no string passed from C to B to fetch.
But why am I not getting this error when I press back from my phones default button? How can I solve this?
Activity A
Intent intent = new Intent(getActivity(), Chat.class);
intent.putExtra("Recievers_Id", userId);
intent.putExtra("Recievers_Name", userName);
startActivity(intent);
Activity B
MessageSenderId = mAuth.getCurrentUser().getUid();
MessageRecieverId = getIntent().getStringExtra("Recievers_Id");
MessageRecieverName = getIntent().getStringExtra("Recievers_Name");
Activity C
Toolbar toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
Getting an error on
MessageRecieverId = getIntent().getStringExtra("Recievers_Id");
MessageRecieverName = getIntent().getStringExtra("Recievers_Name");
because obviously nothing to fetch... how do i solve this

Add onClickListener to the back button of your toolbar:
toolbar.setNavigationOnCLickListener(new View.OnClickListener){
#Override
public void onClick(View view) {
finish();
}
});
If you are getting error for null then try this:
if(getIntent().getStringExtra("Recievers_Id") != null){
MessageRecieverId = getIntent().getStringExtra("Recievers_Id");
}
if(getIntent().getStringExtra("Recievers_Name") != null){
MessageRecieverName = getIntent().getStringExtra("Recievers_Name");
}

On activity B you should check is Intent has rquired Extra.
Intent i = getIntent();
if (i.hasExtra("Recievers_Id")) {
messageRecieverId = i.getStringExtra("Recievers_Id");
}
if (i.hasExtra("Recievers_Name")) {
messageRecieverName= i.getStringExtra("Recievers_Name");
}

You can set the working of back button on toolbar as:
#Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
switch (id) {
// Respond to the action bar's Up/Home button
case android.R.id.home:
//NavUtils.navigateUpFromSameTask(this);
onBackPressed();
return true;
}
return super.onOptionsItemSelected(item);
}

First of all, you need to understand what happens when user presses navigation up button and what happens when onBackPressed.
Based on the documentation:
If the parent activity has launch mode <singleTop>, or the up intent contains FLAG_ACTIVITY_CLEAR_TOP, the parent activity is brought
to the top of the stack, and receives the intent through its
onNewIntent() method.
If the parent activity has launch mode , and the up intent does not contain FLAG_ACTIVITY_CLEAR_TOP, the parent activity
is popped off the stack, and a new instance of that activity is
created on top of the stack to receive the intent.
Where as when back button is pressed, it navigate, in reverse chronological order, through the history of screens. In this case Activity won't be re-created.
To summarize, the lauch mode of your ActivityB in AndroidManifest.xml must be standard. In this case the activity will be recreated when you press the navigation up button. But when back button is pressed, ActivityB is just brought to front, hence the difference in behavior.
Solution:
Approach 1: handle Up button by yourself
#Override
public boolean onOptionsItemSelected(MenuItem item) {
if(item.getItemId()== android.R.id.home {
onBackPressed();
return true;
}
return super.onOptionsItemSelected(item);
}
Approach 2:
Set launch mode of Activity B to singleTop in AndroidManifest.xml. Remember to check the implication of changing the launch mode.
The "standard" and "singleTop" modes differ from each other in just
one respect: Every time there's a new intent for a "standard"
activity, a new instance of the class is created to respond to that
intent. Each instance handles a single intent. Similarly, a new
instance of a "singleTop" activity may also be created to handle a new
intent. However, if the target task already has an existing instance
of the activity at the top of its stack, that instance will receive
the new intent (in an onNewIntent() call); a new instance is not
created.

Related

carrying intent data throughout 2 activities in android studio

i carried some edittext string data from a second activity to the first and placed the string data into textviews in the first activity.
this worked fine.
when i go from the first activity back to the second activity (done using the options menu), i want to carry the previously entered edittext data back into the edit texts in the second activity. i cant get it to carry over - the second activity edittexts go back to the original edittext settings (empty).
this is my second activity code:
public void goToMain(View view) { //run when a button is clicked
Intent intent = new Intent(setPlayersActivity.this, MainActivity.class);
intent.putExtra("P1",p1EditText.getText().toString());
startActivity(intent);
}
and in my first activity code i have in the on create:
Intent name = getIntent();
p1TextView.setText(name.getStringExtra("P1"));
to go from the first activity to the second
public boolean onOptionsItemSelected(#NonNull MenuItem item) {
if (item.getItemId() == R.id.resetAll) {
updateScoreTeamA(scoreA = 0);
} else if (item.getItemId() == R.id.setPlayers) {
Intent intent = new Intent(MainActivity.this, setPlayersActivity.class);
startActivity(intent);
}
return super.onOptionsItemSelected(item);
}
up to here is working fine.
upon returning to the second activity though, the edittexts are again empty (i want to carry the previously entered data back to this activity).
to fill the edittexts with the previously entered string data, i tried the following in the on create of the second activity.
p1EditText.setText(getIntent().getStringExtra("P1"));
thanks in advance for the help. i am a beginner with programming and cannot imagine making any progress without this community.
When your changing activity you have to provide data to that certain intent. Otherwise it won't work
Intent intent = new Intent(MainActivity.this, setPlayersActivity.class);
intent.putExtra("P1","data");
startActivity(intent);

Closing current and previous activity on click of button(not the back button) on current activity

I start in main activity A. From A I go to activity B and from B I go to C. Now in activity C if a button is clicked (not back button) ,activity B and C need to close and a new instance of activity B needs to be created. But if that particular button is not pressed and back button is pressed then activity C is closed and we return to previous activity B. I am making a reminder app. Activity B is a recycler view showcasing all the tasks and Activity c is to create new task. So if on activity C submit button is pressed I want activity C and B to be closed and a new instance of b to be opened i.e. recycler view with new tasks but if submit is not pressed I want to close activity C and return to original instance of B. How to do so?
Maybe you can use this 2 methods
(1) Use IntentReceiver
From second activity
Intent i = new Intent(SecondActivity.this, ThirdActivity.class);
i.putExtra("SecondActivity", new ResultReceiver(null) {
#Override
protected void onReceiveResult(int resultCode, Bundle resultData) {
SecondActivity.this.finish();
}
});
startActivityForResult(i, 1);
In third activity
((ResultReceiver) Objects.requireNonNull(getIntent().getParcelableExtra("MainActivity"))).send(1, new Bundle());
//And after this finish current activity (Second activty)
startActivity(new Intent(ThirdActivity.this, FirstActivity.class));
finish();
(2) If Clear all previous and current activity
Intent intent = new Intent(getApplicationContext(), FirstActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
You can use the method finishAffinity() to exit an activity. I hope this at least makes the problem a bit easier.
Start Activity B with the intent flag FLAG_ACTIVITY_CLEAR_TOP
https://developer.android.com/reference/android/content/Intent#FLAG_ACTIVITY_CLEAR_TOP

Can I end an activity and start a new one from a fragment switch case?

I am working in android studio.I have a bottom-navigation fragment. For the last switch case, I need a button to navigate to the HomeActivity (home screen). I tried:
...
case SUMMARY:
navNextText.setText(R.string.end);
navNextImageView.setOnClickListener(v -> navigateHome());
navNextText.setOnClickListener(v -> navigateHome());
break;
default:
Log.w(TAG, "Executing a default case in navigateNext(). CTX: " + contextState.toString());
}
private void navigateHome() {
Objects.requireNonNull(getActivity()).finish();
Intent in = new Intent(getActivity(), HomeActivity.class);
startActivity(in);
}
This works to an extent. I can navigate home, but when I click back into the activity that the navigation fragment resides, the navigation bar resumes where it was previous to changing activity.
I have also tried adding onStop() and onDestroy to private void navigateHome, but that seemed to do nothing.
I am just wondering what is the cleaner way to close an activity from a fragment and start a new one.
just add finish() if you want to remove the current activity from the backstack
As you're in a fragment, use requireActivity().finish()
Also to make sure you have no activities in back stack, you can remove all using below intent flag
private void navigateHome() {
Objects.requireNonNull(getActivity()).finish();
Intent in = new Intent(getActivity(), HomeActivity.class);
in.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); // <<<<< flag
startActivity(in);
requireActivity().finish(); // <<< finish the current activity
}

Trying to call a method from 1st class activity and keep the same argument in a 2nd class activity (android studio)

Currently finishing up an app I have been working on but I'm kinda stuck on this last thing.
The app has 2 activities, one with buttons that are categories and the other shows the information according to the button pressed. For example if you click the button Fast food, it goes to the 2nd screen and displays info on that.
I'm trying to get a refresh button on the 2nd activity that will call a method in the 1st activity to refresh new information depending on the button pressed. The problem is that I don't know how to make it so the method keeps the same argument when called. What I mean is, if fast food was clicked, the refresh button would get new info that still relates to the fast food category.
Here's the relevant code in the Main activity:
public void yelpSearch(View view) {
switch (view.getId()) {
case R.id.button: buttoncategory = "Restaurant";
break;
case R.id.button2: buttoncategory = "Chinese restaurant";
break;
case R.id.button3: buttoncategory = "Fast Food";
break;
and this on the 2nd Activity
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.refresh:
Refresh();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
public void Refresh() {
MainActivity mActivity = new MainActivity();
mActivity.yelpSearch();
}
I'm not sure what to put inside mActivity.yelpSearch();
I tried using (View view) but it'll say cannot resolve symbol view. And if I make a local variable for view, it'll say not initialized and I don't know what to set it as
Any help would be awesome, been googling on this for a while now and searched through tons of questions on here as well. I'm still new at this so bear with me
I think you want to pass data between activities?
First Activity(Send DATA):
String data="YourXXXdata"
Intent intent = new Intent(getBaseContext(), MainActivity.class);
intent.putExtra("DATANAME", data);
startActivity(intent)
second Activity(Receive DATA):
Bundle extras = getIntent().getExtras();
if (extras != null) {
String value = extras.getString("DATANAME");
}
The data now is in String value
*you have to put in data the value you need depend you preview select button.
Make your yelpSearch method static
and call it like this from 2nd activity MainActivity.yelpSearch();

Switching back to previous activity in tabhost

I am using TabActivity(for example, TActivity) to create tab and in every tab I am loading instance of same activity(for example, MainActivity).
Through this activity I want to switch another activitity(for example, ChildActivity which will be same for every tab i.e. in every tab we will get instance of this activity) using Button click.
This button is hardcoded in original TabActivity(TActivity).
Now I am able to do up to this. But Now I want to switch between 'MainActivity' and 'ChildActivity' using same Button.
MainActivity:
class MainActivity ...{
onCreate(){
Btn.setOnClickListener(new OnClickListener(--) {
public void onClick(--){
Intent intent = new Intent(getBaseContext(),ChildActivity.class);
replaceContentView("MainActivity", intent);
}});
}//MainActivity
public void replaceContentView(String id, Intent newIntent) {
View view = getLocalActivityManager().startActivity(id,newIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_REORDER_TO_FRONT)) .getDecorView(); this.setContentView(view);
}//replaceContentView
in ChildActivity:
public void hideCurrentActivity(){
Intent intent = new Intent(getBaseContext(),MainActivity.class);
replaceContentView("ChildActivity", intent);
}
public void replaceContentView(String id, Intent newIntent) {
View view = getLocalActivityManager().startActivity(id,newIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP) .getDecorView(); this.setContentView(view);
}
Ok, now problem is that this code creates fresh activity everytime. So all previous data is getting lost once I switch to previous activity.But i don't want to create fresh activity instead just want to bring old one to front.
Can anybody help?
Thanks in advance.

Categories