Skip to content
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

Adding a Connectivity.ConnectivityChanged handler throw an exception on Android 14 #17861

Closed
daniel-c opened this issue Oct 6, 2023 · 55 comments · Fixed by #18520
Closed

Adding a Connectivity.ConnectivityChanged handler throw an exception on Android 14 #17861

daniel-c opened this issue Oct 6, 2023 · 55 comments · Fixed by #18520
Assignees
Labels
area-essentials Essentials: Device, Display, Connectivity, Secure Storage, Sensors, App Info delighter fixed-in-8.0.6 Look for this fix in 8.0.6 SR1! platform/android 🤖 s/triaged Issue has been reviewed s/verified Verified / Reproducible Issue ready for Engineering Triage t/bug Something isn't working
Milestone

Comments

@daniel-c
Copy link

daniel-c commented Oct 6, 2023

Description

When adding a Connectivity.ConnectivityChanged handler, the following exception is thrown on an Android 14 device, when the targetSdkVersion is 34 (the default with new Maui app) an when run on Android 14:

Exception has occurred: Java.Lang.SecurityException
com.companyname.dotnetmaui: One of RECEIVER_EXPORTED or RECEIVER_NOT_EXPORTED should be specified when a receiver isn't being registered exclusively for system broadcasts
    at Java.Interop.JniEnvironment.InstanceMethods.CallNonvirtualObjectMethod(JniObjectReference instance, JniObjectReference type, JniMethodInfo method, JniArgumentValue* args) in /Users/runner/work/1/s/xamarin-android/external/Java.Interop/src/Java.Interop/obj/Release/net7.0/JniEnvironment.g.cs:20416
    at Java.Interop.JniPeerMembers.JniInstanceMethods.InvokeVirtualObjectMethod(String encodedMember, IJavaPeerable self, JniArgumentValue* parameters) in /Users/runner/work/1/s/xamarin-android/external/Java.Interop/src/Java.Interop/Java.Interop/JniPeerMembers.JniInstanceMethods_Invoke.cs:876
    at Android.Content.ContextWrapper.RegisterReceiver(BroadcastReceiver receiver, IntentFilter filter) in /Users/runner/work/1/s/xamarin-android/src/Mono.Android/obj/Release/net8.0/android-34/mcw/Android.Content.ContextWrapper.cs:2605
    at Microsoft.Maui.Networking.ConnectivityImplementation.StartListeners() in D:\a\_work\1\s\src\Essentials\src\Connectivity\Connectivity.android.cs:48
    at Microsoft.Maui.Networking.ConnectivityImplementation.add_ConnectivityChanged(EventHandler`1 value) in D:\a\_work\1\s\src\Essentials\src\Connectivity\Connectivity.shared.cs:91
    at Microsoft.Maui.Networking.Connectivity.add_ConnectivityChanged(EventHandler`1 value) in D:\a\_work\1\s\src\Essentials\src\Connectivity\Connectivity.shared.cs:58
    at DotnetMaui.App..ctor() in /Users/daniel/Development/Samples/DotnetMaui/App.xaml.cs:9

Steps to Reproduce

  1. Create a new MAUI app with botnet new maui
  2. In the App constructor in App.xaml.cs, add :
    Connectivity.ConnectivityChanged += (sender, e) => { };
  3. Start the app on an Android 14 emulator or device.

Link to public reproduction project repository

No response

Version with bug

8.0.0-rc.1.9171

Is this a regression from previous behavior?

Not sure, did not test other versions

Last version that worked well

Unknown/Other

Affected platforms

Android

Affected platform versions

Android 14

Did you find any workaround?

Change the target Android version to 13. The code will work on Android 14 then.

Relevant log output

