Android Activity singleton - android

I have an activity called MainActivity. This activity launches a notification that has a PendingIntent that opens this MainActivity.
So, to close the application, I have to click the back button twice. I would like to set up activity as singleton. I tried to set singleInstance or singleTask to manifest but this doesn't work.

singleInstance and singleTask are not recommended for general use.
Try:
android:launchMode="singleTop"
For more information please refer to launchMode section of the Activity element documentation.
In addition to the previous reference you should also read tasks and back stack

If you need to return to your app without creating a new instance of your activity, you can use the same intent filters as android uses when launching the app:
final Intent notificationIntent = new Intent(context, MainActivity.class);
notificationIntent.setAction(Intent.ACTION_MAIN);
notificationIntent.addCategory(Intent.CATEGORY_LAUNCHER);
PendingIntent contentIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0);
As the intent you created to open your activity from the notification bar is the same as android used for launching your app, the previously opened activity will be shown instead of creating a new one.

Related

How to bring an Activity back to the front after i click home button(via notification)

I have a VideoActivity which plays a video, what im trying to implement is when i click home button, i will display a notification, and once i click the notification it will bring the VideoActivity instance back to the front.
here's how i define the Intent for my notification:
Intent notificationIntent = new Intent(context, VideoActivity.class);
notificationIntent.addFlags( Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT);
but everytime i click the notification, it turns out that a new VideoActivity will be created.
Use this as this will also do the same thing in more elegant manner ( without any side effects )
final Intent notificationIntent = new Intent(context, YourActivity.class);
notificationIntent.setAction(Intent.ACTION_MAIN);
notificationIntent.setFlags(FLAG_ACTIVITY_NEW_TASK);
notificationIntent.addCategory(Intent.CATEGORY_LAUNCHER);
or
you can use this too
<activity
android:name=".YourActivity"
android:launchMode="singleTask"/>
Description of singleTask
The system creates a new task and instantiates the activity at the root of the
new task. However, if an instance of the activity already exists in a separate
task, the system routes the intent to the existing instance through a call to
its onNewIntent() method, rather than creating a new instance. Only one
instance of the activity can exist at a time.
You should try this.
Intent notificationIntent = new Intent(context, VideoActivity.class);
notificationIntent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP|Intent.FLAG_ACTIVITY_CLEAR_TOP);
You have to make your activity single task means when it is already running or in background state then its new instance should not be created and already running activity should be brought to front.
For this in your AndroidManifest.xml
where you declared your activity add
android:launchMode="singleTask"
in your activity entry.

Android: Reopen app when click on notification

This is the code I use to create the PendingIntent for my notification.
Intent notificationIntent = new Intent(context, Activity1.class);
PendingIntent myIntent = PendingIntent.getActivity(context, 0,notificationIntent, 0);
This PendingIntent launches Activity1 when the notification is click.
How can I simply reopen the app and go to the most recent Activity (as though clicking on the launcher icon) instead of launching a new Activity when the notification is clicked?
Activity1 is just an example. I have multiple Activity in the app. I just want to reopen the app and go to the most recent Activity
NOTE: this looks like wrong design for me, because notification should allow user to enter activity that is in context with the notification.
Technically, you can create redirecting activity and your notification intent should launch it when tapped. In its onCreate() you check what activity you want user to be redirected (you can keep this info in SharedPreferences, and each activity would write this info in onCreate() (or make that in your base class if you have it). Then in redirector you call regular startActivity() to go last activity and call finish() to conclude your redirector. Moreover, your redirector activity does not need any layout so add
android:theme="#android:style/Theme.NoDisplay"
to its Manifest entry (of course you also need no call to setContentView())
create Activity1 as a singletask activity , by changing the launchMode of the activity to singleTask...
set your activity to launchMode="singleTop" in your Manifest.xml then use this code instead of what you are using above to reopen the active one:
Title = "YourAppName";
Text = "open";
notificationIntent = new Intent(this, Activity1.class);
cIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0);
notification.setLatestEventInfo(getApplicationContext(), Title, Text, cIntent);
You can change the android:launchMode in the manifest file for the activity targeted by the pending intent.
Typically, you can use singleTop, which will reuse the same instance when the targeted activity is already on top of the task stack (i.e.: Activity is shown before you left your app).
You can also consider SingleTask and SingleInstance, if you want to keep only a single instance of the activity.

How do you avoid more than one instance of an Activity when created from widget?

