I had an app that used to open the phone browser, where the user would be redirected to my webapp, where after a certain user action, the webapp redirects back to the app using intent filters
<application>
<activity
android:name="com.xyz.sdk.SomeActivity"
android:allowTaskReparenting="true"
android:configChanges="keyboardHidden|orientation|keyboard|screenSize"
android:launchMode="singleTask"
android:noHistory="true"
android:theme="@android:style/Theme.NoTitleBar">
<intent-filter>
<data android:scheme="someString-${applicationId}" />
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
</intent-filter>
</activity>
</application>
Recently I migrated to using Chrome Custom Tabs instead of browser (Webview is not an option due to security concerns)
Unfortunately, when redirecting back to app in chrome custom tabs the chrome custom tab does not auto close. Even though i can verify via logs that the app has received the response, the custom tab remains open and stays on top, so the user cant see whats happening on the app, until he closes the app.
One workaround i found to this was to set the NEW_TASK flag while initiating my custom tab, but that makes my app and the custom tab show up as two separate apps which is the entire reason I moved away from browsers in the first place.
In summary: I have App A, which opens a custom tab, the webapp opened in the custom tab redirects back to App A using intent filters, but the vustom tab does not close and remains on top until the user manuall closes it.
I have tried setting the NO_HISTORY flag for the custom tab intent but it made no difference.
custom tab code:
CustomTabsIntent customTabsIntent = new CustomTabsIntent.Builder()
.setShowTitle(true)
.setToolbarColor(getToolBarColor())
.setStartAnimations(this, android.R.anim.slide_in_left, android.R.anim.slide_out_right)
.setExitAnimations(this, android.R.anim.slide_in_left, android.R.anim.slide_out_right)
.build();
customTabsIntent.intent.setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
customTabsIntent.launchUrl(this, Uri.parse(url));
customTabsIntent.launchUrl(this, Uri.parse(url));
UPDATE I have realized that if the intent filter redirect back to a different app, then the custom tab closes successfully (provided its a singletop activity and no history is set to true) But in my case, we need to redirect back to the same activity from which custom tabs was invoked.
I also faced the same issue, but in my case its now working.
I launched the custom tab with FLAG_ACTIVITY_NO_HISTORY and FLAG_ACTIVITY_CLEAR_TOP.
customTabsIntent.intent.setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
customTabsIntent.intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
And launchMode of my activity was "singleTop".
<activity
android:name=".SomeActivity"
android:theme="@style/SomeTheme"
android:configChanges="keyboardHidden|orientation|screenSize"
android:noHistory="true"
android:launchMode="singleTop" >
<intent-filter>
<data android:scheme="intent" />
<data android:scheme="myFile" />
<data android:scheme="myScheme" />
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
</intent-filter>
</activity>
An important update by @bkant:
I was able to get this to work by changing the launch mode from 'singleTop' to either 'singleTask' or 'singleInstance'. In this mode, the redirect will come to the same Activity via 'onNewIntent'.
This problem can exist in Xamarin too and the answer applies to issue when using Xamarin.Forms. It can be applied by modifying the Activity attribute. Modify the code to match LaunchMode = LaunchMode.SingleTask
Here is a modified example of Xamarain.Auth from https://developer.xamarin.com/samples/xamarin-forms/WebServices/OAuthNativeFlow/
namespace OAuthNativeFlow.Droid
{
[Activity(Label = "CustomUrlSchemeInterceptorActivity", NoHistory = true, LaunchMode = LaunchMode.SingleTask)]
[IntentFilter(
new[] { Intent.ActionView },
Categories = new[] { Intent.CategoryDefault, Intent.CategoryBrowsable },
DataSchemes = new[] { "<insert custom URL here>" },
DataPath = "/oauth2redirect")]
public class CustomUrlSchemeInterceptorActivity : Activity
{
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
// Convert Android.Net.Url to Uri
var uri = new Uri(Intent.Data.ToString());
// Load redirectUrl page
AuthenticationState.Authenticator.OnPageLoading(uri);
Finish();
}
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With