Skip to content

[Bug] MAUI - App shut down by OS on Android 15. Fine on 14. Anyone else have this problem? #5273

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
MarkEvans8 opened this issue May 13, 2025 · 1 comment
Labels
needs attention Delete label after triage public-client untriaged Do not delete. Needed for Automation

Comments

@MarkEvans8
Copy link

Library version used

4.72.0

.NET version

9

Scenario

PublicClient - mobile app

Is this a new or an existing app?

This is a new app or experiment

Issue description and reproduction steps

This app has been working fine for months with Android 14, but authentication fails with Android 15 (API 35). I have tested it with several different emulators and an OPPO phone running Android 14 and then 15. It worked fine until I updated the OS on my phone.

When I click the login button in the app, it launches the browser. Then the application shuts down. The logs appear to show that the OS is shutting down the app. See logs below. The app is called "kidsareeverywhere".

I've wasted many hours trying to fix this. I'm wondering if it's a problem with MSAL? Has anyone else experienced this?

Device Logs

05-13 17:32:54.649 pixel_7_pro_-_api_35 Info 574 AppsFilter interaction: PackageSetting{977c70b com.android.microdroid.empty_payload/10197} -> PackageSetting{502e9ce com.kidsareeverywhere.kae3_0/10214} BLOCKED

...............

05-13 17:32:54.631 pixel_7_pro_-api_35 Info 574 ActivityManager Killing 12863:com.kidsareeverywhere.kae3_0/u0a214 (adj 700): stop com.kidsareeverywhere.kae3_0 due to from pid 14764
05-13 17:32:54.631 pixel_7_pro
-api_35 Debug 574 DisplayManagerService Drop pending events for gone uid 10214
05-13 17:32:54.629 pixel_7_pro
-_api_35 Info 574 ActivityManager Force stopping com.kidsareeverywhere.kae3_0 appid=10214 user=0: from pid 14764

...............

05-13 17:32:48.102 pixel_7_pro_-_api_35 Info 574 AppsFilter interaction: PackageSetting{fcb0413 com.kidsareeverywhere.kae3_0/10214} -> PackageSetting{efca1c4 com.android.chrome/10146} BLOCKED

...................

05-13 17:32:48.077 pixel_7_pro_-api_35 Info 12863 DOTNET ############# MSAL [Warning] False MSAL 4.72.0.0 MSAL.Xamarin.Android .NET 9.0.4 35 [2025-05-13 07:32:48Z - 4d4da9e3-8251-4e98-8f43-dfbe3184adc4] Browser with custom tabs package not available. Launching with alternate browser. See https://aka.ms/msal-net-system-browsers for details.
05-13 17:32:48.075 pixel_7_pro
-_api_35 Info 574 AppsFilter interaction: PackageSetting{fcb0413 com.kidsareeverywhere.kae3_0/10214} -> PackageSetting{efca1c4 com.android.chrome/10146} BLOCKED

Relevant code snippets

### AndroidManifest.xml

<manifest xmlns:android="http://schemas.android.com/apk/res/android">
  <application
      android:label="Kids are Everywhere 3.0"
      android:allowBackup="true"
      android:icon="@mipmap/appicon"
      android:roundIcon="@mipmap/appicon"
      android:supportsRtl="true"
      android:networkSecurityConfig="@xml/network_security_config"
      android:usesCleartextTraffic="true">
  </application>
  <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
  <uses-permission android:name="android.permission.INTERNET" />
  <meta-data android:name="android.webkit.WebView.EnableSafeBrowsing" android:value="true" />  
</manifest>




### MainActivity.cs

[Activity(Theme = "@style/Maui.SplashTheme", MainLauncher = true,
    LaunchMode = LaunchMode.SingleTask, 
    ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation | ConfigChanges.UiMode | ConfigChanges.ScreenLayout | ConfigChanges.SmallestScreenSize | ConfigChanges.Density)]
public class MainActivity : MauiAppCompatActivity
{
    protected override void OnCreate(Bundle? savedInstanceState)
    {
        UiContext.ParentWindow = this;// I moved this up above the base.OnCreate method
        base.OnCreate(savedInstanceState);
    }