Exception has occurred: Java.Lang.SecurityException
com.companyname.dotnetmaui: One of RECEIVER_EXPORTED or RECEIVER_NOT_EXPORTED should be specified when a receiver isn't being registered exclusively for system broadcasts
    at Java.Interop.JniEnvironment.InstanceMethods.CallNonvirtualObjectMethod(JniObjectReference instance, JniObjectReference type, JniMethodInfo method, JniArgumentValue* args) in /Users/runner/work/1/s/xamarin-android/external/Java.Interop/src/Java.Interop/obj/Release/net7.0/JniEnvironment.g.cs:20416
    at Java.Interop.JniPeerMembers.JniInstanceMethods.InvokeVirtualObjectMethod(String encodedMember, IJavaPeerable self, JniArgumentValue* parameters) in /Users/runner/work/1/s/xamarin-android/external/Java.Interop/src/Java.Interop/Java.Interop/JniPeerMembers.JniInstanceMethods_Invoke.cs:876
    at Android.Content.ContextWrapper.RegisterReceiver(BroadcastReceiver receiver, IntentFilter filter) in /Users/runner/work/1/s/xamarin-android/src/Mono.Android/obj/Release/net8.0/android-34/mcw/Android.Content.ContextWrapper.cs:2605
    at Microsoft.Maui.Networking.ConnectivityImplementation.StartListeners() in D:\a\_work\1\s\src\Essentials\src\Connectivity\Connectivity.android.cs:48
    at Microsoft.Maui.Networking.ConnectivityImplementation.add_ConnectivityChanged(EventHandler`1 value) in D:\a\_work\1\s\src\Essentials\src\Connectivity\Connectivity.shared.cs:91
    at Microsoft.Maui.Networking.Connectivity.add_ConnectivityChanged(EventHandler`1 value) in D:\a\_work\1\s\src\Essentials\src\Connectivity\Connectivity.shared.cs:58
    at DotnetMaui.App..ctor() in /Users/daniel/Development/Samples/DotnetMaui/App.xaml.cs:9
    at at System.Reflection.MethodBaseInvoker.InterpretedInvoke_Constructor(Object obj, IntPtr* args)
    at at System.Reflection.MethodBaseInvoker.InvokeWithNoArgs(Object obj, BindingFlags invokeAttr)
    at at System.Reflection.RuntimeConstructorInfo.Invoke(BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
    at at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitConstructor(ConstructorCallSite constructorCallSite, RuntimeResolverContext context)
    at at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2[[Microsoft.Extensions.DependencyInjection.ServiceLookup.RuntimeResolverContext, Microsoft.Extensions.DependencyInjection, Version=8.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60],[System.Object, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]].VisitCallSiteMain(ServiceCallSite callSite, RuntimeResolverContext argument)
    at at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitRootCache(ServiceCallSite callSite, RuntimeResolverContext context)
    at at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2[[Microsoft.Extensions.DependencyInjection.ServiceLookup.RuntimeResolverContext, Microsoft.Extensions.DependencyInjection, Version=8.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60],[System.Object, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]].VisitCallSite(ServiceCallSite callSite, RuntimeResolverContext argument)
    at at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.Resolve(ServiceCallSite callSite, ServiceProviderEngineScope scope)
    at at Microsoft.Extensions.DependencyInjection.ServiceProvider.CreateServiceAccessor(ServiceIdentifier serviceIdentifier)
    at at System.Collections.Concurrent.ConcurrentDictionary`2[[Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceIdentifier, Microsoft.Extensions.DependencyInjection, Version=8.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60],[Microsoft.Extensions.DependencyInjection.ServiceProvider.ServiceAccessor, Microsoft.Extensions.DependencyInjection, Version=8.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60]].GetOrAdd(ServiceIdentifier key, Func`2 valueFactory)
    at at Microsoft.Extensions.DependencyInjection.ServiceProvider.GetService(ServiceIdentifier serviceIdentifier, ServiceProviderEngineScope serviceProviderEngineScope)
    at at Microsoft.Extensions.DependencyInjection.ServiceProvider.GetService(Type serviceType)
    at Microsoft.Maui.MauiContext.WrappedServiceProvider.GetService(Type serviceType) in D:\a\_work\1\s\src\Core\src\MauiContext.cs:68
    at Microsoft.Maui.MauiContext.WrappedServiceProvider.GetService(Type serviceType) in D:\a\_work\1\s\src\Core\src\MauiContext.cs:68
    at at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(IServiceProvider provider, Type serviceType)
    at at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService[IApplication](IServiceProvider provider)
    at Microsoft.Maui.MauiApplication.OnCreate() in D:\a\_work\1\s\src\Core\src\Platform\Android\MauiApplication.cs:46
    at Android.App.Application.n_OnCreate(IntPtr jnienv, IntPtr native__this) in /Users/runner/work/1/s/xamarin-android/src/Mono.Android/obj/Release/net8.0/android-34/mcw/Android.App.Application.cs:1086
    at Android.Runtime.JNINativeWrapper.Wrap_JniMarshal_PP_V(_JniMarshal_PP_V callback, IntPtr jnienv, IntPtr klazz) in /Users/runner/work/1/s/xamarin-android/src/Mono.Android/Android.Runtime/JNINativeWrapper.g.cs:26
    at java.lang.SecurityException: com.companyname.dotnetmaui: One of RECEIVER_EXPORTED or RECEIVER_NOT_EXPORTED should be specified when a receiver isn't being registered exclusively for system broadcasts
    at at android.os.Parcel.createExceptionOrNull(Parcel.java:3057)
    at at android.os.Parcel.createException(Parcel.java:3041)
    at at android.os.Parcel.readException(Parcel.java:3024)
    at at android.os.Parcel.readException(Parcel.java:2966)
    at at android.app.IActivityManager$Stub$Proxy.registerReceiverWithFeature(IActivityManager.java:5684)
    at at android.app.ContextImpl.registerReceiverInternal(ContextImpl.java:1852)
    at at android.app.ContextImpl.registerReceiver(ContextImpl.java:1792)
    at at android.app.ContextImpl.registerReceiver(ContextImpl.java:1780)
    at at android.content.ContextWrapper.registerReceiver(ContextWrapper.java:755)
    at at crc6488302ad6e9e4df1a.MauiApplication.n_onCreate(Native Method)
    at at crc6488302ad6e9e4df1a.MauiApplication.onCreate(MauiApplication.java:28)
    at at android.app.Instrumentation.callApplicationOnCreate(Instrumentation.java:1316)
    at at android.app.ActivityThread.handleBindApplication(ActivityThread.java:6998)
    at at android.app.ActivityThread.-$$Nest$mhandleBindApplication(Unknown Source:0)
    at at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2236)
    at at android.os.Handler.dispatchMessage(Handler.java:106)
    at at android.os.Looper.loopOnce(Looper.java:205)
    at at android.os.Looper.loop(Looper.java:294)
    at at android.app.ActivityThread.main(ActivityThread.java:8177)
    at at java.lang.reflect.Method.invoke(Native Method)
    at at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:552)
    at at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:971)
    at Caused by: android.os.RemoteException: Remote stack trace:
    at at com.android.server.am.ActivityManagerService.registerReceiverWithFeature(ActivityManagerService.java:13908)
    at at android.app.IActivityManager$Stub.onTransact(IActivityManager.java:2570)
    at at com.android.server.am.ActivityManagerService.onTransact(ActivityManagerService.java:2720)
    at at android.os.Binder.execTransactInternal(Binder.java:1339)
    at at android.os.Binder.execTransact(Binder.java:1275)
