StartActivityForResult result in a new item on OverviewScreen - android

I want to launch an activity from another application inside my own app. I have control over both applications.
For it, I'm using the explicit intent and it works well.
Intent intent = new Intent();
ComponentName componentName = new ComponentName("br.com.example.app","br.com.exemple.app.myactivity");
intent.setComponent(componentName);
My problem occurs when I click on the overview button, the new application appears inside the same item when overview screen (Recents Screen). Thus, the user can figure out if he is one the App1 or App2. Actually, he will think that he is still inside App1.
How do I force it to appear on a different item on the Overview Screen?
I already tried to use
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_DOCUMENT);
and
<activity
android:name=".myactivity"
android:exported="true"
android:screenOrientation="portrait"
android:theme="#style/ApiBaseThemeNoActionBar"
android:documentLaunchMode="always">
</activity>
It seems to work well when using only startActivity(intent).

See the documentation for FLAG_ACTIVITY_NEW_TASK:
This flag can not be used when the caller is requesting a result from the activity being launched.
So in your case, I guess if you're asking for a result, android forces you to stay in the same task.

Related

Two Activity at top of stack even after launchMode is singleTop

I am opening an Activity when a button is pressed. However, if user presses this button twice fast enough my activity launches two times. To prevent that I added launchMode: singleTop in manifest and also added this flag to launching intent.
But still the behaviour is same. I am not looking to prevent double clicking by using handler threads or enabling disabling it. I wish to know why singleTop is not working in this case.
code in Manifest
<activity
android:name=".MyActivity"
android:screenOrientation="portrait"
android:theme="#style/MyTheme"
android:launchMode="singleTop"
android:windowSoftInputMode="adjustResize" />
Intent
val intent = Intent(context, MyActivity::class.java)
intent.flags = Intent.FLAG_ACTIVITY_SINGLE_TOP
activity?.startActivityFromFragment(this, intent, REQUEST_CODE)
Update
Upon more investigation I found that startActivityForResult is not respecting the flag. startActivityFromFragment calls startActivityForResult
I wrote a sample which reproduces this here
You don't need to use signeTop. You can use any delay method on your button so that it won't get clicked immediately next time. If you are using rx android you can use below method. or you can create your own simple logic.
RxView.clicks(view).throttleFirst(500, TimeUnit.MILLISECONDS).subscribe(empty -> {
// action on click
});

Android start activity of second app having no icon from first app

I am having two apps. First app has an activity from which I want to launch an activity from the second app. I am using the following code:
Intent launchIntent = m_context.getPackageManager().getLaunchIntentForPackage(m_packageName);
if (launchIntent != null) {
m_context.startActivity(launchIntent);
}
This code is working very fine to launch the activity from the second app but I want to have the second application without any icon. I am using following code in MainActivity of the second application to remove icon:
PackageManager p = getPackageManager();
//Removing app icon
ComponentName componentName = new ComponentName(this, com.tools.html2pdf.MainActivity.class);
p.setComponentEnabledSetting(componentName, PackageManager.COMPONENT_ENABLED_STATE_DISABLED, PackageManager.DONT_KILL_APP);
This code successfully removes the launcher icon but then activity from my first application is unable to launch the activity from second app.
Can any one help me in this regard? I want to launch activity of an app having no icon from activity of another application.
When you disable the component like you have done, that component can't be launched in any way. However, interesting thing is that other components (non-disabled activities) of your second application are still launchable.
So, you can create an alias of your MainActivity in the second application which will be used for your purpose. Let's call alias as MainActivityAlias.
From your first application, call the intent on MainActivity. The code for disabling the component will be executed and nothing will open. However, the icon will be gone because this component is disabled and everything related to this component (i.e icon) is gone too.
Now, call the intent on MainActivityAlias just after above intent in the first application. This is just a copy of MainActivity but it does not have any code for disabling and thus, it is enabled and launchable.
Some Side Notes :
1) Both activities should have an <intent-filter> with android.intent.action.MAIN.
2) Your MainActivity should be the launcher activity and thus should have android.intent.category.LAUNCHER in the manifest.
3) Inside MainActivity, you have to check where the call is coming from. If the call is from the first application, then execute the code to disable icon which you mentioned in the question. If the call is coming from launcher icon, then open MainActivityAlias using intent. You can know where the call is coming from like this.
Note - This is just an idea. I have not tested it.
If you don't want the second app to have an app icon, just remove the <intent-filter> with ACTION=MAIN and CATEGORY=LAUNCHER for the root Activity in the second app. When the app is installed, if there is no <intent-filter> with ACTION=MAIN and CATEGORY=LAUNCHER, there will be no app icon shown.
Your app can still launch the second app, but not with the method you've described, since Android doesn't know which is the "launch" Activity. Assuming you know the package and class name of the Activity you want to launch in the second app, you can launch it like this:
Intent launchIntent = new Intent();
launchIntent.setClassName("second.package.name", "fully.qualified.class.name.of.MainActivity");
// add and Intent flags if necessary here
launchIntent.addFlags(Intent.FLAG_ACTIVITY_...);
startActivity(launchIntent);

