I’ve created a React Native Package (extends ReactPackage) for Android. I’ve created all of the supporting .kt files. However, NativeModules is an empty object ({}) when I try to access it from within my top-level React component:
import { NativeModules } from ‘react-native’;
const { IntentModule } = NativeModules;
I’ve validated that IntentModulePackage.init() gets called (with log output) – but createNativeModules() does not get called (no log output). In addition – MainApplication.getPackages() logs the following info:
React Packages: [com.facebook.react.shell.MainReactPackage@7bcb47f, com.adac1001.mediamanager.IntentModulePackage@391bc4c]
Any idea what this state reflects exactly? I guess IntentModulePackage gets basic initialization with metadata but createNativeModules() never gets hit for some reason – so NativeModules never gets populated with it?
But the “React Packages” log output above also reflects “MainReactPackage” which also does not appear to be reflected in NativeModules – so maybe there are multiple issues here. I’ve tried multiple debug scenarios with multiple AI bots – and this the best problem statement that I can discern atm. Any idea what the issue might be here or how to debug further? kt classes below.
====
package com.myorg.myapp
import android.app.Application
import android.util.Log
import com.facebook.react.ReactApplication
import com.facebook.react.ReactNativeHost
import com.facebook.react.ReactPackage
import com.facebook.react.shell.MainReactPackage
import com.facebook.soloader.SoLoader
import java.util.*
import com.adac1001.mediamanager.IntentModulePackage
class MainApplication : Application(), ReactApplication {
private val mReactNativeHost = object : ReactNativeHost(this) {
override fun getUseDeveloperSupport(): Boolean {
return BuildConfig.DEBUG
}
override fun getPackages(): List<ReactPackage> {
val packages = listOf(
MainReactPackage(),
IntentModulePackage() // Register the package here
)
Log.d("MainApplication", "React Packages: $packages")
return packages
}
override fun getJSMainModuleName(): String {
return "index"
}
}
override val reactNativeHost: ReactNativeHost
get() = mReactNativeHost
override fun onCreate() {
Log.d("MainApplication", "onCreate called")
super.onCreate()
SoLoader.init(this, false)
}
}
====
package com.myorg.myapp
import android.content.Intent
import android.os.Bundle
import android.util.Log
import com.facebook.react.ReactActivity
import com.facebook.react.ReactActivityDelegate
import com.facebook.react.defaults.DefaultNewArchitectureEntryPoint.fabricEnabled
import com.facebook.react.defaults.DefaultReactActivityDelegate
import com.facebook.react.bridge.ReactContext
import com.facebook.react.modules.core.DeviceEventManagerModule
class MainActivity : ReactActivity() {
override fun getMainComponentName(): String = "MediaManager"
override fun createReactActivityDelegate(): ReactActivityDelegate =
DefaultReactActivityDelegate(this, mainComponentName, fabricEnabled)
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
Log.d("MainActivity", "onCreate called")
// Handle the incoming share intent
if (intent?.action == Intent.ACTION_SEND) {
Log.d("MainActivity", "Intent action is SEND")
if (intent.type == "text/plain") {
Log.d("MainActivity", "Intent type is text/plain")
handleSendText(intent) // Handle text being sent
}
}
}
private fun handleSendText(intent: Intent) {
val text = intent.getStringExtra(Intent.EXTRA_TEXT)
Log.d("MainActivity", "handleSendText called with text: $text")
text?.let {
// Send the text to React Native
sendEventToReactNative(it)
}
}
override fun onNewIntent(intent: Intent) {
super.onNewIntent(intent)
setIntent(intent)
Log.d("MainActivity", "onNewIntent called")
// Handle the new intent
if (intent.action == Intent.ACTION_SEND && intent.type == "text/plain") {
Log.d("MainActivity", "New Intent action is SEND and type is text/plain")
handleSendText(intent)
}
}
private fun sendEventToReactNative(sharedText: String) {
val reactContext = reactInstanceManager?.currentReactContext
reactContext?.let {
it
.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
.emit("ShareText", sharedText)
}
}
}
====
package com.myorg.myapp
import android.util.Log
import com.facebook.react.ReactPackage
import com.facebook.react.bridge.ReactApplicationContext
import com.facebook.react.bridge.NativeModule
import com.facebook.react.uimanager.ViewManager
class IntentModulePackage : ReactPackage {
init {
Log.d("IntentModulePackage", "IntentModulePackage initialized")
}
override fun createNativeModules(reactContext: ReactApplicationContext): List<NativeModule> {
Log.d("IntentModulePackage", "enter createNativeModules")
val modules = listOf(IntentModule(reactContext))
Log.d("IntentModulePackage", "createNativeModules: $modules")
return modules
}
override fun createViewManagers(reactContext: ReactApplicationContext): List<ViewManager<*, *>> {
return emptyList()
}
}
====
package com.myorg.myapp
import android.content.Intent
import android.util.Log
import com.facebook.react.bridge.ReactApplicationContext
import com.facebook.react.bridge.ReactContextBaseJavaModule
import com.facebook.react.bridge.ReactMethod
import com.facebook.react.bridge.Promise
import com.facebook.react.bridge.Arguments
class IntentModule(reactContext: ReactApplicationContext) : ReactContextBaseJavaModule(reactContext) {
private var receivedIntent: Intent? = null
init {
Log.d("IntentModule", "IntentModule initialized")
}
override fun getName(): String {
return "IntentModule"
}
@ReactMethod
fun getSharedText(promise: Promise) {
Log.d("IntentModule", "getSharedText called")
receivedIntent?.let {
if (Intent.ACTION_SEND == it.action && it.type == "text/plain") {
val sharedText = it.getStringExtra(Intent.EXTRA_TEXT)
val map = Arguments.createMap()
map.putString("sharedText", sharedText)
promise.resolve(map)
Log.d("IntentModule", "Shared text resolved: $sharedText")
} else {
promise.resolve(null)
Log.d("IntentModule", "Intent action not ACTION_SEND or type not text/plain")
}
} ?: run {
promise.resolve(null)
Log.d("IntentModule", "Received intent is null")
}
}
fun setReceivedIntent(intent: Intent) {
receivedIntent = intent
Log.d("IntentModule", "Intent received and set")
}
}