@daniel-c daniel-c added the t/bug Something isn't working label Oct 6, 2023
@jsuarezruiz jsuarezruiz added platform/android 🤖 area-essentials Essentials: Device, Display, Connectivity, Secure Storage, Sensors, App Info labels Oct 6, 2023
@drasticactions
Copy link
Contributor

drasticactions commented Oct 6, 2023

https://github.com/xamarin/xamarin-android/blob/19d978bc1b6ee04e6dd4b11ec01d2a9c8f6b3e49/src/Mono.Android/Android.Content/Context.cs#L22-L25

There is a breaking change for Android API 34 that requires setting the RecieverFlags. I believe if we update

https://github.com/dotnet/maui/blob/main/src/Essentials/src/Connectivity/Connectivity.android.cs#L48

to this new API,

Application.Context.RegisterReceiver(conectivityReceiver, filter, ReceiverFlags.NotExported);

it would work again... the problem being, it's only in the Android 34 dlls (In that, it's in the preprocessor defs to only be compiled for Android 34, and as far as I can tell can't be referenced on early versions. I'm not sure if MAUI ships multiple editions for essentials that target specific Android versions like that.

@jonpryor @jpobst do ya'll know how to access this API in Essentials? Or did I misunderstand the problem?

@jpobst
Copy link
Contributor

