I have a problem that is annoying me. I have made an application that has two activitis. The first activity has a button and when you press the button it starts the second activity. I'm in the second activity and I press the home button to exit the app, and when I reopen the app the activity launched it's the first one. I want to launch the activity where the app was closed, in this case the second one. How can I do it?
public class FirstActivity extends ActionBarActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_first);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
View bub = findViewById(R.id.card_ub);
bub.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent1 = new Intent(FisrtActivity.this, SecondActivity.class);
startActivity(intent1);
}
});
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
// Respond to the action bar's Up/Home button
}
return super.onOptionsItemSelected(item);
}
}
Second Activity -
public class SecondActivityActivity extends ActionBarActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_second);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
View bub = findViewById(R.id.card_ub);
bub.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent1 = new Intent(FSecondActivity.this, FirstActivity.class);
startActivity(intent1);
}
});
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
// Respond to the action bar's Up/Home button
}
return super.onOptionsItemSelected(item);
}
}
Manifest file -
<application
android:allowBackup="true"
android:icon="#drawable/dc"
android:label="#string/app_name"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<activity
android:name=".FirstActivity"
android:label="#string/app_name"
android:screenOrientation="portrait"
android:theme="#style/AppTheme">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".SecondActivity"
android:label="Example"
android:screenOrientation="portrait"
android:theme="#style/AppTheme">
</activity>
</application>
</manifest>
Check developer page for better understanding of backstack.
http://developer.android.com/guide/components/tasks-and-back-stack.html
just call startactivity(new Intent(FirstActivity.this, SecondActivity.class). if you shoould not call finish() when starting new activity. if you are using intent flags like CLEAR_FLAG it will destroy your activity when starting the second activity.
Check your phone setting if you setup "Don't keep background process".
In your case, seems your phone system always kill your application when entering background.
So, if your phone always does that, you can do two things:
close this setting.
Or, you can save activity status in SecondActivity, e.g, onPause / onStop, to let your application know that your current status is SecondActivity.
Next time you open the application, check your application status in FirstActivity, and restore the status to SecondActivity.
Related
I have a simple application. It consists of Activity A and Activity B.
When I start at Activity A (from the launcher icon) and then navigate to Activity B, and then hit the up button. I arrive at Activity A. Perfect.
Yet when I start activity B from the command line (simulating another app or a notification starting this activity) and I hit the up button, I just get taken to the home screen.
Here is my setup:
Activity A
public class ActivityA extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent intent = new Intent(ActivityA.this, ActivityB.class);
startActivity(intent);
}
});
}
}
Activity B
public class ActivityB extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_b);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
}
}
My manifest. Note that the parent activity is defined and my app min api is 16 (so the parent activity declaration is valid for 16 and up).
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:roundIcon="#mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<activity
android:name=".ActivityA"
android:label="#string/app_name"
android:theme="#style/AppTheme.NoActionBar">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".ActivityB"
android:exported="true"
android:label="#string/title_activity_b"
android:parentActivityName=".ActivityA"
android:theme="#style/AppTheme.NoActionBar" />
</application>
To start ActivityB from cmd line I use: adb shell am start com.example.demo/com.example.demo.ActivityB
EDIT 1
According to docs here: https://developer.android.com/training/appbar/up-action.html
You do not need to catch the up action in the activity's
onOptionsItemSelected() method. Instead, that method should call its
superclass, as shown in Respond to Actions. The superclass method
responds to the Up selection by navigating to the parent activity, as
specified in the app manifest.
Edit 2:
Just for kicks, I tried the two code snippets here. One at a time to see if they would do the trick. But they don't. ActivityA doesn't open. ActivityB just closes.
https://developer.android.com/training/implementing-navigation/ancestral.html
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
// Respond to the action bar's Up/Home button
case android.R.id.home:
NavUtils.navigateUpFromSameTask(this);
return true;
}
return super.onOptionsItemSelected(item);
}
and
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
// Respond to the action bar's Up/Home button
case android.R.id.home:
Intent upIntent = NavUtils.getParentActivityIntent(this);
if (NavUtils.shouldUpRecreateTask(this, upIntent)) {
// This activity is NOT part of this app's task, so create a new task
// when navigating up, with a synthesized back stack.
TaskStackBuilder.create(this)
// Add all of this activity's parents to the back stack
.addNextIntentWithParentStack(upIntent)
// Navigate up to the closest parent
.startActivities();
} else {
// This activity is part of this app's task, so simply
// navigate up to the logical parent activity.
NavUtils.navigateUpTo(this, upIntent);
}
return true;
}
return super.onOptionsItemSelected(item);
}
What's happening vs expected?
When I open ActivityB via the cmd line and hit up, I expect to go to ActivityA while ActivityB closes. What actually happens is that ActivityB just closes.
That is the default bahavior, the up navigation button works with the Activity Stack, if the ActivityA isn't in the stack, the Android will return to the previous screen , in this case the Home.
I have 2 activities: HomeActivity and EmailChangeActivity and some fragment inside HomeActivity. What I want to do is to set back navigation arrow in EmailChangeActivity toolbar. I have more activities and somehow I managed to make that arrow (but I made Intents straight from activities, not from fragment inside activities). What I did in order to get that arrow was:
When I go to EmailChangeActivity from HomeActivity I call this in HomeActivity fragment:
Intent intent = new Intent(getActivity().getApplicationContext(),
ChangeEmailActivity.class);
getActivity().startActivityForResult(intent, 1);
Inside EmailChangeActivity I insert standard code creating Toolbar and setting it:
// Setting Toolbar
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
getSupportActionBar().setTitle(getString(R.string.change_email_activity_name));
getSupportActionBar().setDisplayShowHomeEnabled(true);
getSupportActionBar().setDefaultDisplayHomeAsUpEnabled(true);
In Manifext.xml I made:
<!-- Home Activity -->
<activity
android:name="com.example.nazwamarki.myapplication.HomeActivity"
android:label="#string/home_activity_name"
android:theme="#style/AppTheme.Normal">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<!-- Change Email Activity -->
<activity
android:name="com.example.nazwamarki.myapplication.ChangeEmailActivity"
android:label="#string/register_activity_name"
android:theme="#style/AppTheme.Normal"
android:parentActivityName=".HomeActivity">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value="com.example.nazwamarki.myapplication.HomeActivity" />
</activity>
Still got no result. Any help?
Edit
I forgot to add that I also included in EmailChangeActivity:
#Override
public boolean onCreateOptionsMenu(Menu menu) {
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == R.id.home) {
NavUtils.navigateUpFromSameTask(this);
return true;
}
return super.onOptionsItemSelected(item);
}
If you're not using an ActionBarActivity:
mToolbar.setNavigationIcon(getResources().getDrawable(R.drawable.ic_action_back));
mToolbar.setNavigationOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// The intent to go back to HomeActivity
}
});
If you are using an ActionBarActivity, then all you need to do is make Android use the Toolbar as an ActionBar.
setSupportActionBar(mToolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setDisplayShowHomeEnabled(true);
Looks like you're missing this part:
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
// Respond to the action bar's Up/Home button
case android.R.id.home:
NavUtils.navigateUpFromSameTask(this);
return true;
}
return super.onOptionsItemSelected(item);
}
You can get more details on this here Android Developers- Providing up navigation
I have an Activity name "IntroActivity" that is the "Launcher" activity for the app and after some decision making opens up a new Activity named "HomeActivity".
In my HomeActivity I have an ActionBar with a "Log Out" Action (which is in the menu but set to appear as an Action) which is supposed to do some operations and return the user to the "IntroActivity".
However, the startActivity method used inside HomeActivity does not work and there are no errors generated. I have debugged the code and the onOptionsItemSelected method is definitely executed as is the correct case inside. Here is the code:
HomeActivity:
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_standard, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.menu_standard_settings:{
// TODO
return true;
}
case R.id.menu_standard_logout:{
//Set logged in to false and then return the user to the intro page
SharedPreferences.Editor editor = settings.edit();
editor.putBoolean("logged_in", false);
Intent introIntent = new Intent(this, IntroActivity.class);
startActivity(introIntent);
return true;
}
}
return super.onOptionsItemSelected(item);
}
The Manifest includes:
<activity
android:name="com.kennel39.diabeteslive_adtdev.IntroActivity"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
I'm not sure what else I can provide that will be of use but I will quickly post up any extra parts if required.
Thanks in advance,
Josh
I think you miss commit the shared preference after setting loggedIn as false. So your flag is not updated and your intro activity again redirect you to home activity.
Try
editor.commit();
From what I can see, you miss two things to make things work:
Add editor.commit(); just after editor.putBoolean("logged_in", false); in order to save your value "logged_in"
Add finish(); between startActivity(introIntent); and return true;
I have my simple PreferenceActivity class and its onCreate passes my R.xml.preferences screen to ((PreferenceActivity)super).addPreferencesFromResource. Finally, in my AndroidManifest.xml my activity as follows:
<activity android:name="com.criticalrf.jwalkietalkie.PreferenceServerActivity" >
<intent-filter>
<action android:name="android.intent.action.MANAGE_NETWORK" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
On the device, the menu button will trigger a menu with only the word "Settings." Clicking on Settings makes the Settings button go away but does not show anything. Do I need to add something in my MainActivity? I followed this guide, I'm not sure what I missed.
If you want to open this preference activity from your main activity you should call somewhere in your MainActivity:
startActivity(new Intent(this, PreferenceServerActivity.class));
and preference activity will show.
Typical implementation would be doing it with options menu. Like:
private static final int SettingsId = 1;
#Override
public boolean onCreateOptionsMenu(Menu menu)
{
menu.add(0, SettingsId, 0, "Settings");
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item)
{
switch (item.getItemId())
{
case SettingsId:
startActivity(new Intent(this, PreferenceServerActivity.class));
return true;
default:
return false;
}
}
Intent filter in your manifest from tutorial just says, that this activity can be opened from system settings when user browse data usage of your app.
I created a base activity that has a menu, this menu will open other activities in the application.
public class BaseActivity extends Activity{
#Override
protected void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
//Intent i = new Intent("com.app.Activity1");
//startActivity(i);
}
#Override
public boolean onCreateOptionsMenu(Menu menu){
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.menu, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.icon: Intent i1 = new Intent("com.app.Activity1");
startActivity(i1);
break;
case R.id.text: Intent i2 = new Intent("com.app.Activity2");
startActivity(i2);
break;
case R.id.icontext: Intent i3 = new Intent("com.app.Activity3");
startActivity(i2);
break;
}
return true;
}
}
All activities extend this base activity, so when you press the menu button, the menu pops up and you can select an activity.
However, lets say I use the menu to go to activity A. Once I'm in activity A I can use the menu to go to Activity A again. I can do this X times, but now the back button will go back to the same activity X times.
How can I tell if the activity is already running so a user can't keep opening the same activity?
Or rather, would you suggest I disable the menu item once in activity A?
Thanks for your input. Sorry if this seems like a trivial question.
There is a simple solution to this. You want to disable the menu item for the current activity in onPrepareOptionsMenu() in your BaseActivity like this:
#Override
public boolean onPrepareOptionsMenu(Menu menu) {
// Determine what activity I am and find the menu item for that activity
MenuItem menuItem = null;
if (getClass().equals(com.app.Activity1.class)) {
menuItem = menu.findItem(R.id.icon);
} else if (getClass().equals(com.app.Activity2.class)) {
menuItem = menu.findItem(R.id.text);
} else if (getClass().equals(com.app.Activity3.class)) {
menuItem = menu.findItem(R.id.icontext);
}
// Disable this menu item
if (menuItem != null) {
menuItem.setEnabled(false); // Make it non-selectable (even with shortcut)
menuItem.setVisible(false); // Make it non-visible
}
return true;
}
I think u need not to do that.I think you just appoint your activity's launchMode="singleTask".Code in your AndroidManifest.xml:
<activity android:name=".com.app.Activity1" android:launchMode="singleTask" android:configChanges="orientation|keyboardHidden" android:screenOrientation="portrait"></activity>
<activity android:name=".com.app.Activity2" android:launchMode="singleTask" android:configChanges="orientation|keyboardHidden" android:screenOrientation="portrait"></activity>
<activity android:name=".com.app.Activity3" android:launchMode="singleTask" android:configChanges="orientation|keyboardHidden" android:screenOrientation="portrait"></activity>
^-^
Kind of a trivial solution - why not have a global int in your baseActivity called 'int choice'? When you switch to an activity just set choice to that activity. For example
case R.id.icon:
if (choice != 1){
startActivity(i1);
choice = 1;
}
break;
You can implement this in two ways:
To call activity A from activity A, call it with flag as FLAG_ACTIVITY_REORDER_TO_FRONT, so A will be called again without creating a new instance, so goin back will not create any problem.
As you said, disable the menu item for activity A if activity A is in front.