Application restart and activity hiding - android

I have application with two activities: SplashActivity and MainActivity. SplashActivity is the launch activity, it start for few seconds, close and launch MainActivity. MainActivity contains all application logic.
When user minimize application by Home button, then doesn't using application some time and maximize it again, data in my application is expired and I need to restart application. I make it with onStart in MainActivity:
#Override
public void onStart() {
super.onStart();
if (dataIsExpired()) {
finish();
Intent intent = getBaseContext().getPackageManager().getLaunchIntentForPackage(getBaseContext().getPackageName());
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
}
}
It working well, but before SplashActivity launched I see MainActivity with old data for few moments. Is there way to restart without previous activity showing?
I don't need to clear it manually, I just need to restart whole app.

You can call finish() your activity in onPause() or onStop() of MainActivity so that it will be removed when minimising the app and will launch fresh.

Related

startActivity in onPause() not working after opening new app

I Start a second activity when my first activity is paused.
FirstActivity.java
#Override
public void onPause(){
super.onPause();
startActivity(new Intent(this, SecondActivity.class));
}
When I press on the homescreen button, SecondActivity will start but with a delay. In this delay, there is enough time to open a new app (like messenger for instance). However, when I open a new app, SecondActivity will not start anymore (it won't even call the onCreate method of SecondActivity).
How can i still start SecondActivity even when I open a new app?
Override the onBackPressed() method and start new activity from there, instead of adding your code into onPause().
#Override
public void onBackPressed()
{
startActivity(new Intent(this, SecondActivity.class));
super.onBackPressed();
}
I think I have a solution, if you would like to launch the new activity I would go with onStop, instead of onPause.
Start the new activity with the flag of: singleInstance
<activity ..
android:launchMode= "singleInstance" />
Please use onStop() in the second activity and call finish() there. so you killing the 2nd activity instance, when leaving the app. You can restart it easily.

How to restart app again when user exit from application

Hi in my code when user press back button from mainactivity he/she exit from the application but problem is when user again press application icon it resume the mainactivity where i left it..... i want to restart my app again when user click on application icon. Thanks in advance
///exit from app by pressing back button
public void onBackPressed() {
Log.i("HA", "Finishing");
Intent intent = new Intent(Intent.ACTION_MAIN);
intent.addCategory(Intent.CATEGORY_HOME);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
}
}
You need this
public static final int FLAG_ACTIVITY_CLEAR_TASK
Added in API level 11
If set in an Intent passed to Context.startActivity(), this flag will cause any existing task that would be associated with the activity to be cleared before the activity is started. That is, the activity becomes the new root of an otherwise empty task, and any old activities are finished.
You should look here
There are three options:
1.You can override onResume() and put whatever is there in your onCreate() method inside it to do fresh restart everytime..
2.You can override onPause and kill the activity
onStop(); onCreate(getIntent().getExtras());
3.The best approach:
Alternatively you can also use http://developer.android.com/reference/android/content/Intent.html#FLAG_ACTIVITY_NO_HISTORY so that your activity is restarted everytime.
public static final int FLAG_ACTIVITY_NO_HISTORY
Added in API level 1 If set, the new activity is not kept in the
history stack. As soon as the user navigates away from it, the
activity is finished. This may also be set with the noHistory
attribute.
Constant Value: 1073741824 (0x40000000)

clear Activity Stack when user Logs in

There are a lot of topics on this post. But i couldn't find a solution to my problem.
Let me describe my activity stack first.
SplashScreen->A->Login->Home.
What i would like to achieve is , when i click on back button after logging in to Home, i should come out of the application and go to Home if i use my application again. For this i am assuming i should clear the activity stack before Home, after i login. I would also like to preserve the activity stack if the user hasn't logged in yet.
I want this to work on or after 2.1
What i have tried already.
using finish() in Login Activity , before calling startActivity on Home. This will redirect me to A , if i use back button on Home.
All variations of FLAG_ACTIVITY_NEW_TASK and FLAG_ACTIVITY_CLEAR_TOP . Nothing worked, when i use back button, i am redirected to login screen.
Any suggestions or simple solution to achieve this?
using finish() in Login Activity , before calling startActivity on Home. This will redirect me to A , if i use back button on Home.
ok so use finish on all the activities that you want them to be popped before calling startActivity
go to Home if i use my application again
Simply save your login parameters in SharedPreference and from A startActivity Home directly if login successful.
You can also try to make use of BroadcastReceiver aswell if you want to try that route.
In your "SplashScreen" and "A" activities, in the onCreate method you can create and register and IntentFilter and a BroadcastReceiver like so:
Assuming you have a global variable called broadcastReceiver
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction("ACTION_LOGIN");
this.broadcastReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
finish();
}
};
registerReceiver(broadcastReceiver, intentFilter);
Also don't forget to unregister your receiver in the onDestroy method (this is to prevent memory leaks in the program):
#Override
protected void onDestroy() {
unregisterReceiver(this.broadcastReceiver);
super.onDestroy();
}
Now in your "Login" activity, once the user has successfully logged in, you can broadcast a message to all the registered receivers, which will finish those activites in the back stack:
Intent broadcastIntent = new Intent();
broadcastIntent.setAction("ACTION_LOGIN");
sendBroadcast(broadcastIntent);
Your SplashScreen and A activities will now be finished.