jpobst commented Oct 6, 2023

Context: dotnet/android@d9e4407

This new API will only be available for projects targeting .NET 8+. If you want to be able to call this API for earlier projects you will need to call the incorrectly enumified version that has existed for many years:

https://learn.microsoft.com/en-us/dotnet/api/android.content.context.registerreceiver?view=xamarin-android-sdk-13#android-content-context-registerreceiver(android-content-broadcastreceiver-android-content-intentfilter-android-content-activityflags)

You can cast the enums as needed:

Application.Content.RegisteredReceiver(conectivityReceiver, filter, (ActivityFlags)ReceiverFlags.NotExported);

@XamlTest XamlTest added s/verified Verified / Reproducible Issue ready for Engineering Triage s/triaged Issue has been reviewed labels Oct 10, 2023
@XamlTest
Copy link

Verified this on Visual Studio Enterprise 17.8.0 Preview 2.0(8.0.0-rc.1.9171). Repro on Android 14.0-API34 with below Project:
17861.zip

image

@pasha-o
Copy link

pasha-o commented Oct 11, 2023

verified the issue exists on Xamarin forms as well

@albertruff
Copy link

We also face this issue. Is there any chance to temporary avoid this exception?

@dondestas
Copy link

@albertruff You can temporary avoid this exception by setting the Android targetSdkVersion to 33 instead of 34.

@albertruff
Copy link

@dondestas Thank you. It works

@Redth Redth self-assigned this Nov 3, 2023
@Redth Redth added this to the .NET 8 SR1 milestone Nov 3, 2023
@Redth Redth added the delighter label Nov 3, 2023
@Redth
Copy link
Member

Redth commented Nov 3, 2023

This needs to be updated in other areas too. We need to do an audit of our code base to see where it's implicated and determine the correct values to use.

@Alex-Dobrynin
Copy link
Contributor

Got this crash today after update to .net 8

@edgedj
Copy link

edgedj commented Nov 15, 2023

I'm getting this on a project after .net 8 upgrade, specifically during this call:

Connectivity.ConnectivityChanged += OnConnectivityChanged;

@dylix
Copy link

dylix commented Nov 16, 2023

EDIT: ah its in nightly builds now... zzzz. i'll wait :P
Why is this closed? It's not fixed in .net8 release.

@Alex-Dobrynin

This comment was marked as off-topic.

@jfversluis
Copy link
Member

@dylix closing PRs/issues only when something is released is a pretty hard thing to administer. Whenever something is merged we consider it fixed but it is pending release. Keep you eye on the release notes.

@ieuangriffiths97
Copy link

+1
Commenting so I can keep track of when this gets released

@stefanpirkl
Copy link

+1 Commenting so I can keep track of when this gets released

Commenting your comment for the same reason

@logtagenginterna
Copy link

+1

+1 Commenting so I can keep track of when this gets released

Commenting your comment for the same reason

@Raynham
Copy link

Raynham commented Dec 1, 2023

+1

Larhei added a commit to HDBW/APOLLO that referenced this issue Jan 18, 2024
thewen-heires added a commit to HDBW/APOLLO that referenced this issue Jan 18, 2024
@gabsamples6
Copy link