    protected override void OnActivityResult(int requestCode, Result resultCode, Intent? data)
    {
        Console.WriteLine($"############ OnActivityResult: requestCode={requestCode}, resultCode={resultCode}, data={data?.ToString() ?? "null"}");

        base.OnActivityResult(requestCode, resultCode, data);

        // Return control to MSAL
        AuthenticationContinuationHelper.SetAuthenticationContinuationEventArgs(requestCode, resultCode, data);
    }
}




### MainApplication.cs

//[Application]
[Application(UsesCleartextTraffic = true)] // hack! Added to get http working on the android emulator so it could talk to api on localhost. This is a security risk. Remove for prod
public class MainApplication : MauiApplication
{
    public MainApplication(IntPtr handle, JniHandleOwnership ownership)
        : base(handle, ownership)
    {
    }

    protected override MauiApp CreateMauiApp() => MauiProgram.CreateMauiApp();
}




### MsalActivity.cs

[Activity(Exported = true)]
[IntentFilter(new[] { Intent.ActionView },
    Categories = new[] { Intent.CategoryBrowsable, Intent.CategoryDefault },
    DataHost = "auth",
    DataScheme = "msal<clientId>")]
public class MsalActivity : BrowserTabActivity
{
}




### AuthManager.cs

public class AuthManager
{
    private readonly ISettingsService _mobileSettingsService;
    private readonly IPublicClientApplication _msalClient;

    public AuthManager(ISettingsService mobileSettingsService)
    {
        _mobileSettingsService = mobileSettingsService;        

        Console.WriteLine($"#######  ClientId: {_mobileSettingsService.ClientId}, Authority: {_mobileSettingsService.Authority}, IOSKeychainSecurityGroup: {_mobileSettingsService.IOSKeychainSecurityGroup}, TenantId: {_mobileSettingsService.TenantId}");

        _msalClient = PublicClientApplicationBuilder
            .Create(_mobileSettingsService.ClientId)
            .WithAuthority(_mobileSettingsService.Authority)
            .WithIosKeychainSecurityGroup(_mobileSettingsService.IOSKeychainSecurityGroup)
            .WithRedirectUri($"msal{_mobileSettingsService.ClientId}://auth")
            .WithTenantId(_mobileSettingsService.TenantId) // added to try and get android 15 working. Probably not needed.

#if ANDROID
            .WithBroker(false)// added to try and get android 15 working. Probably not needed.
            .WithParentActivityOrWindow(() => Platform.CurrentActivity)// added to try and get android 15 working. Probably not needed.            
#endif            
            // Keep this
            .WithLogging((level, message, containsPii) =>
            {
                Console.WriteLine($"############# MSAL [{level}] {message}");
            }, LogLevel.Verbose, enablePiiLogging: false, enableDefaultPlatformLogging: true)
            .Build(); 
    }

    public async Task<AuthenticationResult?> AuthenticateMsalAsync(bool allowInteractiveLogin)
    {
        var accounts = await _msalClient.GetAccountsAsync();
        var firstAccount = accounts.FirstOrDefault();

        if (firstAccount == null)
            if(allowInteractiveLogin)
                return await InteractiveLogin();
            else
                return null;

        // Account found so we can try silent login
        try
        {
            return await SilentLogin(firstAccount);
        }
        catch (MsalUiRequiredException ex)
        {
            Console.WriteLine($"####  AuthManager.AuthenticateMsalAsync. MsalUiRequiredException. This exception is thrown when the token is expired or the user needs to re-authenticate. Ex: {ex}");
            // Token expired so log in interactively
            await LogoutMsalAsync(); // having trouble with expired tokens on iOS. Maybe this helps?

            if (allowInteractiveLogin)
                return await InteractiveLogin();
            else
                return null;
        }
    }

    private async Task<AuthenticationResult?> InteractiveLogin()
    {
        return await _msalClient.AcquireTokenInteractive(_mobileSettingsService.Scopes)
        .WithParentActivityOrWindow(UiContext.ParentWindow)
        //#if ANDROID
        //            .WithUseEmbeddedWebView(true) // Keep this. Only way to get this app working with Android 15 at the moment :(
        //#endif
        .ExecuteAsync();
    }