I would like to start my application\activity when a button is pressed in my widget.
I am using this code:
Intent launchApp = context.getPackageManager()
Intent launchApp = context.getPackageManager()
.getLaunchIntentForPackage("com.sexy.code");
launchApp.setData(Uri.parse(listItemClickIntent
.toUri(Intent.URI_INTENT_SCHEME)));
pIntent = PendingIntent.getActivity(context, 0, launchApp,
PendingIntent.FLAG_UPDATE_CURRENT);
My problem is in a scenario that my application is already alive in the background so everything looks ok until I close that activity that opened and discover another one behind it. It's like I need to exit the application twice.
How do I avoid this?
Try this:
launchApp.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
From the documentation for FLAG_ACTIVITY_CLEAR_TOP:
If set, and the activity being launched is already running in the current task, then instead of launching a new instance of that activity, all of the other activities on top of it will be closed and this Intent will be delivered to the (now on top) old activity as a new Intent.
This flag can also be combined with FLAG_ACTIVITY_NEW_TASK, as in:
launchApp.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP |
Intent.FLAG_ACTIVITY_NEW_TASK);
You can also use them separately, depending on what your desired behavior is.
What about using launch mode flag:
android:launchMode="singleTask"
You activity should look like:
<activity
android:name=".YourActivity"
android:launchMode="singleTask"
android:configChanges="orientation|screenSize" >

finish activity in which a pending intent starts

In my app, i created a custom notification that contain a button that show recent apps(instead of home button long press)
when user open main activity and press home button to go to home screen then drag the notification drawer and click on the button:
Desired result is that the recent apps are shown and the main activity is one of the recent apps.
Actual result is that the recent apps are shown but the main activity is not in them and the main activity resumes.
My code to start "RecentApps (is a dummy class that show recent apps)" class with pending intent
Intent recentAppIntent = new Intent(getBaseContext(), RecentApps.class);
PendingIntent pendingrecentAppIntent = PendingIntent.getActivity(getBaseContext(), 1, recentAppIntent, 0);
notificationView.setOnClickPendingIntent(R.id.recentAppButt, pendingrecentAppIntent);
I think that the problem is getBaseContext, so when the main activity is alive and not finished the recent apps are shown but with context is the main activity.
I tried getApplication and getApplicationContext but not working.
I also tried to use flags for "recentAppIntent" but it is not working, It is a half solution to use
recentAppIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
but it not what i need.
So, my question is "How to finish the main activity in which the pending intent starts".
Thanks in advance, Mostafa
You need to ensure that your MainActivity and your RecentApps don't belong to the same task. The "Recent apps" doesn't actually show recent apps. It shows recent tasks.
To make sure that your RecentApps isn't in the same task as your MainActivity, you can add the following to the <activity> definition in the manifest for RecentApps:
aandroid:taskAffinity=""
Also, when creating the notification, add FLAG_ACTIVITY_NEW_TASK to the Intent, like this:
Intent recentAppIntent = new Intent(getBaseContext(), RecentApps.class);
recentAppIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
PendingIntent pendingrecentAppIntent = PendingIntent.getActivity(getBaseContext(), 1, recentAppIntent, 0);
notificationView.setOnClickPendingIntent(R.id.recentAppButt, pendingrecentAppIntent);
I think FLAG_ACTIVITY_CLEAR_TOP will help as a flag.
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
Explanation for Intent flags are available here: link

Make PendingIntent from notification not fire if the Activity is already on front

Service A creates a Notification with a PendingIntent that opens Activity B. User pulls the notification drawer down and presses the Notification with Activity B on front previously. The PendingIntent basically adds another instance of Activity B instead of opening the currently open one.
Is there any way to make the PendingIntent open the Activity if it's already open, go back on the backstack if there's an instance of that Activity there, and open a new instance otherwise?
Add Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP when creating the Intent for your Notification.
Setting both Intent.FLAG_ACTIVITY_CLEAR_TOP and Intent.FLAG_ACTIVITY_SINGLE_TOP will cause an existing instance of the Activity to be used (onNewIntent() will be called). If you only specify Intent.FLAG_ACTIVITY_CLEAR_TOP and there is already an existing instance of the Activity, that instance (and all other activities on top of it) will be finished and removed from the stack and a new instance of the Activity will be created (onCreate() will be called).
Yes, you can use the single task or single instance launch mode of your activity (or in your pending intent flags) to control this behavior.
Check the launch modes documentation for details on how to set those flags.
You can set Activity's attribute in Manifest file as following:
android:launchMode="singleTask"
or
On defining Flags for PendingIntent, you can use flags as:
Intent in=new Intent();
in.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP
| Intent.FLAG_ACTIVITY_SINGLE_TOP);

Categories

Resources