rns-nativecall 0.5.0 → 0.5.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -23,6 +23,15 @@ class CallMessagingService : FirebaseMessagingService() {
23
23
  private val pendingNotifications = mutableMapOf<String, Runnable>()
24
24
  }
25
25
 
26
+ // Helper to check app state
27
+ private fun isAppInForeground(context: Context): Boolean {
28
+ val activityManager = context.getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager
29
+ val appProcesses = activityManager.runningAppProcesses ?: return false
30
+ return appProcesses.any {
31
+ it.importance == ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND && it.processName == context.packageName
32
+ }
33
+ }
34
+
26
35
  override fun onMessageReceived(remoteMessage: RemoteMessage) {
27
36
  val data = remoteMessage.data
28
37
  val context = applicationContext
@@ -42,25 +51,20 @@ class CallMessagingService : FirebaseMessagingService() {
42
51
  if (isAppInForeground(context)) {
43
52
  CallModule.sendEventToJS("onCallReceived", data)
44
53
  } else {
45
- // 1. Show the Full Screen Notification IMMEDIATELY
46
54
  NativeCallManager.handleIncomingPush(context, data)
47
55
 
48
- // 2. Start HeadlessJS Task as a Foreground Service
49
56
  try {
50
57
  val headlessIntent = Intent(context, CallHeadlessTask::class.java).apply {
51
58
  val bundle = Bundle()
52
59
  data.forEach { (k, v) -> bundle.putString(k, v) }
53
60
  putExtras(bundle)
54
61
  }
55
-
56
- // CRITICAL: Must use startForegroundService for background starts on Android 8+
57
62
  ContextCompat.startForegroundService(context, headlessIntent)
58
63
  HeadlessJsTaskService.acquireWakeLockNow(context)
59
64
  } catch (e: Exception) {
60
65
  e.printStackTrace()
61
66
  }
62
67
 
63
- // 3. Backup Safety
64
68
  val showNotificationRunnable = Runnable {
65
69
  if (!isAppInForeground(context)) {
66
70
  NativeCallManager.handleIncomingPush(context, data)
@@ -109,12 +113,4 @@ class CallMessagingService : FirebaseMessagingService() {
109
113
 
110
114
  notificationManager.notify(uuid.hashCode(), builder.build())
111
115
  }
112
-
113
- private fun isAppInForeground(context: Context): Boolean {
114
- val activityManager = context.getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager
115
- val appProcesses = activityManager.runningAppProcesses ?: return false
116
- return appProcesses.any {
117
- it.importance == ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND && it.processName == context.packageName
118
- }
119
- }
120
116
  }
@@ -4,15 +4,15 @@ import android.app.NotificationChannel
4
4
  import android.app.NotificationManager
5
5
  import android.app.PendingIntent
6
6
  import android.content.Context
7
- import android.content.Intent // CRITICAL IMPORT
7
+ import android.content.Intent
8
8
  import android.os.Build
9
- import android.os.Bundle // CRITICAL IMPORT
9
+ import android.os.Bundle
10
10
  import androidx.core.app.NotificationCompat
11
11
  import android.media.Ringtone
12
12
  import android.media.RingtoneManager
13
13
  import android.graphics.Color
14
14
  import androidx.core.app.Person
15
- import androidx.core.app.NotificationCompat.CallStyle
15
+ import androidx.core.graphics.drawable.IconCompat
16
16
 
17
17
  object NativeCallManager {
18
18
 
@@ -32,10 +32,16 @@ object NativeCallManager {
32
32
  PendingIntent.FLAG_UPDATE_CURRENT
33
33
  }
34
34
 
35
- // 1. Full Screen / UI Intent
35
+ // Prepare Common Bundle
36
+ val extras = Bundle().apply {
37
+ data.forEach { (k, v) -> putString(k, v) }
38
+ putString("EXTRA_CALL_UUID", uuid)
39
+ }
40
+
41
+ // 1. UI Intent (When tapping the notification body)
36
42
  val intentToActivity = Intent(context, AcceptCallActivity::class.java).apply {
37
43
  action = "ACTION_SHOW_UI_$uuid"
38
- data.forEach { (key, value) -> putExtra(key, value) }
44
+ putExtras(extras)
39
45
  addFlags(Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TOP)
40
46
  }
41
47
  val fullScreenPendingIntent = PendingIntent.getActivity(
@@ -45,18 +51,16 @@ object NativeCallManager {
45
51
  // 2. Reject Intent
46
52
  val rejectIntent = Intent(context, CallActionReceiver::class.java).apply {
47
53
  action = "ACTION_REJECT_$uuid"
48
- putExtra("EXTRA_CALL_UUID", uuid)
49
- data.forEach { (key, value) -> putExtra(key, value) }
54
+ putExtras(extras)
50
55
  }
51
56
  val rejectPendingIntent = PendingIntent.getBroadcast(
52
57
  context, uuid.hashCode() + 1, rejectIntent, pendingFlags
53
58
  )
54
59
 
55
- // 3. Answer Intent (Using your CallActionReceiver)
60
+ // 3. Answer Intent
56
61
  val answerIntent = Intent(context, CallActionReceiver::class.java).apply {
57
- action = "ACTION_ACCEPT_$uuid" // Changed to match your Receiver logic
58
- putExtra("EXTRA_CALL_UUID", uuid)
59
- data.forEach { (key, value) -> putExtra(key, value) }
62
+ action = "ACTION_ACCEPT_$uuid"
63
+ putExtras(extras)
60
64
  }
61
65
  val answerPendingIntent = PendingIntent.getBroadcast(
62
66
  context, uuid.hashCode() + 2, answerIntent, pendingFlags
@@ -74,33 +78,24 @@ object NativeCallManager {
74
78
  notificationManager.createNotificationChannel(channel)
75
79
  }
76
80
 
77
- val caller = Person.Builder()
78
- .setName(name)
79
- .setImportant(true)
80
- .setIcon(context.applicationInfo.icon)
81
- .build()
82
-
83
81
  val builder = NotificationCompat.Builder(context, CALL_CHANNEL_ID)
84
- //.setSmallIcon(context.applicationInfo.icon)
85
82
  .setContentTitle("Incoming $callType call")
86
83
  .setContentText(name)
87
84
  .setPriority(NotificationCompat.PRIORITY_MAX)
88
85
  .setCategory(NotificationCompat.CATEGORY_CALL)
89
86
  .setOngoing(true)
90
87
  .setAutoCancel(false)
91
- .setFullScreenIntent(fullScreenPendingIntent, true)
88
+ .setFullScreenIntent(fullScreenPendingIntent, true) // Essential for waking screen
92
89
  .setColor(Color.parseColor("#28a745"))
93
90
  .setColorized(true)
94
- .setStyle(
95
- NotificationCompat.CallStyle.forIncomingCall(
96
- caller,
97
- answerPendingIntent
98
- rejectPendingIntent,
99
- )
100
- )
101
-
91
+ // ADDING ACTIONS MANUALLY TO CONTROL ORDER
92
+ // First Action added = Leftmost button
93
+ .addAction(0, "Answer", answerPendingIntent)
94
+ .addAction(0, "Decline", rejectPendingIntent)
95
+
102
96
  notificationManager.notify(uuid.hashCode(), builder.build())
103
97
 
98
+ // Start Ringtone
104
99
  try {
105
100
  val ringtoneUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_RINGTONE)
106
101
  ringtone = RingtoneManager.getRingtone(context, ringtoneUri)
@@ -111,14 +106,9 @@ object NativeCallManager {
111
106
 
112
107
  fun stopRingtone() {
113
108
  try {
114
- ringtone?.let {
115
- if (it.isPlaying) it.stop()
116
- }
117
- ringtone = null
118
- } catch (e: Exception) {
119
- e.printStackTrace()
109
+ ringtone?.let { if (it.isPlaying) it.stop() }
120
110
  ringtone = null
121
- }
111
+ } catch (e: Exception) { e.printStackTrace() }
122
112
  }
123
113
 
124
114
  fun dismissIncomingCall(context: Context, uuid: String?) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "rns-nativecall",
3
- "version": "0.5.0",
3
+ "version": "0.5.2",
4
4
  "description": "RNS nativecall component with native Android/iOS for handling native call ui, when app is not open or open.",
5
5
  "main": "index.js",
6
6
  "types": "index.d.ts",