What I want to do is to start an Activity upon device restarts by sending an intent in a BroadCastReceiver listening BOOT_COMPLETED event. The Activity has a conditional moveTaskToBack in its onCreate event handler. The Activity is launchable and the only Activity of App.
When I reboot the device, App is running and I can tell Activity is hidden from screen. From logcat a 'onCreate' message is print to indicate onCreate event happens. Then I click App icon in screen, expect Activity shows up from back for onCreate shall be omitted and moveTaskToBack shall NOT run. But onCreate event handler is still executed and Activity hides again.
In another way I remove starting Activity from BroadCastReceiver, just open App by click icon in screen. At first tap App starts running and Activity hides, and when I tap icon again, the Activity shows up. From logcat the first event is onRestart, which is expected.
I am not sure what is the different between two ways of bring back Activity? Why onCreate happens twice applying BroadcastReceiver in first case?
Cheers!
I'm now aware that the activity started by broadcast receiver is in a stack, while the activity, which is as same class, started by launcher is in another stack. Thus why onCreate event happened again when I tapped App icon desktop, for App create a new stack and brand-new activity.
Thanks xvlcw for great help...
Related
There is a developer option in android-Destroy Activity as soon as user leave it.
So When i check that activity and run my launcher activity having single top flag.I have seen that both my onCreate and OnNewIntent was called when I launch app after pressing Home Button.
Can Anyone explain that why both the functions was been called and also It was called only for my launcher activity .Rest all activities were working fine.
I am calling one activity on click of status bar notification which is having a Complete button. on click of btn. i have folllowing code -
public void completeTask(){
taskDBAdapter.deleteReminder(rowId);
taskDBAdapter.close();
Intent intent = new Intent(this, TaskManagerActivity.class);
startActivity(intent);
finish();
}
whhen i click complete btn new activity (TaskManagerActivity) gets opened properly.But if i reopen my application it still tries to open this activity and not my default landing activity. Any help on this.??
EDIT -
I have tried repositioning my finish() statement . Still its not working.
EDIT 1.1 -
Ok I will provide some details here. Assume my app has two activities
Main Activity
Notification Activity
My app create some notification to display on Status bar. So as soon as i click on status bar Notification actvty will open. Now there is a button called Complete on click of which the code given will fire and main activity (in the code TaskManagerActivity.class) will open. But after I press back button in my app and again reopen it , it opens the notification activity when it should have fired the main activity (as it is launching activity).
Thanks,
Ray
That's the default way android functions. If you press the home button and then open your app again, it will restore the apps previous state (unless it has killed the apps processes and activities due to memory constraints). So you are not actually restarting your app but only restoring it.
If you wanna quit the app, then press the back button. Now when you re-open the app, the original activity will be launched.
Do not modify this behavior. It is the default system behavior and users expect it to work this way. Your app is fine :-)
- First of all the behavior which you are experiencing is the way Android is made to function, moreover when a user gets a call while this app is open, after finishing the app he will definitely want to get back to the state where he left the application.
Still if you want it that way, here it is.....
- Make sure your application has only single instance of it running, by using android:launchMode="singleTask", or android:launchMode="singleInstance"
- Then finish() your Activity at onPause().
#Override
void onPause()
{
super.onPause();
finish();
}
I have a home screen widget with a button with a pendingIntent. Click it, it bundles a boolean to indicate where it came from and it brings up my main activity.
In my main activity in onCreate, I check for a bundle, if the boolean that says it was launched from my widget is true, I perform an action.
Every time I hit my widget button, it should launch my main activity, and run through onCreate.
And it does, on the emulator. And it did, on my n1. Then suddenly it stopped on my n1. I can still get it to hit onCreate when I launch from the widget but I have force stop or reinstall and then it only does it the first time.
What is going on with this?
What's going on is the Activity lifecycle. Android will keep the same instance of your Activity around so that the user can return to it later. Monitor some of the other lifecycle methods like onStart and onResume to see this in action.
You may see a difference in behavior if the user hits the back button vs. the home button. The back button will finish the current Activity by default, whereas home will leave it alone unless Android decides to kill it for resources later.
I already know that I can pass Bundled data through setResult from one Activity back to another. However, suppose I have an global Activity that can be launched from anywhere in my app since it is mapped to a button that appears in my title bar in almost all of my activities.
Long story short, after it completes its user-driven process, I want it to signal back to the very first activity in the back stack, basically my Home activity, so that it updates the UI accordingly.
Part of the problem is that since if I use a BroadcastReceiver, it is unregistered when my activity is in the background, and it will not get the signal to refresh its data set.
What I want to achieve is the following:
From either Home (ActivityA), or any other activity (Activity B, C, etc...) that can open out my global activity (ActivityX), it should find a way to call back to ActivityA without bringing it to the front.
Should I use FLAG_ACTIVITY_FORWARD_RESULT and if so, how should I model it from my subsequent activities after Home. In other words, if I launch a child activity from Home, should I launch it with startActivityForResult with whatever request code I define and then pass FLAG_ACTIVITY_FORWARD_RESULT when opening my global activity so that the result will be set from there?
Also, suppose I launch a child activity from Home with a result, and then from my child activity I add more to the stack, from which I open ActivityX. Would the system still remember the result chain as long as I opened the first child from Home with a result?
EDIT: I am not looking for just clearing the entire stack back to home immediately after the process is completed in ActivityX; just a way to signal the Home activity to refresh it's UI when the user eventually returns to the Home screen. I guess probably setting a SharedPreference flag that Home checks in onStart when the user re-focuses on that Activity which in turn gives me the condition to do the end result, after which the flag is reset.
Your home-screen should just update it's UI in onResume, this way whenever a user returns to it will be displaying the latest data. There's no need to pass callbacks. Otherwise you could register a Broadcast receiver in onCreate (and unregister in onDestroy... not ideal) in your home activity and then send out a broadcast when you want the home activity to update (although the home activity shouldn't actually update itself until it is resumed).
Here's how to get back to your home activity:
Intent goHome = new Intent(getContext(), HomeActivity.class);
goHome.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
goHome.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(goHome);
FLAG_ACTIVITY_CLEAR_TOP: This ensures that when the activity is launched, it displays its initial activity.
FLAG_ACTIVITY_NEW_TASK: we're starting a new task (i.e. the back button should not go back to the previous screen so that pressing back at your home screen will exit your app).
I'll update on the rest tomorrow.
In one of my services I fire an event that puts a notification in the status bar which includes a pending intent to start an activity when the user clicks the notification.
The activity I'm starting is actually a "popup" that has the theme of a dialog popup (android:theme="#android:style/Theme.Dialog") defined in the manifest. The code for the pending intent is below:
Intent intent = new Intent(this, PopupWindow.class);
PendingIntent launchIntent = PendingIntent.getActivity(context, 0 , intent, 0);
notificationManager.notify(notificationRef, notification);
Everything works fine in android 2.2, but when testing in android 2.1, the newly started popup window doesn't take focus on the screen.
I know the activity is starting, because if I hold the home button down to bring up recently started apps, the "popup" will magically appear and takes focus.
Is there something I'm missing here? Why does my code work in android 2.2 and not 2.1?
After a day of debugging, I found that the new activity launched from the pending intent (Activity B in the stack) would get lost somewhere in the ActivityManager behind either the already opened activity (Activity A) or possibly the window of recently opened apps (long press on home key).
This happened ONLY if navigated away from Activity A with the use of a long-press on the home key ONLY in versions of android < 2.1. Every other instance of navigating away from Activity A (home key short-press, back-key press) would allow the pending intent on Activity B to open and take focus above everything on the screen. In android 2.2 and above, the code works absolutely fine with no issues. Very weird. To make things even weirder, if I put a Toast message to be displayed within the onRestart method of Activity A, the issue completely disappeared. There is nothing weird going on inside the onPause method of Activity A either....I still don't know.
I tried almost all flags on the pending intent for Activity B, but none of them would allow the popup to get to the top of the activity stack....I think Nanne and willytate put me on the right track...
I abandoned the method of setting the pending intent inside of a service, I think it was breaking the affinity between Activity A and Activity B. When I set the pending intent for Activity B inside of Activity A, as apposed to inside the service running in the background, Activity B (in the form of a popup via android:theme="#android:style/Theme.Dialog" in the manifest) would always appear at the top of the stack.
Once again, this "loss of focus" on an activity has only ever happened to me in this process:
Android 2.1
Launch Activity A
Use service to set status bar notification with a pending intent to start Activity B
Navigate away from Activity with long press on home key to any other application.
Service fires notification in status bar with intent to start Activity B.
Click notification to open Activity B.
Activity B, created as a dialog, is no where to be found and Activity A comes to the stop of the stack, but remains paused. No response to user touch at all on Activity A and the timer being displayed isn't moving. The Activity is stuck in onPause maybe?
The only way to get Activity B to appear is to, once again, long press the home key. When this is done, I see the following on the screen, in descending order with the first as the one at the top of the stack ready for user input :
List of recently used apps.
Activity B.
Acitivyt A.
Pressing the back button to dismiss the list of recently used apps will allow Activity B to take user input, and from there everything runs normally.
If this was not a complete waste of time, I did get a much better understanding on how Android handles the application stack.
Can anyone else (if they really wanted to) re-create this issue?