The constructor of a pending intent needs an Intent object in it from the current context to the next activity. In my app, I have only a single activity containing multiple Views. No Second Activity.
The Views are Destroyed or made visible on demand. Obviously I cannot add a View to the constructor of an intent. So how shall I direct the pending intent? Multiple views have been accommodated into the main.xml using the <include/> command.
This is very easy to accomplish. mvnpavan already gave you good hint, you just need to do some additional work. First of all you should get familiar with this page http://developer.android.com/guide/components/tasks-and-back-stack.html.
It explains how to manage your application tasks and back stack. In your case you have 2 options:
1.Configure launchMode property of Activity in manifest. Setting singleTop should do the job since your are using just one activity.
<activity
android:name="com.yourpackage.YourClass"
android:launchMode="singleTop">
</activity>
2.Add flag FLAG_ACTIVITY_SINGLE_TOP to your Intent(the one you are passing to PendingIntent):
Intent intent = new Intent(this, YourActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
Please note that in both cases you can implement callback method of you activity onNewIntent(). Use it in case you wish to do some extra work when app is bring back to the foreground.
Update:
Regards keeping connection to the server I would use Service, not Activity. Then you can do whatever you like with your activity. This is the best practise. If you worry that Activity has no direct access to the Service API, you can bind to that Service. Have a look at this page http://developer.android.com/guide/components/bound-services.html You can just copy/paste the code and your are done. It's very easy to maintain. In the future you may need to create another activity which require connection to the server. It will save you a lot of time and headaches :).
Use pending intent to resume your application and not recreate it like this:
Intent i = new Intent(this, youractivity.class);
pIntent = PendingIntent.getActivity(this, 0, i, PendingIntent.FLAG_UPDATE_CURRENT);
Hope it helps! ;)
Related
My app and activity is in my list of recent apps when I receive a notification. When I click on the notification, I want the intent of the notification to be honored. In my case I want to restart the activity (brute force) and pass in the new intent: so, finish then re-create. I am reading about such tags as FLAG_ACTIVITY_NEW_TASK and FLAG_ACTIVITY_SINGLE_TOP but I don't understand them enough to know how to force a "finish then re-create` of my activity. And, oh, the activity in question is MainActivity.
The snippet inside GcmListenerService uses
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
for sending the notification intent
Alternatively
If I go with onNewIntent things get complicated because there maybe DialogFragments being displayed, etc. And I would have to clear everything. That is why finish then re-create seem like the simplest solution to me.
Intent flag FLAG_ACTIVITY_CLEAR_TOP should produce the desired behavior. The documentation for Tasks and Back Stack says this in the section for Using Intent Flags:
If the launch mode of the designated activity is "standard", it too is
removed from the stack and a new instance is launched in its place to
handle the incoming intent. That's because a new instance is always
created for a new intent when the launch mode is "standard".
The documentation for FLAG_ACTIVITY_CLEAR_TOP describes the same behavior in more detail.
I'm setting up Notifications in my app and I've noticed whilst testing, after clicking a new notifications (in this case the notification loads a blog details page), I have many instances of the blog details activity running (pressing back it shows each activity with the previously loaded blogs).
Is it possible in my Receiver class, so look if there is any instance of ActivityBlog already running, and if there all .finish() them all so there is only ever once instance running?
I found this but I couldn't work out a way to do it from that.
You should study activity launch modes
http://developer.android.com/guide/topics/manifest/activity-element.html#lmode
Use android:launchMode="singleTop" in element in manifest file.
You will get callback in onNewIntent() if an instance of activity is already up. Stack of your activities will be automatically updated and there wont be any need of killing activities which is consumes time and resources.
This i believe is the recommended approach.
Intent z = new Intent(Projects_Accel.this,MainActivity.class);
z.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP |
Intent.FLAG_ACTIVITY_CLEAR_TASK |
Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(z);
use this for kill all activity
Do this way
Intent intent = new Intent(this, ActivityBlog.class);
ComponentName cn = intent.getComponent();
Intent mainIntent = IntentCompat.makeRestartActivityTask(cn);
activity.startActivity(mainIntent);
NOTE:
You need to put android-support.jar in libs folder
Is there a way to set parameters that they would receive as arguments in the constructor were they initialized as standard objects instead of by intents? I can't use parameters stored in the intent because sending an intent doesn't necessarily initialize the activity / service (it may exist already). Can I use the manifest file to set custom parameters?
Thanks.
Starting an Activity will always start activity, and if activity is already in stack, then also it would launch the activity, unless some intent filter havent been specified.
For Service, if you start service by startService(), onStartCommand() method will be invoked, which has an Intent as parameter, you can get values passed from this parameter.
sending an intent doesn't necessarily initialize the activity / service(it may exist already).
What if you keep using Intents but erase the history of the TargetActivity each time you call it.
Intent intent = new Intent(this,TargetActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
I found a possible solution here: Is it possible to have custom attributes in AndroidManifest.xml tags?
Doesn't help if I want to pass objects, but for simple types it's good enough.
is it possible to start multiple activities at once? I mean, from main create 3 activities in some order and just the last will be visible? Up to now, I was able to create only one activity.
Thanks
You might need something like this in order to launch deep into the app after the user has clicked a notification in order to display some newly added content, for example.
Intent i = new Intent(this, A.class);
i.setFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
startActivity(i);
Intent j = new Intent(this, B.class);
j.setFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
startActivity(j);
Intent k = new Intent(this, C.class);
startActivity(k);
In this way you can start activities A, B and C at the same time and suppress transitions to activities A and B. You get a single transition from your current activity to activity C. I strongly suggest that you log the Activity lifecycle method calls (onCreate etc.) to LogCat, for example. It helps a lot in understanding the order of events.
This can be a common thing to do in response to deep linking or other use cases where you, basically, need to synthetically rebuild the Task (and all the activities it should contain). Sometimes, just specifying parents in the manifest isn't enough.
Take a look at TaskStackBuilder. One common example:
TaskStackBuilder.create( context )
.addNextIntent( intentOnBottom )
// use this method if you want "intentOnTop" to have it's parent chain of activities added to the stack. Otherwise, more "addNextIntent" calls will do.
.addNextIntentWithParentStack( intentOnTop )
.startActivities();
Really old question but I thought I still answer it.
Use:
public void startActivities (Intent[] intents, Bundle options)
Try startActivity(new Intent(...); at the end of your onCreate-Method of the first Activity.
This will immediatly launch a new Activity and pause the first one.
With back-key you will get back to the last Activity
I am intercepting sms messages with some information in them. Then in my SmsListener I'm creating notification to show in statusbar.
Then, when user clicks on a notification I want
Bring MainActivity to foreground (If such activity does not exist yet it should be created)
Pass to it data from the sms
Perform some ui changes basing on this data in this MainActivity
My activity is defined as
<activity
android:name=".MainActivity"
android:screenOrientation="sensor"
android:label="#string/app_name"
android:launchMode="singleTask"/>
Activity is launched as
Intent i = new Intent();
i.setClass(context, MainActivity.class);
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(i);
Also in my activity I have overridden method onNewActivity
#Override
public void onNewIntent(Intent intent){
super.onNewIntent(intent);
// I have data from broadcast in intent variable passed to this activity
processDataFromBroadcast(intent);
}
It works fine if the MainActivity already exists but if MainActivity does not exist it is started however onNewIntent was not called
Then I tried to invoke processDataFromBroadcast from onCreate: processDataFromBroadcast(getIntent()).
First time data is passed correctly from my broadcast to the activity.
However if MainActivity is sent to background and then again brought to foreground either onCreate or onNewIntent is called and processDataFromBroadcast is executed again with intent sent by broadcast and thus my MainActivity is updated with data from broadcast every-time the app is bringing to foreground - the latter is unwanted, how can I make my activity to forget this intent after first handling.
Here is sample application.
For an activity to launch only one instance of itself, have a look at the <activity> manifest element, and particularly android:launchMode. You want to configure it with either singleTask or singleInstance.
To pass data to your activity, you add data to the Intent you use to open it. To pass data with the intent, use the putExtra() methods of the intent before sending it off, and getExtra() methods to retrieve them in your receiving activity.
I'm assuming that you know roughly how intents work, but if not you could learn more about intents by taking a look at this Android developers article.
in case your problem is still unresolved, as I was just running into the same issue, here's how I solved it:
I am putting a timestamp as intentId as an extra upon the intent during it's creation. the first time, I am handling the intent in onCreate() or onNewIntent() I am reading the intentId and store it as the last intent handled. so the next time onCreate() or onNewIntet() is invoked I can check the intentId and if it equals the id of the last intent handled, I ignore it! It don't know if this helps in your case, maybe you can adopt it.
To keep intentId independent from activity lifecycles you could persist it in the userdefaults.
I agree that one would expect calling setIntent(new Intent()) in onNewIntent should do the trick.
It it late to answer, but it might be helpful to others looking for the solution.
Just add below lines of code :
Intent mIntent = new Intent(this, SplashActivity.class);
mIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); // You need this if starting the activity from a service
mIntent.setAction(Intent.ACTION_MAIN);
mIntent.addCategory(Intent.CATEGORY_LAUNCHER);
Where SplashActivity is the name of initial application that is the first screen of your application.
Hope it helps. :)