I am currently developing an android app which uses the android web browser and notifications.
What I want to be able to do is the user clicks on an item which loads the android web browser and makes a notification in the notification bar as well.
The user should be on the browser when they go the notification, so when the user is on the browser and they click on the notification I want the notification to perform its task but not redisplay the app activity instead just return to where the user was on the browser.
I've tried setting the different flags on the activity but none of them seem to make any difference.
Thanks for any help you can provide.
According to the following quote from the Android documentation, it sounds like there isn't a way to do some kind of background task without starting an activity when a user clicks a notification. Although you may want to look into sending an Intent to a Service. I've have not tried that before so I can't say whether it works or not.
A notification always starts an
activity as a new task (that is, it
puts FLAG_ACTIVITY_NEW_TASK in the
intent it passes to startActivity())
The documentation also suggests you could have a dedicated activity that could perform the copy paste, and then the user could simply press back to get back to the browser:
For example, when the user receives a
Calendar notification, choosing that
notification starts a special activity
that displays a list of upcoming
calendar events — this view is
available only from the notification,
not through the Calendar's own user
interface. After viewing this upcoming
event, to ensure that the user
pressing the BACK key will return to
the activity the user was in when they
picked the notification, you would
make sure this dedicated activity does
not have the same task affinity as the
Calendar or any other activity. (You
do this by setting task affinity to
the empty string, which means it has
no affinity to anything.)
To get round this as I did not want to have a service running in the background to perform this simple task what I have done is called the method at the end of the activity that the notification calls.
I call moveTaskToBack(true); which places the task into the background. As if the user presses the home button.
Related
Scenario :
In my application i have enabled app linking. So when an App link is triggered, i have set a dummy AppLinkActivity (opens as "singleTask" to avoid creation of new task) to receive and handle the url received through the app link. While handling the url, i have to check whether the app was showing the "DownloadActivity", if so then i have to show a dialog.
So when an App link is triggered, i will have the already existing task with existing activities and on top of that will be the AppLinkingActivity. In this case i have no way to know what the previous activity was, since i cannot pass anything via an intent.
What i want to do
When the AppLinkingActivity is opened via an app link, is there any way by which i can find out what was the last shown activity(of my app) before AppLinkingActivity in the same task?
--Alternatively--
If i exclude the "singleTask" in manifest then the AppLinkingActivity is opened in a new task. In this scenario, is there any way by which i can get the last shown(or topmost) activity in the previous task? If yes, i also need a way to navigate to that topmost activity in the previous task? In this scenario if i simply finish() AppLinkingActivity, then the control goes back to the which ever source that triggered the app link like browser or gmail app etc.
Is any of the above two requirements is possible?
I am trying to open a PendingIntent that opens the Gmail App in the background through a notification.
The steps are as follows:
Show notification with action button
On click of action button (which has a PendingIntent), I want start the PendingIntent (which launches the Gmail app) but in the background.
Dismiss Notification
The notification remains the only thing that the user has seen (i.e. the UI has not changed but only the notification has itself been dismissed after clicking the action button).
It may be "hack-y" but I could also quickly open and then "minimize" the gmail app?
Any ideas?
OK, I really don't understand what you can achieve from such behavior.
you definitely could not provide any meaningful extra data on the intent (unless you are the developer of gmail, which I don't believe is the case..).
actually, if you provides intent to launch explicitly Gmail app (by specifying the package name) - your code would break if Gmail app package name would change.
now to your question:
it is possible to launch activity without bringing it to foreground:
all you have to do is add to the intent been held by the pending intent to flags: FLAG_ACTIVITY_NEW_TASK and FLAG_ACTIVITY_MULTIPLE_TASK
FLAG_ACTIVITY_MULTIPLE_TASK flag is not recommended for use unless your application is the launcher.
gmail main activity would create in background new task, and that's it.
note that the gmail activity would not go threw the onResume and onStart callbacks (because it's not on foreground..) , so if any meaningful code happens from this callbacks - they won't be executed anyway..
UPDATE
now that I know that your purpose is to mark an emails as "read", I can tell you that any attempts to launch gmail app want do to you any good. as I mentioned, you can't pass extra meaningful data to gamil launching intent. there is simply no such API's, and launching main activity simply won't do anything that would help you.
instead, I'll suggest you to use Gmail API's for control user's inbox
Background
Let's take the next sceneraio:
the user uses an app X which has multiple activities (like the gmail app).
after navigating the app X a bit, he goes to your app.
in your app, you need to start this X app using an intent, to go to a specific activity within it.
now the user goes to this specific activity on the app X.
the user presses the back button, hoping to go back to your app instead of staying on the app X.
another similar scenario:
the user navigates on your app between activities.
your app went to the background (using the home button, for example).
your app shows a notification that once clicked, it will open a specific activity of your app.
the user clicks on the notification and goes to the specific activity of your app.
the user presses the back button, hoping to return to the app that was shown before clicking on the notification, instead of going to the previous activity on your app that was shown the last time it left it.
It seems that the last step on both scenarios isn't the default behavior.
This is why I've searched what is the best combination of flags for this purpose.
The problem
It seems that the only flag that can achieve the behavior i've described is Intent.FLAG_ACTIVITY_MULTIPLE_TASK (together with Intent.FLAG_ACTIVITY_NEW_TASK).
According to the android API, however, this flag isn't recommended for normal use:
Do not use this flag unless you are implementing your own top-level
application launcher.
...
Because the default system does not include
graphical task management, you should not use this flag unless you
provide some way for a user to return back to the tasks you have
launched.
This information seems as confusing as the rest of the descriptions about intents.
There are other intents flags that I've seen, like Intent.FLAG_ACTIVITY_CLEAR_TASK that achieve a similar result, but they have weird behaviors and/or they use high API
The question
Is it safe to use this flag? Are there any good alternatives to it?
What is the danger of using this flag and what is the meaning of the description on the API of using it?
In your first scenario, if your app needs to start an activity of another app, it can just start this activity within the same task as your application. There is no reason to use any special Intent flags for this (you don't need FLAG_ACTIVITY_NEW_TASK or FLAG_ACTIVITY_MULTIPLE_TASK). In step 5 of your scenario, the user will return to your application (because BACK just takes him to the previous activity in the current task). This is the standard, default behaviour.
In your second scenario, my first response is "that isn't the standard behaviour". That means that users probably won't expect to be able to go back to the task that they were doing prior to clicking on the notification. However, if you really want to implement this, then I would suggest that you create a special Activity that is launched from the notification and this special Activity should have a different taskAffinity than the rest of the Activities in your application. In this case, when the special Activity is launched from the notification, it will not bring your application's task to the foreground. It will just create a new task containing just the special Activity. When the special Activity is showing, the user can press the BACK key and this will return him to the task that he was working on prior to clicking on your notification.
In general you should NOT use FLAG_ACTIVITY_MULTIPLE_TASK. The main reason is that if you have several tasks containing your application (or parts of it), it is pretty much impossible for the user to return to a specific one. There is no way to provide different launch icons or different application names (for the different tasks)(, so that the user will see multiple tasks in the "recent tasks" list, but will not be able to tell which one is which. You will have a hard time cleaning up what you are doing and you will just make more problems than you can deal with. There are about a million side effects of using this flag and for general applicaitons there is just no need to do it.
I am using PendingIntent to take user from push notifications to Activity B i,e when user clicks on notification it will go to screen B.
I want it to be screen B only when application is loaded and running, else it should go to screen A. I have implemented this as well.
Now, there is scenario, wherein I have received the notifications, hence the intent is set to Screen B, but I haven't clicked it. If I kill the application process using DDMS or if the android kills the application before I click on notification and then I click it, it tries to load activity B which is not what I want in this case. I would like to load activity A in this case which is first sceen of the app.
Please, suggest what to do !
It sounds like you're deciding whether to launch activity A or B at the time you post the notification, which, as you've discovered, will not work: once you submit the notification to the Notification Manager, you can't make changes to it.
The way to do this is to always launch the same activity, but have that activity potentially redirect the user to a different activity based on whatever criteria you want. For example, you could launch activity B, which then bounces the user immediately to A if the app is not already in the foreground. (You could also do this with a third activity whose job is simply to route the user around, or with a service, or with a broadcast.)
Now the decision about where to send the user is made at the time the user taps on the notification, rather than at the time the notification is posted.
My app is designed to run as a single instance and the Back button does not allow you to exit the app and return to the Start screen because it is used internally to navigate a hierarchy of screens where each screen can be an activity.
However, an external app can launch one of the app's internal activities. When the user is done with whatever the activity is designed for, the user's intuitive action is to hit the Back button to return back to the calling client. But because I prevent the Back button from exiting, the user cannot return.
I can add code to override this when the code detects that the activity is being launched by a client. The problem however is that if the app closes to return, the user might return to the app from where they left off. But since I closed the app to return to the calling client, the user cannot return back to the app as it was last opened. My app needs to remain as a single instance, so the activity that gets launched cannot be created more than once. Any suggestions on how to return back to the calling client but also keep the app running if it was running when the calling client used one of its activities?
In general, you can programmatically control the back navigation trail. Take a look at
TaskStackBuilder and the documentation for handling notifications Responding to Notifications. It seems that what you're trying to do is control the so-called "back stack". If you use TaskStackBuilder, the behavior will match the platform version you're on.
In pre 3.0 platforms, the Back button went all the way through the back stack to the first task the user did since the phone was turned on. Post 3.0, back does not traverse task boundaries; to get to other tasks, the user clicks the "Recent Items" icon. There's also the "up" icon in an app to navigate to the "beginning" of a task within an app. TaskStackBuilder will "do the right thing" for all versions.
In the current platform version, not allowing Back to exit your app is OK, because Back should only go to the first Activity in the current task. In versions previous to 3.0, not allowing Back to exit the app is more problematic, and I personally wouldn't do it that way, but it's up to you.
What happens when the user clicks Back after an Intent starts your app should be clear from the documentation I've cited. Basically, what you want to do is go back to the previous task.