I have an activity. The launch mode is singleTask, and I implement onNewIntent. When I send an intent to launch this activity while the activity is open (with flags NEW_TASK and RESET_TASK_IF_NEEDED), the screen flashes before showing me the same activity.
Why could this be happening? I thought singleTask should be enough to ensure that new intents are delivered to onNewIntent, rather than the system spinning up a new task or anything for my activity. The flashing goes away when I do either of the following things:
change the launch mode to singleTop;
add the flag Intent.FLAG_ACTIVITY_CLEAR_TOP to the launch intent.
I'm curious to know what's going on and what, if anything, I could do to overcome the flashing (I'd really prefer not to change the launch mode or launch intent flags, if at all possible). Basically, is there any good reason why this should not work?
Note that I do get onNewIntent, even though the screen flashes.
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 have an activity with an intent filter for ACTION_SEND. A file can be shared to this activity from another app , let's say Gallery, and handled in onNewIntent.
However, on my Samsung Galaxy S5 it's not working as it used to (it's been tested on numerous devices and still works on some, so I think it's device specific). onCreate is always being called and onNewIntent is not. It always had a launchMode of singleTask.
When I background the app and come back, onCreate is not called, but when I select my app from a chooser in order to share a file to it, I get the behaviour described above.
I've tried setting the launchMode to singleTop and setting the flags intent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_CLEAR_TOP); on the intent that initially launches the activity.
I've tried setting Intent.FLAG_ACTIVITY_SINGLE_TOP on its own.
I've also tried changing the launchMode to singleInstance.
savedInstanceState seems to be null when I return to the activity too even though onSaveInstanceState was called when app was backgrounded.
Is there any way to prevent this behaviour and call onNewIntent or is it a device-specific bug?
My app, running in background, at some point displays activity to purposefully interrupt user's flow. My activity starts a new task, which appears in "Recent Tasks" lists while being in foreground. Is there any way it could be prevented? Setting android:excludeFromRecents does not work - activity is not presented anymore in "Recent Tasks" only after is has been paused.
Manifest looks like:
<activity
android:name="com.example.recenttasks.MainActivity"
android:excludeFromRecents="true">
</activity>
and activity is started this way:
#Override
public void onReceive(Context context, Intent intent) {
Intent i = new Intent(context, MainActivity.class);
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(i);
}
The key thing you mentioned is
appears in "Recent Tasks" lists while being in foreground
I think you can't change that behavior. I just tested on my app and the same thing happens. If I press the "recent tasks" button while having my activity in the foreground, it appears listed there. The moment I move out of it to another activity or to my phone's main screen, the activity is not listed anymore.
I also tested this on the built-in DeskClock app that comes with recent Android versions and the same behavior is present there when a new alarm is triggered. Note that the AlarmAlertFullscreen activity of that app has the same parameters you mentioned in your question.
I'm not sure you can circumvent this or why you would need to in the first place since the activity is not listed anymore once it loses the focus.
you are defined it in manifest that is enough but it is not coming..
ok..try add this flag also to your Intnet and start the Activity..
intnet.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
Should the user be able to return to it? (Meaning if it shows and user clicks recents, have they lost their chance to see the hidden activity or should it still be there?)
If they cannot return to it anyway then the best action would be to finish() the activity onPause(). This will mean that as long as you have used android:excludeFromRecents and android:noHistory="true", there will be no item in recents.
If however you do wish to return to the 'interruption' activity (but do not want a recents entry) you could consider still finishing the activity onPause - but also recording a preference flag (something like IS_INTERSTITIAL). Your other activities can then check this preference in onResume and, if it is true, send an Intent to restart the Interstitial instead - To the user it will just appear they are resuming the app in the same state as they left it (interstitial)
Edit: If the screen needs to stay (rather than be re-instantiated) it may be possible to use a DialogFragment, although then you must worry about configuration changes. There is one hack you could try (explained in this answer) -
Set your label empty By using android:label="" your recent task is excluded. however this is a definite hack which may produce inconsistent results (as I haven't tested it to be sure)
How do I get my app to appear in on the screen after it has been replaced by some other screen/activity? Some network event occurs and my application wants to reappear in the foreground (presumably in a polite manner).
I think I need to do something like:
contxt.startActivity(myActivity);
I don't want to create another instance of my app or cause it to restart, but I want it to appear.
Use FLAG_ACTIVITY_NEW_TASK
Intent intent = new Intent(contxt, myActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
contxt.startActivity(intent);
In your myActivity onNewIntent is called. I assume myActivity is the top activity in your app current stack
I am looking for a way to launch another app from within my app but so that the focus is not changed from my app to the app launched.
I.e currently I have the new app launched via a intent, however when this is carried out the new app is launched and becomes the app in view, I need it to be kept in the background with my app still in view.
The reason for this?
I am developing an application for internal use that will act like a lock-screen to the device so although things must happen in the background the 'lock-screen' must always be on top.
I have done some research into intents and launching other apps but can not find anything about what I need.
Hope you can help thank you!
Currently the terminal is called like this:
Intent intent = new Intent(Intent.ACTION_MAIN);
intent.setComponent(new ComponentName("jackpal.androidterm", "jackpal.androidterm.RemoteInterface"));
intent.setAction("jackpal.androidterm.RUN_SCRIPT");
intent.putExtra("jackpal.androidterm.iInitialCommand", cmdString);
The reason it needs to be running in the background is so that the app can run commands in terminal without the user having access, but then they 'unlock' the screen they need to then be able to view the terminal and what commands are being run etc
You can not startActivity in Background.Instead start the activity and minimise the activity(in your case this activity is of different application) using moveTaskToBack(true);
In your case, put a condition based on your intent and its params and use moveTaskToBack(true); so that activity will be minimised only when your application launches.
This won't be possible, you will have to start a background Service that does the actual work and only launch the Activity you want to navigate to once your foreground Activity is finished. Depending on your architecture, you can store the Activity to call when your foreground Activity is finished and change it from the service. That way you will have your desire behaviour without having to actually call the Activity.
In addition to the answer from #Meher, in the intent for your current starting activity, you can add the flag FLAG_FROM_BACKGROUND.
With this you get rid of the "blinking" effect (the one where your activity shows for one fraction of second while it discovers wether to go to background)