I am using Branch IO in my application and as per their documentation, I am using android:launchMode="singleTask" for my activity.
Here is some code snippet of my AndroidManifest.
<activity
android:name=".SplashScreen"
android:launchMode="singleTask"
android:screenOrientation="portrait"
android:windowSoftInputMode="stateAlwaysHidden|adjustPan">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<intent-filter>
<data
android:host="open"
android:scheme="com.package.name" />
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
</intent-filter>
<!-- Branch App Links (optional) -->
<intent-filter android:autoVerify="true">
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data
android:host="app.link"
android:scheme="https" />
<!-- <data android:scheme="https" android:host="example-alternate.app.link" /> -->
</intent-filter>
</activity>
Everything is working fine except when I press Home button while using app and tap on App/Launcher Icon, onCreate method of Splash screen activity is called which makes it looks like app is launched from beginning. However, if I press home button while using an app and open it from recent apps, onCreate is not called and everything works perfectly.
How do I make consistent app behavior when brought to foreground from recent apps and App/Launcher icon?
I tried removing singleTask launch mode which makes launch perfect from App/Launcher icon and recent apps but when tapped on branch IO link, the new instance of an app is created. I can understand that to overcome this problem only they are asking to put singleTask in launch mode.
I have checked for this scenario in many apps which are using deep links and they do not have this problem!
I must be doing something wrong which I cannot see.
Is something is missing or implementation is wrong?
Solution to this problem is moving to Single activity architecture.
As splash activity is singleTask, onStart method of it will be called each time when the app is brought to foreground from launcher icon. One has to write routing logic in onStart method, when another activity is started from here, app state will lose.
If a single activity is there, this problem will not be there. However one will have to deal with nasty fragment backstacks. Not an easy but correct approach.
For a quick workaround, one can use this code in onCreate method of activity with launchmode as singleTask.
if ((getIntent().getFlags() & Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT) != 0) {
return;
}
This might help to avoid unnessary execution of code written in onCreate. However this is a recommended solution as it doesn't solve rootcause of problem.
Related
My activity definition looks like this:
<activity
android:name="com.broadvision.myvv.MyVV_Splash"
android:screenOrientation="portrait">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="vmoso" />
<data
android:host="www.vmoso.com"
android:scheme="http" />
</data>
</intent-filter>
</activity>
This activity is root activity in my app, it can be started from browser app, after this, if I hit browser icon, what I want to see is the browser UI, but in fact, I still see my own app, which is incorrect.
I've tried to add android:launchMode="singleInstance" and android:launchMode="singleTask", it works for this case, i.e.: my app activity starts as a new task, and I can switch back to browser, but when I hit my app icon from home screen, it always starts as a new task, which is not what I want to see, I want to see the last Activity when I leave.
Also tried android:allowTaskReparenting="true", but doesn't work, I believe the point is on launchMode, but after tried all 4 modes, still cannot figure it out.
So I have such tricky thing declared in Manifest to be able to start my app from a browser:
<activity android:name=".BrowserIntentCallBackActivity"
android:noHistory="true" >
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data
android:host="*"
android:scheme="trickyapp" />
</intent-filter>
</activity>
this workds ok and starts my BrowserIntentCallBackActivity as expected. If my app wasnt previously started then finishing the BrowserIntentCallBackActivity returns user back to browser and its fine.
However if my app was previuosly started and is running on background finishing the BrowserIntentCallBackActivity returns user to previuos activity of my app. But I want to send user back to browser where he/she clicked the very special link and from where my BrowserIntentCallBackActivity was launched by intent. And I dont want ot kill my running app.
How to achieve this?
Try setting the launch mode of your activity:
https://developer.android.com/guide/topics/manifest/activity-element.html#lmode
I believe the correct mode for your task will be "singleTask" or maybe "singleInstance", although I have limited experience with those so you will have to experiment to be sure.
I do not know if you get my question right, so let me explain:
My app is shown in the chooser after user clicks a web link in any other app, then user clicks on my app and my app shows the link in a webview. This works fine.
But, the problem is when the user launches the other app again (which invoked my app earlier) with a click on the icon that is on the home screen or app drawer, it opens my app again instead of the origin app.
Manifest:
<activity
android:name="com.droidfox.app.browser"
android:label="#string/browser"
android:theme="#android:style/Theme.Black.NoTitleBar"
android:launchMode="singleTop"
android:configChanges="orientation|keyboardHidden|keyboard|screenSize" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="http" />
<data android:scheme="https" />
</intent-filter>
</activity>
Back Button Override:
#Override
public void onBackPressed ()
{
moveTaskToBack(true);
}
Does anyone have a clue why the other app launches my app and how can I fix this?
Try to set android:noHistory for your given activity.
Taken from documentation:
Whether or not the activity should be removed from the activity stack and finished (its finish() method called) when the user navigates away from it and it's no longer visible on screen — "true" if it should be finished, and "false" if not. The default value is "false".
A value of "true" means that the activity will not leave a historical trace. It will not remain in the activity stack for the task, so the user will not be able to return to it.
I've searched documentation, but I'm missing something obvious. Or am trying to do something backwards.
What I have is the main activity, that's fired from the launcher and widgets. I have a second activity that I'd like to be fired off when a URL of a specific pattern is attempted to be opened. Here's the two activity definitions:
<activity android:name=".activities.MainMapScreen" 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.ViewDatasheet" android:configChanges="orientation|keyboardHidden" android:label="#string/app_name" android:process=":BMMapsDatasheet">
<meta-data android:name="Main Screen" android:value=".activities.MainMapScreen" />
<intent-filter>
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="http" android:host="www.ngs.noaa.gov" android:pathPattern="\\/cgi-bin\\/ds_mark.prl\\?PidBox\\=([a-zA-Z]{2}[0-9]{4})" />
</intent-filter>
</activity>
Like the above, url's aren't intercepted. Even if I have nothing in the data but the scheme and host, I don't get the prompt to select my app.
As a test, I copied the browsable and to the main activity, and when I do that, the icon disappears form the launcher altogether. (And I still get no prompt when trying to hit the URL.
All the examples I find has the in the main activity, not a secondary activity, so.. I'm not sure if I'm missing some flags or such.
Any thoughts would be appreciated. If you want me to post the whole Manifest, let me know.
--Mike.
Edit: After adding #iturki suggestions, there was no change. however - if I also added <category android:name="android.intent.category.OPENABLE" /> to the action to handle the URLs, that worked. None of the examples I saw with the had that category, so I'm not yet sure if it would affect other operations of the activities in my application or not.
Try adding a VIEW action to your second Activity's <intent-filter>:
<action android:name="android.intent.action.VIEW"></action>
And I think you might want to add your Intent to the DEFAULT category too:
<category android:name="android.intent.category.DEFAULT"></category>
I'm not sure if it is important but all the <intent-filter>s have this category.
I've an application with a lot of activities. When returning from desktop or lockscreen, the expected behaviour is, that the last used activity is shown again.
This works flawlessly if the application is started again from the normal desktop icon. But if I add it to the lockscreen "widgetlocker" and start it from there, there is always the main activity shown. And unfortunately, if I close the main activity later by returning via back button, I return to all other instances of this main activity.
It might be related to the fact that I'm returned to the lockscreen when closing the application directly after having opened it from the lockscreen.
But I'm quite puzzled why the behaviour is different if I open from lockscreen or open normally.
Any suggestions? How can I force the application to be ALWAYS return to the last used screen?
...
# main activity:
<activity android:name="StudyOptions"
android:launchMode="singleTask"
android:configChanges="keyboardHidden|orientation|locale">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="com.ankidroid.category.DECK" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="application/vnd.anki" />
</intent-filter>
</activity>
<activity android:name="DeckPicker"
android:label="DeckPicker"
android:configChanges="keyboardHidden|orientation|locale"/>
...
how about maintaining the activity changes like a state machine. Giving a state number for each activity and persist the current in the database. And recover the last state from the database on startup and display the corresponding activity.