Lollipop: making my activity stay in the task that launched the share intent

“My First App” has an activity that handles a “share” intent. Its activity in AndroidManifest.xml looks like this:
<activity
android:name="com.example.foo.myfirstapp.MainActivity"
android:label="#string/app_name">
<intent-filter>
<action android:name="android.intent.action.SEND"/>
<category android:name="android.intent.category.DEFAULT"/>
<data android:mimeType="image/jpeg"/>
</intent-filter>
</activity>
In KitKat, sharing an image from the album to “My First App” causes MainActivity to be part of the album’s task. This is the desired behavior.
In Lollipop, sharing an image from the album to “My First App” causes a new instance of “My First App” to be launched. If I look at the overview screen, the album task is there...and then there's a separate entry for "My First App". If I share another image, I wind up with two instances of "My First App"...etc.
Question: How do I make Lollipop process the share intent in the same way as KitKat?
Here's what I've done:
I notice that the intents sent from the Album have different flags set depending on the OS. (I got these using getIntent() and looking at mFlags.)
Kitkat: 0x80001 (524289): FLAG_GRANT_READ_URI_PERMISSION, FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET
Lollipop: 0x18080001 (403177473): FLAG_GRANT_READ_URI_PERMISSION, FLAG_ACTIVITY_MULTIPLE_TASK, FLAG_ACTIVITY_NEW_DOCUMENT, FLAG_ACTIVITY_NEW_TASK
From reading http://developer.android.com/reference/android/content/Intent.html, it seems that these last three flags are causing the problem. Specifically
When paired with FLAG_ACTIVITY_MULTIPLE_TASK both of these behaviors (FLAG_ACTIVITY_NEW_DOCUMENT or FLAG_ACTIVITY_NEW_TASK) are modified to skip the search for a matching task and unconditionally start a new task.
I’ve been attempting to “override” these flags by specifying android:launchMode and android:documentLaunchMode in the activity in AndroidManifest.xml without success.
From http://developer.android.com/reference/android/R.attr.html#documentLaunchMode, using documentLaunchMode “never” seems promising, since
This activity will not be launched into a new document even if the Intent contains Intent.FLAG_ACTIVITY_NEW_DOCUMENT. This gives the activity writer ultimate control over how their activity is used.
but this didn't work.
I also considered android:taskAffinity, but there doesn’t seem to be a way to say “please prefer whatever task launched you”.
Afraid you can't do anything about this. It isn't under your control. This is a change in the way the "Album" app is launching its "share" Intent. If it doesn't want your Activity in its task, you can't force it in there.
If you have issues with having multiple instances of your "share" activity, you could declare your "share" activity as launchMode="singleTask" or launchMode="singleInstance" (depending on your needs. This may, however, break other things.

excludeFromRecents doesn't work with taskAffinity

Possible duplicate:
How to not show app on recent apps list in ICS? excludeFromRecents doesn't work
Let's say I have two activities A (the main activity) and B. I start B from A as follows:
Intent i = new Intent(A.this, B.class);
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(i);
I want my app to have just one entry in the recents at any time AND B to be started at a new task. If B has a manifest entry as follows, I achieve that:
<activity
android:name="com.example.verysimpleactivity2.app.B"
android:excludeFromRecents="true"
android:label="B" ></activity>
But I also want B to have a different taskAffinity than the main activity, i.e. A. So I change the manifest entry into:
<activity
android:name="com.example.verysimpleactivity2.app.B"
android:excludeFromRecents="true"
android:taskAffinity=""
android:label="B" ></activity>
In this case, if B is not in the foreground then it does not show up in the recents and I only have A (good!) However, if B is in the foreground and I press recents button, I see both A and B there. Why is B shown in the recents in this case? How to make sure I don't see B at all?
Apparently, it is impossible to achieve what I want (at least in KitKat).
Source: an Android engineer
A bit late but also adding the answer from androidManifest activity android:excludeFromRecents works. Just in case anyone else was having the same issue and though it couldn't work.

More than one instance of activity due to intent

For an App I am developing, I override the back button to make it act like the home button so that the state of the main activity is preserved even when the app is exited. Now, I also send a notification to the user from time to time using a service. When this notification is pressed I want to open the main activity again. I noticed though that this creates a second instance of the app, which creates major problems. I am trying to make the main activity go to the front again, without calling oncreate again like so:
Intent to launch main activity again:
Intent notificationIntent = new Intent(this, MainActivity.class);
notificationIntent.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
This doesn't work though. I still end up with two instances of my main activity. Does anybody know how to fix this?
By the way, I already have android:launchMode="singleInstance" in my manifest.
There's a way to force the OS to create only one instance of an activity and thats using the tag launchMode in the Manifest as shown below:
<activity android:name="YourActivity"
android:launchMode="singleInstance"/>
Hope this Helps...
Regards
Try adding this flag to the intent .addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP), works for me.

Categories

Resources