How to add flags to an APPWIDGET_CONFIGURE intent? - android

I have an activity registered on APPWIDGET_CONFIGURE:
<activity android:name="com.tahanot.activities.NearbyStops">
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_CONFIGURE" />
</intent-filter>
</activity>
However this activity does not behave as expected. It opens inside of an existing stack, and when I press the Back button, it takes me to other activities instead of closing the task. Ideally, I would like the APPWIDGET_CONFIGURE intent to include FLAG_ACTIVITY_NEW_TASK and FLAG_ACTIVITY_MULTIPLE_TASK.
Is it possible to specify flags in AndroidManifest.xml, and if not, what workaround would you suggest?

Consider specifying launchMode attribute to the activity element.
<activity android:launchMode="singleTask" android:name="com.tahanot.activities.NearbyStops">
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_CONFIGURE" />
</intent-filter>
</activity>
As per the official docs,
FLAG_ACTIVITY_NEW_TASK
Start the activity in a new task. If a task is already running for
the activity you are now starting, that task is brought to the
foreground with its last state restored and the activity receives the
new intent in onNewIntent().
This produces the same behavior as the "singleTask" launchMode value,
discussed in the previous section.
Since you mention you want FLAG_ACTIVITY_NEW_TASK behavior so singleTask launchMode might work for you.

USe this java code when you start your activity
Intent intent = new Intent(this,
activityname.class);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
Here you can add flag with your intent object like this.
And you can also add multiple flag.

This is the manifest declaration that I used, following appsroxcom's idea for android:launchMode:
<activity
android:name="com.tahanot.activities.NearbyStops"
android:configChanges="orientation"
android:label="#string/title_activity_stops_nearby"
android:launchMode="singleTop"
android:taskAffinity="com.tahanot.tasks.widgetConfiguration" >
<!-- android:launchMode makes sure the Back button doesn't navigate to another NearbyStops activity.
android:taskAffinity makes sure the Back button doesn't navigate to some other activity. -->
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_CONFIGURE" />
</intent-filter>
</activity>

Related

Difference between launching app from recents and home screen

I have ActivityA as launcher activity.
From ActivityA I open -> ActivityB. I put the app in background.
When I open the app from recents the app is resumed with ActivityB.
When I open the app from homescreen, the app is resumed with ActivityA without calling onCreate(), just onResume().
Why is ActivityB cleared from stack when I open the app from homescreen, even if onCreate() from ActivityA is never called, and how to fix this?
Manifest file looks like this:
ActivityA:
<activity-alias
android:name=".Launcher"
android:label="#string/app_name"
android:targetActivity="path.ActivityA">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity-alias>
<activity
android:name=".path.ActivityA"
android:launchMode="singleTask"
android:screenOrientation="sensorPortrait"
android:theme="#style/BlackIntroTheme"
android:windowSoftInputMode="adjustPan">
<nav-graph android:value="#navigation/graph1" />
<nav-graph android:value="#navigation/graph2" />
<nav-graph android:value="#navigation/graph3" />
<nav-graph android:value="#navigation/graph4" />
</activity>
ActivityB:
<activity
android:name=".path.ActivityB"
android:launchMode="singleTask"
android:screenOrientation="sensorPortrait"
android:windowSoftInputMode="adjustPan" />
this is how Activity stacking works, some nice example of all launchModes in HERE, more complex info in DOCs
in short - Activity with singleTask started (again) will clear all on-top-of-it Activities. you have your first MAIN Activity declared with this launchMode, so every icon click on devices launcher will clear your Activities stack. you can track this by overriding onNewIntent method. picking from recents just brings all your Activities stack to front, with last opened on top ofc.
consider removing launchMode (is this necessary line for you?) or set it as standard (default)
android:launchMode="standard"

Intent for activity brings another activity to front