    private async Task<AuthenticationResult?> SilentLogin(IAccount? firstAccount)
    {
        // Silent login
        var stopwatch = System.Diagnostics.Stopwatch.StartNew();

        var result = await _msalClient
                        .AcquireTokenSilent(_mobileSettingsService.Scopes, firstAccount)
                        .ExecuteAsync();

        stopwatch.Stop();
        Console.WriteLine($"#######################  SilentLogin completed in {stopwatch.ElapsedMilliseconds} ms");
        Console.WriteLine($"#######################  Token expires on: {result.ExpiresOn}");

        return result;
    }
  
    public async Task LogoutMsalAsync()
    {
        try
        {
            var accounts = await _msalClient.GetAccountsAsync();

            while (accounts.Any())
            {
                await _msalClient.RemoveAsync(accounts.First());
                accounts = await _msalClient.GetAccountsAsync();
            }
        }
        catch (System.Exception ex)
        {
            Console.WriteLine($"#### Logout error: {ex}");
            throw;
        }
    }
}




### Project file (some irrelevant stuff removed)

<Project Sdk="Microsoft.NET.Sdk.Razor">

  <PropertyGroup>
    <TargetFrameworks>net9.0-ios;net9.0-android35.0</TargetFrameworks>
    <TargetFrameworks Condition="$([MSBuild]::IsOSPlatform('windows'))">$(TargetFrameworks);net9.0-windows10.0.19041.0</TargetFrameworks>



    <OutputType>Exe</OutputType>
    <RootNamespace>Kae.Mobile</RootNamespace>
    <UseMaui>true</UseMaui>
    <SingleProject>true</SingleProject>
    <ImplicitUsings>enable</ImplicitUsings>
    <EnableDefaultCssItems>false</EnableDefaultCssItems>
    <Nullable>enable</Nullable>

    <!-- Disable warning about not being AOT compatible with WinRT (Windows I think) -->
    <NoWarn>$(NoWarn);MVVMTK0045</NoWarn>
    <!-- Disable warning about "Use Pattern Matching". I think in many cases it makes the code harder to read. -->
    <NoWarn>$(NoWarn);IDE0019</NoWarn>
    
    <!-- Added to fix compile warnings "binding not compiled" -->
    <!--MauiEnableXamlCBindingWithSourceCompilation>true</MauiEnableXamlCBindingWithSourceCompilation--> 

    <!-- Display name -->
    <ApplicationTitle>Kae.Mobile</ApplicationTitle>

    <!-- App Identifier -->
    <ApplicationId>com.kidsareeverywhere.kae3-0</ApplicationId>
    <!--ApplicationId>com.companyname.kae</ApplicationId-->

    <!-- Versions -->
    <ApplicationDisplayVersion>1.0</ApplicationDisplayVersion>
    <ApplicationVersion>1</ApplicationVersion>

    <!-- To develop, package, and publish an app to the Microsoft Store, see: https://aka.ms/MauiTemplateUnpackaged -->
    <WindowsPackageType>None</WindowsPackageType>

    <SupportedOSPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'ios'">15.0</SupportedOSPlatformVersion>
    <SupportedOSPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'maccatalyst'">15.0</SupportedOSPlatformVersion>
    <SupportedOSPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'android'">24.0</SupportedOSPlatformVersion>
    <SupportedOSPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'windows'">10.0.17763.0</SupportedOSPlatformVersion>
    <TargetPlatformMinVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'windows'">10.0.17763.0</TargetPlatformMinVersion>
    <SupportedOSPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'tizen'">6.5</SupportedOSPlatformVersion>
    
    <!-- added to get ios simulator and account working. Hack. I think some/all of this may need to be removed/edited to deploy to read device or app store? -->
    <RuntimeIdentifier Condition="$(TargetFramework.Contains('-ios'))">iossimulator-x64</RuntimeIdentifier>
    <CodesignKey>Apple Development</CodesignKey>
    <CodesignEntitlements>Entitlements.plist</CodesignEntitlements>
    <CodesignProvision></CodesignProvision>
    <MtouchNoSymbolStrip>true</MtouchNoSymbolStrip>
    <MtouchLink>None</MtouchLink>
    <!-- end -->

    <!-- added to get ios sim running on remote machine rather than locally-->
    <UseRemoteSimulator>true</UseRemoteSimulator>
    
    <PackageIcon></PackageIcon>   
  </PropertyGroup>

  <PropertyGroup Condition="'$(TargetFramework)'=='net9.0-ios'">
    <ProvisioningType>manual</ProvisioningType>
  </PropertyGroup>

  <PropertyGroup Condition="'$(Configuration)|$(TargetFramework)|$(Platform)'=='Debug|net9.0-android|AnyCPU'">
    <Optimize>False</Optimize>
  </PropertyGroup>

  <PropertyGroup Condition="'$(Configuration)|$(TargetFramework)|$(Platform)'=='Debug|net9.0-ios|AnyCPU'">
    <Optimize>False</Optimize>
  </PropertyGroup>

  <PropertyGroup Condition="'$(Configuration)|$(TargetFramework)|$(Platform)'=='Debug|net9.0-windows10.0.19041.0|AnyCPU'">
    <Optimize>False</Optimize>
  </PropertyGroup>

  <ItemGroup>
   .........
    
    <!-- trying to fix problem. does this work? needed?-->
    <!--EmbeddedResource Include="Resources\**\*.resx" /-->
  </ItemGroup>