Notification to restore a task rather than a specific activity?

I have a foreground service that keeps a connection open with the server as long as the user is logged into the application. This is so that the connection is kept alive and can receive messages directly from the server even when the application has been sent into the background by the user pressing Home.
The application has a number of Activities, any of which could be the active one when it is sent into the background.
I would like to allow the user to click on the notification to restore the current Activity. I understand how to restore a particular activity, but wondered if there is a way to restore the last Activity that the user was on? Of course I could keep track of the the last one, and then call that from the Notification callback, but thought there might be a way at a task level?
Thanks for any advice you can offer.
What you need is just a simple Activity that does nothing. Here is an example:
public class NotificationActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Now finish, which will drop the user in to the activity that was at the top
// of the task stack
finish();
}
}
Set up your notification to start this activity. Make sure that in the manifest the task affinity of this activity is the same as the task affinity of the other activities in your application (by default it is, if you haven't explicitly set android:taskAffinity).
When the user selects this notification, if your application is running, then the NotificationActivity will be started on top of the topmost activity in your application's task and that task will be brought to the foreground. When the NotificationActivity finishes, it will simply return the user to the topmost activity in your application (ie: wherever the user left it when it went into the background).
This won't work if your application isn't already running. However, you have 2 options to deal with that:
Make sure the notification isn't present in the notification bar when your application is not running.
In the onCreate() method of the NotificationActivity, check if your application is running, and if it isn't running call startActivity() and launch your application. If you do this, be sure to set the flag Intent.FLAG_ACTIVITY_NEW_TASK when starting the application so that the root activity of the task is not NotificationActivity.
Works very well, thanks David! The following class checks if the application is already running and if not, starts it before finishing (as suggested by David in option 2).
public class NotificationActivity extends Activity
{
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
// If this activity is the root activity of the task, the app is not running
if (isTaskRoot())
{
// Start the app before finishing
Intent startAppIntent = new Intent(getApplicationContext(), MainActivity.class);
startAppIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(startAppIntent);
}
finish();
}
}
There is a simpler solution that does not require the extra activity. See this post for details. Basically, the notification starts the (possibly existing) task the same way it is started when you click the launcher icon while the app ist in the background.
My solution, which emulates the behaviour of the launcher (bringing up the task to the foreground):
Intent intent = new Intent(Intent.ACTION_MAIN);
intent.addCategory(Intent.CATEGORY_LAUNCHER);
intent.setClassName(MyApplication.class.getPackage().getName(), MainActivity.class.getName());
Intent intent = new Intent(Intent.ACTION_MAIN);
intent.addCategory(Intent.CATEGORY_LAUNCHER);
This works, no doubts about it but the problem is when you set your intent as ACTION_MAIN. Then you will not be able to set any bundle to the intent. I mean, your primitive data will not be received from the target activity because ACTION_MAIN can not contain any extra data.
Instead of this, you can just set your activities as singleTask and call your intent normally without setting ACTION_MAIN and receive the intent from onNewIntent() method of your target activity.
But be aware if you call, super.onNewIntent(intent); then a second instance of the activity will be created. Just don't call super method.
I combined David Wasser's and Raginmari's solution by doing that approach to the root activity of your app then it will work for both cases when your app was already started or haven't been started.
public class YourRootActivity extends Activity
{
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
if (!isTaskRoot()) // checks if this root activity is at root, if not, we presented it from notification and we are resuming the app from previous open state
{
val extras = intent.extras // do stuffs with extras.
finish();
return;
}
// OtherWise start the app as usual
}
}

Relaunch app from intent

I would like to put a notification with an intent.
My intent is basically action = DEFAULT and category = LAUNCHER in order to bring the activity that was launched into the front.
When the app is not shown, there is no problem, the intent works perfectly and launches the last activity seen but when there is already an activity launched, onNewIntent is not called (activity is in singleTop mode).
I'm wondering how to relaunch the app from an intent to the last activity seen and call onNewIntent when the activity is already launched.
the problem is that your activity is defined as
android:launchMode="singleTop"
when there is already an activity
launched, onNewIntent is not called
implement the onDestroy method::
#Override
public void onDestroy(){
super.onDestroy();
}

Categories

Resources