Skip to content

🐛 Android build fails with Kotlin 2.x / RN 0.81 due to currentActivity and mutable map return types #1521

@fathinafiff

Description

@fathinafiff

Description

Android build fails when using @100mslive/react-native-hms with modern React Native and Expo setups
(RN 0.81+, Expo SDK 54, Kotlin 2.1.x).

The failure happens during :compileDebugKotlin.

Errors

  • Return type mismatch: expected MutableMap, actual Map
  • Unresolved reference: currentActivity

Example errors:


Return type mismatch: expected 'MutableMap<String, Any>?', actual 'Map<String, Any>'
Unresolved reference: currentActivity

Root cause

  1. Kotlin 2.x is stricter and does not allow returning immutable Map where React Native
    ViewManager APIs expect MutableMap.
  2. currentActivity synthetic access is no longer available or deprecated in newer
    Kotlin / RN plugin versions. The recommended access is via
    reactApplicationContext.currentActivity.

Proposed fix

1) Return mutable maps

MapBuilder.of(
  ...
).build().toMutableMap()

2) Replace currentActivity access

reactApplicationContext.currentActivity

Files affected

  • android/src/main/java/com/reactnativehmssdk/HMSHLSPlayerManager.kt
  • android/src/main/java/com/reactnativehmssdk/HMSManager.kt
  • android/src/main/java/com/reactnativehmssdk/HMSSDKViewManager.kt

Patch (diff)