Connectivity Change event does not fire in android 34 and also does not fire in iOS

@TranTrieuLamQuynh
Copy link

@gabsamples6
We have checked again. Connectivity Change event work in iOS with me.

@mikeluken
I used broadcast receiver register on Android and set intent.setPackage(getPackageName()) => the registered receiver will be able to listen for the action.

Note:
All, I found the solution for all requireActivity().registerReceiver() calls. They will only listen for the action if the action is sent with the package name of the application. So whenever we send a broadcast, we should also set the package with the intent using intent.setPackage(getPackageName()). Then, the registered receiver will be able to listen for the action.

Reference link: https://developer.android.com/about/versions/14/behavior-changes-14#runtime-receivers-exported

@mikeluken
Copy link

mikeluken commented Jan 19, 2024

@TranTrieuLamQuynh

Thanks for the comment. However, I do not fully understand your post. I don't have a broadcast receiver to register. In App.xaml.cs, I am just specifying:

Connectivity.ConnectivityChanged += Connectivity_ConnectivityChanged;

In Android 13, this works. In Android 14, Connectivity_ConnectivityChanged is never hit when toggling on/off Wi-Fi.

Can you please provide a full example of how you got this to work?

It appears as though a fix was already attempted for this:

https://github.com/dotnet/maui/blame/584d99f14d9b54c25819d1594ceecd370183b92c/src/Essentials/src/Connectivity/Connectivity.android.cs#L48

However, I am running the latest nightly builds and this still does not work.

Note: I also added this to my MainActivity.OnCreate(...):

Intent.SetPackage(AppInfo.PackageName);

It had no effect.

@TranTrieuLamQuynh
Copy link

TranTrieuLamQuynh commented Jan 22, 2024

@mikeluken
Particularly for android 14. I don't use
Connectivity.ConnectivityChanged += Connectivity_ConnectivityChanged;
Instead. I created BroadcastReceiver:

[BroadcastReceiver(Enabled = true, Exported = true)]
public class PowerConnectedBroadcastReceiver : BroadcastReceiver
{
    public override void OnReceive(Context context, Intent intent)
    {
        // Handle when wifi on/off
    }
}

Creat in MainActivity:

    PowerConnectedBroadcastReceiver _receiver;
    IntentFilter _intentFilter;

Then in OnStart() of MainActivity:

        if (OperatingSystem.IsAndroidVersionAtLeast(34))
        {
            Intent.SetPackage(AppInfo.Current.PackageName);
            _receiver = new ();
            _intentFilter = new ();
            _intentFilter.AddAction("android.net.conn.CONNECTIVITY_CHANGE");
            _intentFilter.Priority = (int)IntentFilterPriority.HighPriority;
            ContextCompat.RegisterReceiver(this, _receiver, _intentFilter, 1);
        }

I use this temporary solution until MAUI makes a correction
If I have anything wrong. Wish you sympathize!

@mikeluken
Copy link

Thanks. Yes I was able to get broadcast receivers to work. I was however trying to point out the fact that ConnectivityChanged event in dotnet Maui doesn't work for Android 14.

@gabsamples6
Copy link

gabsamples6 commented Jan 22, 2024

The only hope we have now is that #19949 that you raised @mikeluken gets fixed.. and from what I can see is no part of any milestone.. which you know what that means

@anotherlab
Copy link

Adding the obligatory comment so I'll know when I can target Android 14

@pasha-o
Copy link

pasha-o commented Jan 25, 2024

hi @jfversluis - Since Essentials is part of Maui now, is this issue going to be fixed? or a new issue should be created since this one is closed.

@samhouts samhouts added the fixed-in-8.0.6 Look for this fix in 8.0.6 SR1! label Jan 31, 2024
@ataparia
Copy link

ataparia commented Feb 5, 2024

+1 to keep it on my radar

@samhouts
Copy link
Member