........

  <ItemGroup>
    <PackageReference Include="CommunityToolkit.Maui" Version="11.2.0" />
    <PackageReference Include="CommunityToolkit.Maui.Core" Version="11.2.0">
      <TreatAsUsed>true</TreatAsUsed>
    </PackageReference>
    <PackageReference Include="CommunityToolkit.Mvvm" Version="8.4.0" />
    <PackageReference Include="Microsoft.AspNetCore.Mvc.Abstractions" Version="2.3.0" />
    <PackageReference Include="Microsoft.AspNetCore.SignalR.Client" Version="9.0.4" />
    <PackageReference Include="Microsoft.Identity.Client" Version="4.72.0" />
    <PackageReference Include="Microsoft.Maui.Controls" Version="9.0.60">
      <TreatAsUsed>true</TreatAsUsed>
    </PackageReference>
    <PackageReference Include="Microsoft.AspNetCore.Components.WebView.Maui" Version="9.0.60" />
    <PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="9.0.4" />
    <PackageReference Include="Syncfusion.Maui.Buttons" Version="29.1.41">
      <TreatAsUsed>true</TreatAsUsed>
    </PackageReference>
    <PackageReference Include="Syncfusion.Maui.Calendar" Version="29.1.41" />
    <PackageReference Include="Syncfusion.Maui.Chat" Version="29.1.41" />
    <PackageReference Include="Syncfusion.Maui.DataForm" Version="29.1.41">
      <TreatAsUsed>true</TreatAsUsed>
    </PackageReference>
    <PackageReference Include="Syncfusion.Maui.Popup" Version="29.1.41">
      <TreatAsUsed>true</TreatAsUsed>
    </PackageReference>
    <PackageReference Include="Syncfusion.Maui.Toolkit" Version="1.0.4" />
  </ItemGroup>

  <ItemGroup>
    <ProjectReference Include="..\Kae.Shared\Kae.Shared.csproj" />
  </ItemGroup>

Expected behavior

App launches system browser, user authenticates, MAUI app opens again. This is what happens on Android 14 but not on 15.

Identity provider

Microsoft Entra External ID

Regression

No response

Solution and workarounds

It works if I add ".WithUseEmbeddedWebView(true)" but then the user experience is not as good, and users cannot log in with their Google account.

@MarkEvans8 MarkEvans8 added untriaged Do not delete. Needed for Automation needs attention Delete label after triage labels May 13, 2025
@MarkEvans8
Copy link
Author

MarkEvans8 commented May 13, 2025

I just tried testing the sample here: https://github.com/Azure-Samples/ms-identity-dotnetcore-maui/tree/main/MauiAppBasic

I carefully configured Entra ID and everything else by following the instructions. I had the same problem. It worked in 14 and failed in the same way on 15. The app shut down two seconds after launching the browser. Has this been tested on Android 15?

I have attached the logs from the MauiAppBasic sample running on a Pixel 7 emulator with Android 15.

I started logging just before hitting the authenticate button in the app and stopped logging when the app shut down.

VS Output.txt

VS Device Log.txt

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
needs attention Delete label after triage public-client untriaged Do not delete. Needed for Automation
Projects
None yet
Development

No branches or pull requests

1 participant