I'm creating an intent for a custom app shortcut like following:
Intent.ShortcutIconResource icon = ...;
Intent intent = new Intent();
Intent launchIntent = new Intent(getThis(), HandleShortcutActivity.class);
// add a few user settings
And the activity handles the intent like following:
public class HandleShortcutActivity extends AppCompatActivity
{
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_helper);
// get data from intent
// ...
// handle the action
// ...
// finish this activity instantly again
finish();
}
}
And here's my manifest:
<activity
android:name=".activities.MainActivity"
android:windowSoftInputMode="adjustPan"
android:launchMode="singleTask"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".activities.HandleShortcutActivity"
android:configChanges="orientation|screenSize"
android:excludeFromRecents="true"
android:noHistory="true"
android:theme="#style/Theme.Transparent"
android:launchMode="singleTask">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
</intent-filter>
</activity>
Problem
If MainActivity is runnning in background and my shortcut intent is started, my MainActivity is broought to front. Why? How can I avoid this?
What you need here is to set a 'Task Affinity' so that your task is created as a part of a new stack that is not related to your MainActivity. Then, when you finish() it, it would close the HandleShortcutActivity as opposed to going "back" to MainActivity
From the official docs:-
android:taskAffinity
The task that the activity has an affinity for. Activities with the
same affinity conceptually belong to the same task (to the same
"application" from the user's perspective). The affinity of a task is
determined by the affinity of its root activity. The affinity
determines two things — the task that the activity is re-parented to
(see the allowTaskReparenting attribute) and the task that will house
the activity when it is launched with the FLAG_ACTIVITY_NEW_TASK flag.
By default, all activities in an application have the same affinity.
You can set this attribute to group them differently, and even place
activities defined in different applications within the same task. To
specify that the activity does not have an affinity for any task, set
it to an empty string.
If this attribute is not set, the activity inherits the affinity set
for the application (see the element's taskAffinity
attribute). The name of the default affinity for an application is the
package name set by the element.
HandleShortcutActivity in your Manifest file after adding taskAffinity:
<activity
android:name=".activities.HandleShortcutActivity"
android:configChanges="orientation|screenSize"
android:excludeFromRecents="true"
android:noHistory="true"
android:theme="#style/Theme.Transparent"
android:launchMode="singleTask"
android:taskAffinity="">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
</intent-filter>
</activity>
To explain what would happen in this case, see the below diagram with task #1 being your calling task/activity and task #2 being your HandleShortcutActivity
I found this article very useful when understanding the different Android Launch modes, and explains various scenarios you might face quite coherently.
Update your manifest...
<activity
android:name=".activities.MainActivity"
android:windowSoftInputMode="adjustPan"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
Remove android:launchMode="singleTask" from your Activity declaration in manifest file.
this launch mode search Activity in task stack and if it's available takes from the stack and not created a new instance of MainActivity.

Two activities in task manager of same app

My application have two activities, say MainActivity and SecondActivity. Main activity is declared as android:launchMode="singleInstance" and its orientation is always portrait. Second activity is always has landscape orientation.
In some devices, everything is alright and in task manager there is only one instance of my app, but in some devices (like Samsung S7), when I launch SecondActivity, there will be two instances of my app in task manager like this image:
My guess is that something is wrong with the launchMode of the MainActivty but I need it to be singleInstance. Any suggestion?
EDIT:
MainActivity in manifest:
<activity
android:name=".Activities.MainActivity"
android:screenOrientation="portrait"
android:launchMode="singleInstance"
android:theme="#style/AppTheme"
android:windowSoftInputMode="adjustPan">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
and second:
<activity
android:name=".Activities.SecondActivity"
android:screenOrientation="landscape" />
launching code:
Intent intent = new Intent(getActivity(),
intent.putExtra("VideoUri", filmGet.getOutput().getData().getFilmTrailer());
startActivity(intent);
If it helps, I launch SecondActivity from a fragment.
So, after reading #sharan comment and some googling, it made me to read some google documents. According to docs, there isn't any difference between android:launchMode=singleInstance and android:launchMode=singleTask but one. They both make your activity singleton and so you will never have two instances of it. The only difference between them is that singleInstance will prevent the task from attaching any other activity while singleTask has not this limitation. Any other things about them are the same.
So, for anyone who is reading this post, I'll recommend you to never use singleInstance launch mode unless you exactly need what it has. Because if you have only one activity in your app, then there will be no differences between singleInstance and singleTask. And if you have more than one activity, then I'll recommend you to all of your activities belong to one task.
In short, change singleInstance to singleTask and you are go.

Transparent Activity opening independently

I want to create a activity with transparent background that I can start by clicking on a Notification.
I created the notification and the activity with no problem, but now, I want to open this particular TransparentActivity independently i.e. without showing the other activities on the background.
I tried to put some flags on the intent:
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
and on the AndroidManifest file, on my TransparentActivity tag, I put:
<activity
android:name=".TransparentActivity"
android:launchMode="singleTask"
android:theme="#style/Theme.Transparent">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
It works as expected, but now I have two icons for my app, which is something I don't want.
Is there a way to make it work?
Easiest way to do this is to change the taskAffinity for this Activity in the manifest. Add:
android:taskAffinity=""
to the <activity> declaration for this oneActivity`.
This one Activity will then be launched into a new task, and not into the task that runs the rest of your application.

Problem while displaying activity from BroadcastReceiver

Hi I have a Broadcast receiver with following code.
1. Intent i = new Intent(context, A.class);
2. i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3. context.startActivity(i);
This works fine and my activity does start, but it starts on top of my main activity i.e. B. What I want is that from my broadcast receiver I should be able start an Activity A, such that it does not start on top of B. Why B is always starting in background. What I am doing wrong.
Also, to mention by activity A has Theme.Dialog.
Please let me know your thoughts.
A new activity is supposed to start on top of existing activities.
If you want to start something without appearing in the activity history stack, maybe this something shouldn't be an Activity but a Service instead?
Edit: I think you can change this behaviour with FLAG_ACTIVITY_NEW_TASK in conjunction with android:launchMode="singleTask" in the Manifest. (see documentation on launch mode)
If you start an Activity then of course it will come foreground.The activity previously was in foreground will go to the background automatically.
If you don't need to start it on top of B,what about to start it from service?.Let Activity A stay as it is.
If you need to access anything from service and no need to show the activity,then surely you are looking for other then starting an Activity with an intent.
Finally if you really want to start Activity A,and B will be on top then start Activity B after starting A
I think you mean you want to start the application with a different activity. You can edit your AndroidManifest.xml file to make a different activity start first.
EDIT: Heres an example:
<application android:icon="#drawable/icon" android:label="#string/app_name">
<activity android:name=".MainActivity" <-this will start first
android:label="#string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name =".otherActivity"
android:theme="#android:style/Theme.Dialog">
</activity>
<activity android:name=".anotherActivity"></activity>
</application>

Categories

Resources