samhouts commented Feb 6, 2024

@TranTrieuLamQuynh

Thanks for the comment. However, I do not fully understand your post. I don't have a broadcast receiver to register. In App.xaml.cs, I am just specifying:

Connectivity.ConnectivityChanged += Connectivity_ConnectivityChanged;

In Android 13, this works. In Android 14, Connectivity_ConnectivityChanged is never hit when toggling on/off Wi-Fi.

Can you please provide a full example of how you got this to work?

It appears as though a fix was already attempted for this:

https://github.com/dotnet/maui/blame/584d99f14d9b54c25819d1594ceecd370183b92c/src/Essentials/src/Connectivity/Connectivity.android.cs#L48

However, I am running the latest nightly builds and this still does not work.

Note: I also added this to my MainActivity.OnCreate(...):

Intent.SetPackage(AppInfo.PackageName);

It had no effect.

@mikeluken Thank you! Can you please open a new issue for this? It'll be easier for us to track it. Thanks!!!

@dimplevador
Copy link

dimplevador commented Feb 13, 2024

@TranTrieuLamQuynh
Thanks for the comment. However, I do not fully understand your post. I don't have a broadcast receiver to register. In App.xaml.cs, I am just specifying:

Connectivity.ConnectivityChanged += Connectivity_ConnectivityChanged;

In Android 13, this works. In Android 14, Connectivity_ConnectivityChanged is never hit when toggling on/off Wi-Fi.
Can you please provide a full example of how you got this to work?
It appears as though a fix was already attempted for this:
https://github.com/dotnet/maui/blame/584d99f14d9b54c25819d1594ceecd370183b92c/src/Essentials/src/Connectivity/Connectivity.android.cs#L48
However, I am running the latest nightly builds and this still does not work.
Note: I also added this to my MainActivity.OnCreate(...):

Intent.SetPackage(AppInfo.PackageName);

It had no effect.

@mikeluken Thank you! Can you please open a new issue for this? It'll be easier for us to track it. Thanks!!!

Just adding my two cents, this intent

static Intent connectivityIntent = new Intent(ConnectivityChangedAction);
needs to have package info set in order for the connectivity change event to fire because of this change by google: https://developer.android.com/about/versions/14/behavior-changes-14#safer-intents

If I set this in the constructor of that class, everything works fine:

connectivityIntent.SetPackage(AppInfo.PackageName);

@573F4N077
Copy link

I am using version 8.0.7 but the event ConnectivityChanged still doesn't fire if I turn off Wifi or turn on Wife on my Android phone. At least it doesn't crash the whole application anymore. Do you have the same issue or does it work for you now?

@plppp2001
Copy link

I am using version 8.0.7 but the event ConnectivityChanged still doesn't fire if I turn off Wifi or turn on Wife on my Android phone. At least it doesn't crash the whole application anymore. Do you have the same issue or does it work for you now?

Same here it's not working for me either. Please FIX MS.

@shingming
Copy link

Test on

  • Pixel 8 Pro Simulator API 34 (run on macOS 13.6.5)
  • .NET SDK 8.0.100
  • android:targetSdkVersion="34"

The app will crash on the same exception in the initial stage

One of RECEIVER_EXPORTED or RECEIVER_NOT_EXPORTED should be specified when a receiver isn't being registered exclusively for system broadcasts ---> Android.OS.RemoteException

@ilmian
Copy link

ilmian commented Mar 26, 2024

Not working on Android 14.

@dartasen
Copy link
Contributor

@ilmian Maybe you wanna open a new issue, since this one is closed

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area-essentials Essentials: Device, Display, Connectivity, Secure Storage, Sensors, App Info delighter fixed-in-8.0.6 Look for this fix in 8.0.6 SR1! platform/android 🤖 s/triaged Issue has been reviewed s/verified Verified / Reproducible Issue ready for Engineering Triage t/bug Something isn't working
Projects
Status: Done
Development

Successfully merging a pull request may close this issue.