diff --git a/android/src/main/java/com/reactnativehmssdk/HMSHLSPlayerManager.kt b/android/src/main/java/com/reactnativehmssdk/HMSHLSPlayerManager.kt
index 6248c4e4fa35e150458c25617f9722ba0c0e19e5..c27eb6ddb9a7dae8ade6e7302bd06796bce87af3 100644
--- a/android/src/main/java/com/reactnativehmssdk/HMSHLSPlayerManager.kt
+++ b/android/src/main/java/com/reactnativehmssdk/HMSHLSPlayerManager.kt
@@ -113,6 +113,7 @@ class HMSHLSPlayerManager : SimpleViewManager<HMSHLSPlayer>() {
       .put("disableClosedCaption", 120)
       .put("getPlayerDurationDetails", 130)
       .build()
+      .toMutableMap()
 
   @ReactProp(name = "url")
   fun setStreamURL(
diff --git a/android/src/main/java/com/reactnativehmssdk/HMSManager.kt b/android/src/main/java/com/reactnativehmssdk/HMSManager.kt
index be72cbf1a4fdcfbc950463c391268235b6cd9bcb..2dfc6b4c32d86dfece8d4a70b7e8834743939104 100644
--- a/android/src/main/java/com/reactnativehmssdk/HMSManager.kt
+++ b/android/src/main/java/com/reactnativehmssdk/HMSManager.kt
@@ -96,7 +96,7 @@ class HMSManager(
       reactAppContext = reactApplicationContext
 
       if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
-        currentActivity?.let {
+        reactApplicationContext.currentActivity?.let {
           pipReceiver?.register(it)
         }
       }
@@ -438,7 +438,7 @@ class HMSManager(
     data: ReadableMap,
     callback: Promise?,
   ) {
-    currentActivity?.application?.registerActivityLifecycleCallbacks(this)
+    reactApplicationContext.currentActivity?.application?.registerActivityLifecycleCallbacks(this)
     val hms = HMSHelper.getHms(data, hmsCollection)
 
     hms?.startScreenshare(callback)
@@ -461,7 +461,7 @@ class HMSManager(
   ) {
     val hms = HMSHelper.getHms(data, hmsCollection)
 
-    currentActivity?.application?.unregisterActivityLifecycleCallbacks(this)
+    reactApplicationContext.currentActivity?.application?.unregisterActivityLifecycleCallbacks(this)
     hms?.stopScreenshare(callback)
   }
 
@@ -470,7 +470,7 @@ class HMSManager(
     data: ReadableMap,
     callback: Promise?,
   ) {
-    currentActivity?.application?.registerActivityLifecycleCallbacks(this)
+    reactApplicationContext.currentActivity?.application?.registerActivityLifecycleCallbacks(this)
     val hms = HMSHelper.getHms(data, hmsCollection)
 
     hms?.startAudioshare(data, callback)
@@ -493,7 +493,7 @@ class HMSManager(
   ) {
     val hms = HMSHelper.getHms(data, hmsCollection)
 
-    currentActivity?.application?.unregisterActivityLifecycleCallbacks(this)
+    reactApplicationContext.currentActivity?.application?.unregisterActivityLifecycleCallbacks(this)
     hms?.stopAudioshare(callback)
   }
 
@@ -784,7 +784,7 @@ class HMSManager(
       return
     }
 
-    val activity = currentActivity
+    val activity = reactApplicationContext.currentActivity
 
     if (activity !== null) {
       val hmssdk = getHmsInstance()[PipActionReceiver.sdkIdForPIP!!]?.hmsSDK
@@ -1085,7 +1085,7 @@ class HMSManager(
         throw Throwable(message = "PIP Mode is not supported!")
       }
 
-      val activity = currentActivity ?: return false
+      val activity = reactApplicationContext.currentActivity ?: return false
       val pipParamConfig = readableMapToPipParamConfig(data) ?: return false
       val pipParams = buildPipParams(pipParamConfig) ?: return false
 
@@ -1122,7 +1122,7 @@ class HMSManager(
         throw Throwable(message = "PIP Mode is not supported!")
       }
 
-      val activity = currentActivity ?: return false
+      val activity = reactApplicationContext.currentActivity ?: return false
       val pipParamConfig = readableMapToPipParamConfig(data) ?: return false
       val pipParams = buildPipParams(pipParamConfig) ?: return false
 
@@ -1713,7 +1713,7 @@ class HMSManager(
             hmsCollection[key]?.leave(null)
           }
         }
-        currentActivity?.application?.unregisterActivityLifecycleCallbacks(this)
+        reactApplicationContext.currentActivity?.application?.unregisterActivityLifecycleCallbacks(this)
         hmsCollection = mutableMapOf()
         // unregistering pip actions on activity destroy.
         if (pipReceiver !== null && Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
diff --git a/android/src/main/java/com/reactnativehmssdk/HMSSDKViewManager.kt b/android/src/main/java/com/reactnativehmssdk/HMSSDKViewManager.kt
index 5c1ac2f357346bbffc10fe04deb155333ae26e20..6ac8203a6cc3087346311647e36bae3036fc794a 100644
--- a/android/src/main/java/com/reactnativehmssdk/HMSSDKViewManager.kt
+++ b/android/src/main/java/com/reactnativehmssdk/HMSSDKViewManager.kt
@@ -28,12 +28,13 @@ class HMSSDKViewManager : SimpleViewManager<HMSView>() {
         "topChange",
         MapBuilder.of("phasedRegistrationNames", MapBuilder.of("bubbled", "onChange")),
       ).build()
+      .toMutableMap()
 
   override fun getExportedCustomDirectEventTypeConstants(): MutableMap<String, Any>? =
     MapBuilder.of(
       "captureFrame",
       MapBuilder.of("registrationName", "onDataReturned"),
-    )
+    ).toMutableMap()
 
   @RequiresApi(Build.VERSION_CODES.N)
   override fun receiveCommand(

Tested with

  • Expo SDK 54
  • React Native 0.81.5
  • Kotlin 2.1.x
  • Android Gradle Plugin via Expo

Notes

This change is backward compatible with older RN versions and fixes build failures
for modern Expo / RN setups.

100ms React Native Version

@100mslive/react-native-hms@1.12.0

React Native Version

react-native@0.81.5 (Expo SDK 54)

Steps to reproduce

  1. Create a new Expo SDK 54 project (or any RN 0.81.x project).
  2. Install dependency:
    • yarn add @100mslive/react-native-hms@1.12.0
  3. Prebuild / run Android:
    • npx expo run:android
      (or cd android && ./gradlew assembleDebug)
  4. Build fails at :100mslive_react-native-hms:compileDebugKotlin with Kotlin compilation errors.

Expected results

Android build should succeed on modern React Native / Expo toolchains (RN 0.81.x, Expo SDK 54) without Kotlin compilation errors.

Code example, screenshot, or link to a repository

I can't share the full app repo, but this reproduces in a fresh Expo SDK 54 project by only installing @100mslive/react-native-hms@1.12.0 and running npx expo run:android.

Logs

Task :100mslive_react-native-hms:compileDebugKotlin FAILED
e: .../HMSHLSPlayerManager.kt:113:5 Return type mismatch: expected 'MutableMap<String, Int>?', actual 'Map<String, Int>'.
e: .../HMSManager.kt:99:9 Unresolved reference 'currentActivity'.
e: .../HMSManager.kt:853:16 Unresolved reference 'setPictureInPictureParams'.
e: .../HMSSDKViewManager.kt:25:5 Return type mismatch: expected 'MutableMap<String, Any>?', actual 'Map<String, Any>'.

[ExpoRootProject] Using the following versions:

  • compileSdk: 36
  • targetSdk: 36
  • ndk: 27.1.12297006
  • kotlin: 2.1.20

Extra Note:
This appears to be Kotlin 2.x / RN 0.81 compatibility. Using reactApplicationContext.currentActivity and returning toMutableMap() resolves the build.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions