DefinedNet / mobile_nebula

Brings nebula to mobile devices (iOS, Android)
https://defined.net
123 stars 37 forks source link

Android 14 (sdk api 34) Crash due to SecurityException from ContextCompat.registerReceiver call #156

Closed isi-lincoln closed 5 months ago

isi-lincoln commented 5 months ago

This may be a case of PEBKAC and I apologize if this is not relevant as I do not develop on android.

After building the apk and running it on my Android 34 device (changing the grandle build settings for compileSdkVersion and targetSdkVersion from the default 33 value to 34), it would immediately crash with the following error message:

03-28 15:04:54.598 E/AndroidRuntime(11951): Caused by: java.lang.SecurityException: net.defined.mobile_nebula: One of RECEIVER_EXPORTED or RECEIVER_NOT_EXPORTED should be specified when a receiver isn't being registered exclusively for system broadcasts

I modified the registerReceiver calls in the kotlin code base (indicated below in my diff) to include the RECEIVER_EXPORTED int flag.

I'm honestly not sure if it should be EXPORTED or UNEXPORTED, however I found this modification enough to allow the application to open without crashing.

diff --git a/android/app/src/main/kotlin/net/defined/mobile_nebula/MainActivity.kt b/android/app/src/main/kotlin/net/defined/mobile_nebula/MainActivity.kt
index dd83799..e9bc4c5 100644
--- a/android/app/src/main/kotlin/net/defined/mobile_nebula/MainActivity.kt
+++ b/android/app/src/main/kotlin/net/defined/mobile_nebula/MainActivity.kt
@@ -98,7 +98,7 @@ class MainActivity: FlutterActivity() {

         apiClient = APIClient(context)

-        registerReceiver(refreshReceiver, IntentFilter(ACTION_REFRESH_SITES))
+        registerReceiver(refreshReceiver, IntentFilter(ACTION_REFRESH_SITES), RECEIVER_EXPORTED)

         enqueueDNUpdater()
     }
diff --git a/android/app/src/main/kotlin/net/defined/mobile_nebula/NebulaVpnService.kt b/android/app/src/main/kotlin/net/defined/mobile_nebula/NebulaVpnService.kt
index 620b46a..dea7a71 100644
--- a/android/app/src/main/kotlin/net/defined/mobile_nebula/NebulaVpnService.kt
+++ b/android/app/src/main/kotlin/net/defined/mobile_nebula/NebulaVpnService.kt
@@ -209,11 +209,11 @@ class NebulaVpnService : VpnService() {
             }
         }

-        registerReceiver(receiver, IntentFilter(PowerManager.ACTION_DEVICE_IDLE_MODE_CHANGED))
+        registerReceiver(receiver, IntentFilter(PowerManager.ACTION_DEVICE_IDLE_MODE_CHANGED), RECEIVER_EXPORTED)
     }

     private fun registerReloadReceiver() {
-        registerReceiver(reloadReceiver, IntentFilter(ACTION_RELOAD))
+        registerReceiver(reloadReceiver, IntentFilter(ACTION_RELOAD), RECEIVER_EXPORTED)
     }
johnmaguire commented 5 months ago

Hi @isi-lincoln - thanks for the report. Are you able to compile / run without a crash if you don't change the target and compile version? Without investigation, I suspect the API changed at SDK 34. You should be able to build the app without upgrading the SDK.

I'm thinking you may have compiled this yourself to avoid the Play Store - if that's not the case, do you experience crashes on the Play Store build?

isi-lincoln commented 5 months ago

Hello John,

I've re-compiled the code targeting SDK API 33 and you are correct that the app does not crash. You are welcome to close the issue as you see fit.

I'm thinking you may have compiled this yourself to avoid the Play Store

That is correct - my device cannot connect to the Google Play Store.

Thank you for your insight and response.

johnmaguire commented 5 months ago

Thanks @isi-lincoln! I'm going to close this out as it's not a bug in the existing code per se, but will keep it in mind when we upgrade the SDK. :) Appreciate the info.