I'm working on a Xamarin based Mobile Application in which this functionality works as expected and seems to have broken in Android 14.
When either changing Activity, or returning to the application from a browser for SSO login, instead of resuming the existing process it's creating a new instance of the application and providing me with a blank screen with my AndroidManifest label on the top of the screen.
I believe I've addressed the BroadcastReceiver changes outlined [https://developer.android.com/about/versions/14/behavior-changes-14#system-broadcasts%5C](here) so I don't think that's it.
Initially the application would create a SplashScreen and transfer to the MainActivity with this method:
StartActivity(new Intent(this, typeof(MainActivity)));
This was creating a second instance of the application and leading into the login/sso process. While testing through, I'm at the point where I've removed that and now start the app directly into MainActivity, which is not creating the new instance and opens the browser window for Microsoft Login as expected
Now however after logging into Microsoft account instead of returning to the original application as it does in Android 13 and prior, it's creating that new instance as seen before with a blank page and title label.
Here's the SSO Login Code:
public async Task<UserToken> OnSignInAsync()
{
UserToken currentUser = null;
if (publicClientApplication == null)
{
this.publicClientApplication = PublicClientApplicationBuilder.Create(ClientID)
.WithIosKeychainSecurityGroup(AppInfo.PackageName)
.WithRedirectUri($"msal{ClientID}://auth")
.Build();
}
var accounts = await this.publicClientApplication.GetAccountsAsync();
try
{
try
{
var firstAccount = accounts.FirstOrDefault();
var authResult = await this.publicClientApplication.AcquireTokenSilent(Scopes, firstAccount).ExecuteAsync();
currentUser = await this.RefreshUserDataAsync(authResult?.AccessToken).ConfigureAwait(false);
if (currentUser == null)
throw new MsalUiRequiredException("0","Unable to get current user information.");
}
catch (MsalUiRequiredException ex)
{
// the user was not already connected.
try
{
var authResult = await this.publicClientApplication.AcquireTokenInteractive(Scopes)
.WithParentActivityOrWindow(ParentWindow)
.ExecuteAsync();
currentUser = await this.RefreshUserDataAsync(authResult?.AccessToken).ConfigureAwait(false);
}
catch (Exception ex2)
{
// Manage the exception with a logger as you need
System.Diagnostics.Debug.WriteLine(ex2.ToString());
}
}
if (currentUser != null)
{
currentUser.LoginModelOAuth = new LoginModelOAuth();
currentUser.LoginModelOAuth.iv = Constants.IV;
currentUser.LoginModelOAuth.kv = EncryptAES(currentUser.UserPrincipalName, Constants.IV);
}
}
catch (Exception ex)
{
// Manage the exception with a logger as you need
System.Diagnostics.Debug.WriteLine(ex.ToString());
throw(ex);
}
return currentUser;
}
I found an answer to this issue here but depends on some of your Activity configuration. This helped me, so I hope it helps you.
In Android 14, it appears an Activity with LaunchMode SingleInstance won't receive these redirects. Changing to SingleTask resolved it.