unoplatform / uno

Open-source platform for building cross-platform native Mobile, Web, Desktop and Embedded apps quickly. Create rich, C#/XAML, single-codebase apps from any IDE. Hot Reload included! 90m+ NuGet Downloads!!
https://platform.uno
Apache License 2.0
8.89k stars 720 forks source link

[Android] It can take 1min + for the `NetworkStatusChanged` to be raised after you change from Wifi to LTE in the background #11008

Open Marc-Antoine-Soucy opened 1 year ago

Marc-Antoine-Soucy commented 1 year ago

Current behavior

When you put the app in background, and then close the wifi with LTE available. When you return to the the app, the the NetworkStatus is LocalAccess instead of internet access, despite the app having access to the internet. I think this is because android doesnt allow the app to access the internet when you change to lte with the app in background. And since we're always using lte, the NetworkStatus changed doesnt know it should be called despite the app having access to internet when coming back.

As said in the title, it can last more than 1 min. The amount of time this takes is very inconsistent. Sometimes, it's pretty much instant. To make it last as long as you can, I think the best way is to enter the app with wifi enabled, wait 5 sec, put the app in background, wait another few seconds (and I think it works better if you check other apps while the main app is in background), disable wifi, wait another few seconds, and then go to the app again. Most of the time, it takes around 40s when I do it this way, but sometimes, I get it to last ~70 sec, just like in this gif: wifitoLTE

Expected behavior

When you return to the app, the Network Status should be reevaluated.

How to reproduce it (as minimally a

InternetAccess.zip nd precisely as possible)

Workaround

The workaround I am using which seems to work is to suscribe to the Window.Activated Event and check with NetworkInformation.GetInternetConnectionProfile()?.GetNetworkConnectivityLevel() with a small loop in case it didnt work the first time. It seems to work all the time I've tried.

void OnCurrentWindowActivated(object sender, WindowActivatedEventArgs e)
{
    bool noInternetAccess = GetHasNoInternetAccess();
        interlocked.Exchange(ref hasAccess!, new TaskCompletionSource<bool>()).TrySetResult(noInternetAccess);

        for (int i = 0; i < 4 || noInternetAccess == true; i++)
    {
            Task.Delay(1000);
                noInternetAccess = GetHasNoInternetAccess();
                Interlocked.Exchange(ref hasAccess!, new TaskCompletionSource<bool>()).TrySetResult(noInternetAccess);

        }
}

Works on UWP/WinUI

N/A

Environment

WinUI

NuGet package version(s)

    <PackageReference Include="Uno.WinUI" Version="4.7.0-dev.981" />
    <PackageReference Include="Uno.WinUI.RemoteControl" Version="4.7.0-dev.981" Condition="'$(Configuration)'=='Debug'" />
    <PackageReference Include="Uno.UI.Adapter.Microsoft.Extensions.Logging" Version="4.6.39" />
    <PackageReference Include="Microsoft.Extensions.Logging.Console" Version="5.0.0" />
    <PackageReference Include="Uno.WinUI.Lottie" Version="4.6.39" />

Affected platforms

Android

IDE

Windows VS 2022

IDE version

17.4.1

Relevant plugins

None

Anything else we need to know?

Marc-Antoine-Soucy commented 1 year ago

I pressed on some keys that posted the issue when I was starting to write it. it will be complete in a few minutes.

jeromelaban commented 1 year ago

Note for contributors

This may be related to this method: https://github.com/unoplatform/uno/blob/f395100f8b8b3cdbea1641ea22d2036e4f103f62/src/Uno.UWP/Networking/Connectivity/NetworkInformation.Android.cs#L150-L167

Which uses a Task.Delay for raising the event and misbehave when the app is paused. It may also be a native behavior, where the native API does not provide the information in a timely manner.