I have two activities, Activity1 and Activity2. Activity1 is launcher activity which starts at the beginning. Now when I'm pressing Home button from activity2 and again opening the app from all apps then Activity1 is opening. I want to open the same activity that was opened at the time of pressing the home button. I need to save state of activity2, but how I don't have any clue.
I looked at this and this but still I didn't got the clear picture on how to do this. Please help me as I'm new to android.
When you pressed "home" button, your activity goes to onPause().
So I personally recommend you to override the onPause() method which can not only handle the "home" button pressed but also other circumstances.
In your case, it is only onPause() and onResume() related, so you can try put the state into SharedPreferences or Internal/External storage.
say:
in your onPause() method, do something like:
// Use Shared Preferences to save data
SharedPreferences previewSizePref = getSharedPreferences("PREF",MODE_PRIVATE);
SharedPreferences.Editor prefEditor = previewSizePref.edit();
prefEditor.putInt("x", somethingA);
prefEditor.putInt("y", somethingB);
prefEditor.commit();
and in your onResume(), retrieve the saved data like:
SharedPreferences previewSizePref = getSharedPreferences("PREF",MODE_PRIVATE);
if (previewSizePref.contains("x") && previewSizePref.contains("y")) {
//your saved data exists, do something
} else {
// handle the circumstances that the saved data doesn't exist
}
For saving state in onPause() and restore in onResume() you can have a look at this answer:
Saving Activity State in the onPause
And for SharedPreferences, you can have a look at API document: Data Storage - Shared Preferences
What you're describing should be standard for behaviour for Android, and if it isn't doing what you describe then you've probably overwritten this behaviour somewhere else, probably in your manifest.
If you create a new Android application and make a simple two page app, with Activity A as the launcher and Activity B as the second page, then your manifest will look like the following and the app will display the behaviour you describe.
<application
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name=".ActivityA"
android:label="#string/title_activity_main" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".ActivityB"
android:label="#string/title_activity_main" >
</activity>
</application>
Double check that your manifest looks similar to this- Activity B has no flags and is just a declaration that it exists in your manifest.
Related
i'm developing a basic app that has four activities. The first two Activities have textviews that are reseted when the back button is pressed. here's the manifest
<activity android:name=".MainActivity"
android:alwaysRetainTaskState="true"
android:launchMode="singleInstance">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".ContactActivity" />
<activity android:name=".Page2Activity"
android:alwaysRetainTaskState="true"
android:launchMode="singleInstance"/>
<activity android:name=".FinalActivity"></activity>
I've also used the android:freezesText="true" but it doesnt help
I didnt write any android programs. But you should try android:alwaysRetainTaskState:"false"
Whether or not the state of the task that the activity is in will always be maintained by the system — " true " if it will be, and " false " if the system is allowed to reset the task to its initial state in certain situations.
Your solution may be saving the data in string form and repopulating your object on resume. You would save the data in onPause() and repopulate in onResume().
I will show you how to do that with a SharedPreference. SharedPreferences are an easy way to save strings, integers, lists, and other objects, without a database in android.
//This code will save a string. The first parameter in putString() is the key. The second is the value
SharedPreferences.Editor editor = getSharedPreferences("myPrefs", MODE_PRIVATE).edit();
editor.putString("myTextviewText", "Hello World");
//Save the data
editor.apply();
//This code will retrieve the String. You can run this code and retrieve the value even if the app was killed
SharedPreferences prefs = getSharedPreferences("myPrefs", MODE_PRIVATE);
String restoredText = prefs.getString("myTextViewText", "default");
You can override onPause and in there use the first part of the code to save what you want in your textview. I'm onResume use the second part to retrieve the string and then edit the textview text with the restored text. To hold serveral values just use a different key to set and get data.
SharedPreferences will save when the app is stopped. They act like a database but with less maintenance.
I try to add welcome tutorial for users that install application for the first time. That activity need to be declare as Main in Manifest (or I miss something?). But if I choose any other activity else than main one (which is actual app), app shortcuts (Android 7.1) doesn't work anymore. It's interesting however that shortcuts are still available at custom launchers (Apex, Nova). Any idea?
(almost all) Google apps has welcome tutorial as well as launcher shortcuts. I can't get it how they did it?
A welcome tutorial does not have to be an activity. It could be some other sort of presentation (e.g., a fragment).
A welcome tutorial, even if it is another activity, does not have to be the launcher activity. The launcher activity could detect that it is the first run and started the tutorial activity.
Thank you for the answers CommonWare! Your statements helps me to find answer. So, I want to start an app which shows Splash screen, then Welcome tutorial. Also, app need working shortcuts on main screen as well as only one launcher icon. So, first, I declare Splash screen as main in Manifest.xml:
<activity
android:name=".SplashActivity"
android:noHistory="true"
android:theme="#style/SplashTheme">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<meta-data
android:name="android.app.shortcuts"
android:resource="#xml/shortcuts" />
</activity>
Then, Welcome (tutorial) activity:
<activity
android:name=".IntroActivity.WelcomeActivity"/>
After that, in SplashActivity.class checking first launch:
public static final String FIRST_APP_LAUNCH = "com.ips.test";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (isFirstAppLaunch()) {
setFirstAppLaunch(false);
startActivity(new Intent(this, WelcomeActivity.class));
} else {
startActivity(new Intent(this, MainActivity.class));
}
finish();
}
private boolean isFirstAppLaunch() {
SharedPreferences preferences = this.getPreferences(Context.MODE_PRIVATE);
return preferences.getBoolean(FIRST_APP_LAUNCH, true);
}
private void setFirstAppLaunch(boolean value) {
SharedPreferences preferences = this.getPreferences(Context.MODE_PRIVATE);
SharedPreferences.Editor editor = preferences.edit();
editor.putBoolean(FIRST_APP_LAUNCH, value);
editor.apply();
}
}
Final result is as I wanted: app launch with Splash screen, then it runs Welcome tutorial. Next start will trigger Splash screen which will continue to main activity (app itself). When user click on shortcut in main screen it will get shortcuts, and in Launcher it will have just one application shortcut.
I have a problem with resume Activity. I have a MainActivity which contains other activities. Each one contains a radio station. I have a button (Play) in each activity, and when the user clicks on it, the button changes its function to Stop, so it turns to Stop button. My problem is that when I go for example from Activity(B) to MainActivity and then return to Activity(B) instead of the Stop button, it shows again the Play button, and if the button is pressed, the player plays the same station again at the same moment. I tried to resume the activity using flag, but that didn't work.
My code looks like this:
if (position == 3) {
Intent intent = new Intent(RadioActivity.this, Taraf.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP|Intent.FLAG_ACTIVITY_SINGLE_TOP);
startActivity(intent);
}
And the manifest looks like this:
<activity
android:name=".SettingsActivity"
android:launchMode="singleTop"
android:screenOrientation="portrait">
</activity>
<activity
android:name=".MainActivity"
android:label="#string/app_name"
android:launchMode="singleTop">
</activity>
You should save the status of your button in sharedPreferences, and retrive it when you return to Activity(B), then reset your button according to status of the button saved in sharedpreferences.You can refer to this documentation.
you have to save the state somewhere whether in shared preferences or any other storage.
An d when you are returning to your activity you can retrieve this data.
Hi I have 2 activities,
Activity A and Activity B,
So its Activity A and on a Button click I go to Activity B.
Now I press home button and go and do somany other things. Because of memory issue the task is closed by android. Now when I try to open it again it starts from Activity B. Is this expected?
If yes is there a way to prevent it?
Below is the part of AndroidManifest where both activities are defined
Activity A = MenuActivity, Activity B = AndroidLauncher
<activity
android:name=".AndroidLauncher"
android:configChanges="keyboard|keyboardHidden|orientation|screenSize"
android:label="#string/app_name"
android:finishOnTaskLaunch="true"
android:screenOrientation="portrait" >
</activity>
<activity
android:name=".MenuActivity"
android:clearTaskOnLaunch="true"
android:screenOrientation="portrait" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
Also I am putting the code of onCreate of Activity B
protected void onCreate (Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.game_view);
AndroidApplicationConfiguration config = new AndroidApplicationConfiguration();
int gameType = getIntent().getIntExtra("GAME_TYPE", 0);
GDXtoAndroidInterface.sharedInstance().activity = this;
TurnBasedHelper.sharedInstance().listener = this;
FrameLayout lg=(FrameLayout)findViewById(R.id.layout);
lg.addView(initializeForView(new LetterPress(GDXtoAndroidInterface.sharedInstance(),gameType), config));
busyDialog = new ProgressDialog(this);
busyDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
busyDialog.setCanceledOnTouchOutside(false);
busyDialog.setCancelable(false);
showBusy("Setting up..");
Log.d("MSG", "on create called launcher");
}
Also the reason why I need this is Activity A is like a login screen and Activity B is based on it. Activity B cannot work alone. User has to move from Activity A to Activity B
Thanks
when I try to open it again it starts from Activity B. Is this expected?
yes, this is the expected behavior.
when you press the home button (not the "back button") the entire task is sent by default to background, and when re-launching it (from recent tasks screen or the app icon at the home screen) it coming back by default to foreground with the same stack state as it was. same behavior applies also if your app was killed by the system while it was in background to preserve memory. the operating system will store the state of each activity in the stack, an restore it when it need to re-created (see this post)
you can think of the home button in relation to Activity like the relation in Windows OS terms as the "minimize" window button, and back button would be like the "close window" (x) button.
there a way to prevent it?
assuming you have good reason to do so and break this consistence expected behavior, you can use all kind of combinations between activity launch mode and intent flags that will give you the behavior you want..
I am developing simple application with only two activities.
Activity C configures application
Activity A for interaction with user when some event occur
It is not possible for user to navigate from the one to the other - this is why I call them independent activities. Further more activity A is being invoked only form event, there is no way for user to do it manually.
Problem. Let's assume that application is properly configured. Some event occurs in the system, so application A is being shown to the user. The user interact with it and activity goes to background. Then the user decides to launch configuration activity C. Activity C is shown to the user. The user uses back button to "close" activity, but instead of android launcher or desktop the user is being shown activity A (taken from history).
Similar scenario might happen the other way. C is being used by user, then taken to background. Some event shows activity A and user using back button goes to C instead of closing activity A.
I have solved the problem, but the solution is pretty dirty. Is there any clean or standard way of solving such problem?
Part of my solution includes what was suggested in one answer:
snippet from AndroidManifest.xml:
<activity
android:name=".C"
android:clearTaskOnLaunch="true"
android:excludeFromRecents="false"
android:launchMode="singleTask"
...
>
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:exported="false"
android:name=".A"
android:excludeFromRecents="true"
android:noHistory="true"
android:launchMode="singleInstance"
android:clearTaskOnLaunch="true"
....
>
</activity>
snippet from activity A:
public boolean onKeyUp(final int p_keyCode, final KeyEvent p_event) {
switch(p_keyCode) {
case KeyEvent.KEYCODE_ENDCALL:
case KeyEvent.KEYCODE_HOME:
case KeyEvent.KEYCODE_BACK:
case KeyEvent.KEYCODE_MUTE:
case KeyEvent.KEYCODE_POWER:
this.finish();
break;
....
}
return super.onKeyUp(p_keyCode, p_event);
}
snipped from event handler:
public class H extends BroadcastReceiver {
...
Intent intent = new Intent(p_context, A.class);
intent.addFlags(Intent.FLAG_FROM_BACKGROUND);
intent.addFlags(Intent.FLAG_ACTIVITY_NO_USER_ACTION);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
p_context.startActivity(intent);
...
}
It works for my application. However I want application (activity C) to appear in Recent application. But once activity A is invoked application is removed from Recent.
I don't know if this is the cleanest way to do this, but you can override the void onBackPressed() activity method. This way you can mannually move your activity to the background, like this, and prevent the previous activity from popping in:
public void onBackPressed () {
moveTaskToBack (true);
}
Edit: Turns out there's a better way to do this:
Open your AndroidManifest.xml, and inside each declaration put the following: `android:noHistory="true"``. Doing so will tell Android that your activity does not leave a history, and therefore, when the user hits back Android will quit the application, since there's no other activity for it to return to.