Skip to content

Commit d509538

Browse files
committed
Update android getActivityContext
1 parent dc69607 commit d509538

File tree

2 files changed

+110
-25
lines changed

2 files changed

+110
-25
lines changed

android/build.gradle

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -65,10 +65,10 @@ android {
6565
unitTests.returnDefaultValues = true
6666
}
6767
compileOptions {
68-
sourceCompatibility JavaVersion.VERSION_1_8
69-
targetCompatibility JavaVersion.VERSION_1_8
68+
sourceCompatibility JavaVersion.VERSION_17
69+
targetCompatibility JavaVersion.VERSION_17
7070
}
71-
kotlinOptions { // Configure Kotlin-specific options
71+
kotlinOptions {
7272
jvmTarget = "17"
7373
}
7474
}
@@ -80,7 +80,7 @@ repositories {
8080
}
8181

8282
dependencies {
83-
implementation "org.jetbrains.kotlin:kotlin-stdlib:1.7.10"
83+
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.7.10"
8484
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.6.4"
8585
implementation "com.facebook.react:react-native:${safeExtGet('reactNativeVersion', '+')}"
8686
// AppsFlyer SDK 7.99.512 (required for plugin bridge 0.0.4)

android/src/main/java/com/appsflyer/reactnative/RNAppsFlyerRPCModule.kt

Lines changed: 106 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,41 +1,65 @@
11
package com.appsflyer.reactnative
22

3+
import android.app.Activity
34
import android.os.Handler
45
import android.os.Looper
56
import com.facebook.react.bridge.*
67
import com.facebook.react.modules.core.DeviceEventManagerModule
78
import com.appsflyer.pluginbridge.handler.AppsFlyerRpcHandler
89
import com.appsflyer.pluginbridge.model.RpcResponse
9-
import kotlinx.coroutines.CoroutineScope
10-
import kotlinx.coroutines.Dispatchers
11-
import kotlinx.coroutines.SupervisorJob
12-
import kotlinx.coroutines.launch
10+
import org.json.JSONArray
11+
import org.json.JSONException
1312
import org.json.JSONObject
1413

15-
class RNAppsFlyerRPCModule(private val reactContext: ReactApplicationContext) :
14+
class RNAppsFlyerRPCModule(reactContext: ReactApplicationContext) :
1615
ReactContextBaseJavaModule(reactContext) {
1716

18-
private val rpcHandler: AppsFlyerRpcHandler
17+
private var rpcHandler: AppsFlyerRpcHandler? = null
1918
private val mainHandler = Handler(Looper.getMainLooper())
2019

21-
init {
22-
val context = reactContext.applicationContext
23-
rpcHandler = AppsFlyerRpcHandler(
24-
context = context,
20+
override fun invalidate() {
21+
mainHandler.removeCallbacksAndMessages(null)
22+
rpcHandler = null
23+
}
24+
25+
private fun getOrCreateHandler(): AppsFlyerRpcHandler {
26+
val handler = rpcHandler
27+
if (handler != null) {
28+
return handler
29+
}
30+
31+
val activity = getCurrentActivity() ?: throw IllegalStateException("Activity is required but not available. Make sure the React Native app is fully initialized.")
32+
33+
val newHandler = AppsFlyerRpcHandler(
34+
context = activity,
2535
pluginNotifier = { jsonEvent ->
2636
emitEventToJavaScript(jsonEvent)
2737
}
2838
)
39+
rpcHandler = newHandler
40+
return newHandler
2941
}
3042

3143
override fun getName(): String = "RNAppsFlyerRPC"
3244

3345
@ReactMethod
3446
fun executeJson(jsonRequest: String, promise: Promise) {
47+
if (jsonRequest.isBlank()) {
48+
promise.reject("INVALID_REQUEST", "JSON request cannot be empty", null)
49+
return
50+
}
51+
3552
try {
36-
val response = rpcHandler.execute(jsonRequest)
53+
val handler = getOrCreateHandler()
54+
val response = handler.execute(jsonRequest)
3755
val jsonResponse = convertResponseToJson(response)
3856
promise.resolve(jsonResponse)
57+
} catch (e: IllegalStateException) {
58+
android.util.Log.e("RNAppsFlyerRPC", "[Android] Activity context not available: ${e.message}", e)
59+
promise.reject("CONTEXT_UNAVAILABLE", e.message ?: "Activity context is required", e)
60+
} catch (e: IllegalArgumentException) {
61+
android.util.Log.e("RNAppsFlyerRPC", "[Android] Invalid RPC request: ${e.message}", e)
62+
promise.reject("INVALID_REQUEST", e.message ?: "Invalid request", e)
3963
} catch (e: Exception) {
4064
android.util.Log.e("RNAppsFlyerRPC", "[Android] executeJson error: ${e.message}", e)
4165
promise.reject("RPC_EXECUTION_ERROR", e.message ?: "Unknown error", e)
@@ -47,19 +71,17 @@ class RNAppsFlyerRPCModule(private val reactContext: ReactApplicationContext) :
4771
is RpcResponse.VoidSuccess -> {
4872
JSONObject().apply {
4973
put("jsonrpc", "2.0")
50-
// Use JSONObject.NULL instead of null to ensure the key is included in the JSON string
5174
put("result", JSONObject.NULL)
5275
}.toString()
5376
}
5477
is RpcResponse.Success<*> -> {
5578
JSONObject().apply {
5679
put("jsonrpc", "2.0")
57-
// Handle null result values properly
5880
val resultValue = response.result
5981
if (resultValue == null) {
6082
put("result", JSONObject.NULL)
6183
} else {
62-
put("result", resultValue)
84+
put("result", convertToJsonValue(resultValue))
6385
}
6486
}.toString()
6587
}
@@ -75,9 +97,45 @@ class RNAppsFlyerRPCModule(private val reactContext: ReactApplicationContext) :
7597
}
7698
}
7799

100+
private fun convertToJsonValue(value: Any?): Any {
101+
return when (value) {
102+
null -> JSONObject.NULL
103+
is String -> value
104+
is Boolean -> value
105+
is Int -> value
106+
is Long -> value
107+
is Double -> value
108+
is Float -> value.toDouble()
109+
is Short -> value.toInt()
110+
is Byte -> value.toInt()
111+
is Map<*, *> -> {
112+
val jsonObject = JSONObject()
113+
value.forEach { (k, v) ->
114+
val key = k?.toString() ?: "null"
115+
jsonObject.put(key, convertToJsonValue(v))
116+
}
117+
jsonObject
118+
}
119+
is List<*> -> {
120+
val jsonArray = JSONArray()
121+
value.forEach { item ->
122+
jsonArray.put(convertToJsonValue(item))
123+
}
124+
jsonArray
125+
}
126+
else -> value.toString()
127+
}
128+
}
129+
78130
private fun emitEventToJavaScript(jsonEvent: String) {
79-
val context = reactContext
80-
if (context == null || !context.hasActiveReactInstance()) {
131+
val reactApplicationContext = reactApplicationContext
132+
if (!reactApplicationContext.hasActiveReactInstance()) {
133+
return
134+
}
135+
136+
val activity = getCurrentActivity()
137+
if (activity == null) {
138+
android.util.Log.w("RNAppsFlyerRPC", "[Android] Cannot emit event: activity not available")
81139
return
82140
}
83141

@@ -90,16 +148,19 @@ class RNAppsFlyerRPCModule(private val reactContext: ReactApplicationContext) :
90148
when (value) {
91149
is String -> eventMap.putString(key, value)
92150
is Int -> eventMap.putInt(key, value)
151+
is Long -> eventMap.putDouble(key, value.toDouble())
93152
is Double -> eventMap.putDouble(key, value)
153+
is Float -> eventMap.putDouble(key, value.toDouble())
94154
is Boolean -> eventMap.putBoolean(key, value)
95155
is JSONObject -> eventMap.putMap(key, jsonObjectToWritableMap(value))
156+
is JSONArray -> eventMap.putArray(key, jsonArrayToWritableArray(value))
96157
else -> eventMap.putString(key, value.toString())
97158
}
98159
}
99160

100161
val runnable = Runnable {
101-
if (context.hasActiveReactInstance()) {
102-
context.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
162+
if (reactApplicationContext.hasActiveReactInstance() && getCurrentActivity() != null) {
163+
reactApplicationContext.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
103164
.emit("onEvent", eventMap)
104165
}
105166
}
@@ -109,8 +170,10 @@ class RNAppsFlyerRPCModule(private val reactContext: ReactApplicationContext) :
109170
} else {
110171
mainHandler.post(runnable)
111172
}
173+
} catch (e: JSONException) {
174+
android.util.Log.e("RNAppsFlyerRPC", "[Android] Failed to parse JSON event: ${e.message}", e)
112175
} catch (e: Exception) {
113-
// Ignore JSON parsing errors
176+
android.util.Log.e("RNAppsFlyerRPC", "[Android] Failed to emit event: ${e.message}", e)
114177
}
115178
}
116179

@@ -121,22 +184,44 @@ class RNAppsFlyerRPCModule(private val reactContext: ReactApplicationContext) :
121184
when (value) {
122185
is String -> map.putString(key, value)
123186
is Int -> map.putInt(key, value)
187+
is Long -> map.putDouble(key, value.toDouble())
124188
is Double -> map.putDouble(key, value)
189+
is Float -> map.putDouble(key, value.toDouble())
125190
is Boolean -> map.putBoolean(key, value)
126191
is JSONObject -> map.putMap(key, jsonObjectToWritableMap(value))
192+
is JSONArray -> map.putArray(key, jsonArrayToWritableArray(value))
127193
else -> map.putString(key, value.toString())
128194
}
129195
}
130196
return map
131197
}
132198

199+
private fun jsonArrayToWritableArray(jsonArray: JSONArray): WritableArray {
200+
val array = Arguments.createArray()
201+
for (i in 0 until jsonArray.length()) {
202+
val value = jsonArray.get(i)
203+
when (value) {
204+
is String -> array.pushString(value)
205+
is Int -> array.pushInt(value)
206+
is Long -> array.pushDouble(value.toDouble())
207+
is Double -> array.pushDouble(value)
208+
is Float -> array.pushDouble(value.toDouble())
209+
is Boolean -> array.pushBoolean(value)
210+
is JSONObject -> array.pushMap(jsonObjectToWritableMap(value))
211+
is JSONArray -> array.pushArray(jsonArrayToWritableArray(value))
212+
else -> array.pushString(value.toString())
213+
}
214+
}
215+
return array
216+
}
217+
133218
@ReactMethod
134-
fun addListener(eventName: String) {
219+
fun addListener(_eventName: String) {
135220
// Required for event emitter support
136221
}
137222

138223
@ReactMethod
139-
fun removeListeners(count: Double) {
224+
fun removeListeners(_count: Double) {
140225
// Required for event emitter support
141226
}
142227
}

0 commit comments

Comments
 (0)