rns-nativecall 0.7.3 → 0.7.5

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.
@@ -6,7 +6,6 @@ import android.app.PendingIntent
6
6
  import android.content.Context
7
7
  import android.content.Intent
8
8
  import android.os.Build
9
- import androidx.core.app.NotificationCompat
10
9
  import android.media.Ringtone
11
10
  import android.media.RingtoneManager
12
11
  import android.graphics.Color
@@ -14,155 +13,103 @@ import android.graphics.Color
14
13
  import androidx.core.app.Person
15
14
  import androidx.core.app.NotificationCompat
16
15
 
16
+ import android.app.KeyguardManager
17
+
18
+
17
19
  object NativeCallManager {
18
20
 
19
21
  private var ringtone: Ringtone? = null
20
22
  const val channelId = "CALL_CHANNEL_ID"
21
23
 
22
- // fun handleIncomingPush(context: Context, data: Map<String, String>) {
23
- // val uuid = data["callUuid"] ?: return
24
- // stopRingtone()
25
-
26
- // val name = data["name"] ?: "Incoming Call"
27
- // val callType = data["callType"] ?: "audio"
28
- // val notificationId = uuid.hashCode()
29
-
30
- // val pendingFlags = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
31
- // PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_MUTABLE
32
- // } else {
33
- // PendingIntent.FLAG_UPDATE_CURRENT
34
- // }
35
-
36
- // val noOpIntent = PendingIntent.getActivity(
37
- // context,
38
- // notificationId + 1,
39
- // Intent(),
40
- // pendingFlags
41
- // )
42
-
43
- // val intentToActivity = Intent(context, AcceptCallActivity::class.java).apply {
44
- // this.action = "ACTION_SHOW_UI_$uuid"
45
- // data.forEach { (key, value) -> this.putExtra(key, value) }
46
- // this.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TOP)
47
- // }
48
-
49
- // val fullScreenPendingIntent = PendingIntent.getActivity(
50
- // context,
51
- // notificationId,
52
- // intentToActivity,
53
- // pendingFlags
54
- // )
55
-
56
- // val rejectIntent = Intent(context, CallActionReceiver::class.java).apply {
57
- // this.action = "ACTION_REJECT_$uuid"
58
- // this.putExtra("EXTRA_CALL_UUID", uuid)
59
- // data.forEach { (key, value) -> this.putExtra(key, value) }
60
- // }
61
-
62
- // val rejectPendingIntent = PendingIntent.getBroadcast(
63
- // context,
64
- // notificationId,
65
- // rejectIntent,
66
- // pendingFlags
67
- // )
68
-
69
- // val notificationManager = context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
70
-
71
- // if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
72
- // val channel = NotificationChannel(
73
- // channelId,
74
- // "Incoming Calls",
75
- // NotificationManager.IMPORTANCE_HIGH // NotificationManager.IMPORTANCE_HIGH
76
- // ).apply {
77
- // enableVibration(true)
78
- // vibrationPattern = longArrayOf(0, 500, 500, 500)
79
- // lightColor = Color.GREEN
80
- // setBypassDnd(true)
81
- // lockscreenVisibility = NotificationCompat.VISIBILITY_PUBLIC
82
- // setSound(null, null)
83
- // }
84
- // notificationManager.createNotificationChannel(channel)
85
- // }
86
-
87
- // val builder = NotificationCompat.Builder(context, channelId)
88
- // .setSmallIcon(context.applicationInfo.icon)
89
- // .setContentTitle("Incoming $callType call")
90
- // .setContentText(name)
91
- // .setPriority(NotificationCompat.PRIORITY_MAX) // PRIORITY_HIGH
92
- // .setCategory(NotificationCompat.CATEGORY_CALL) // CATEGORY_CALL
93
- // .setOngoing(true)
94
- // .setAutoCancel(false)
95
- // .setVisibility(NotificationCompat.VISIBILITY_PUBLIC)
96
- // .setFullScreenIntent(fullScreenPendingIntent, true)
97
- // .setContentIntent(noOpIntent)
98
- // .addAction(0, "Answer", fullScreenPendingIntent)
99
- // .addAction(0, "Decline", rejectPendingIntent)
100
-
101
- // notificationManager.notify(notificationId, builder.build())
102
-
103
- // try {
104
- // val ringtoneUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_RINGTONE)
105
- // ringtone = RingtoneManager.getRingtone(context, ringtoneUri)
106
- // if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
107
- // ringtone?.isLooping = true
108
- // }
109
- // ringtone?.play()
110
- // } catch (e: Exception) {
111
- // e.printStackTrace()
112
- // }
113
- // }
114
-
115
-
116
- fun handleIncomingPush(context: Context, data: Map<String, String>) {
117
- val uuid = data["callUuid"] ?: return
118
- stopRingtone()
119
-
120
- val name = data["name"] ?: "Incoming Call"
121
- val callType = data["callType"] ?: "audio"
122
- val notificationId = uuid.hashCode()
24
+ fun handleIncomingPush(context: Context, data: Map<String, String>) {
25
+ val uuid = data["callUuid"] ?: return
26
+ stopRingtone()
123
27
 
124
- // 1. Create the Person object (Required for CallStyle)
125
- val caller = Person.Builder()
126
- .setName(name)
127
- .setImportant(true)
128
- .build()
129
-
130
- // 2. Intents (Keep your existing intent logic)
131
- val intentToActivity = Intent(context, AcceptCallActivity::class.java).apply {
132
- this.action = "ACTION_ANSWER_$uuid"
133
- data.forEach { (key, value) -> this.putExtra(key, value) }
134
- this.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TOP)
28
+ val name = data["name"] ?: "Incoming Call"
29
+ val callType = data["callType"] ?: "audio"
30
+ // --- LOCK SCREEN GATEKEEPER ---
31
+ val keyguardManager = context.getSystemService(Context.KEYGUARD_SERVICE) as KeyguardManager
32
+ if (keyguardManager.isKeyguardLocked) {
33
+ // Device is locked? We bounce it!
34
+ CallState.markCanceled(uuid, context) // Save to disk so Headless/Splash sees it's invalid
35
+ showMissedCallNotification(context, data, uuid)
36
+ return // Kill the flow here
135
37
  }
38
+ val notificationId = uuid.hashCode()
136
39
 
137
- val fullScreenPendingIntent = PendingIntent.getActivity(
138
- context, notificationId, intentToActivity,
139
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S)
140
- PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_MUTABLE
141
- else PendingIntent.FLAG_UPDATE_CURRENT
142
- )
40
+ val pendingFlags = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
41
+ PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_MUTABLE
42
+ } else {
43
+ PendingIntent.FLAG_UPDATE_CURRENT
44
+ }
143
45
 
144
- // 3. Build the Notification with CallStyle
145
- val builder = NotificationCompat.Builder(context, channelId)
146
- .setSmallIcon(context.applicationInfo.icon)
147
- .setPriority(NotificationCompat.PRIORITY_MAX)
148
- .setCategory(NotificationCompat.CATEGORY_CALL)
149
- .setOngoing(true)
150
- .setAutoCancel(false)
151
- .setVisibility(NotificationCompat.VISIBILITY_PUBLIC)
152
- // This makes it show on the lock screen WITHOUT auto-launching the activity
153
- .setFullScreenIntent(fullScreenPendingIntent, true)
154
- .setStyle(
155
- NotificationCompat.CallStyle.forIncomingCall(
156
- caller,
157
- rejectPendingIntent, // Use your existing rejectIntent
158
- fullScreenPendingIntent
159
- )
46
+ val noOpIntent = PendingIntent.getActivity(
47
+ context,
48
+ notificationId + 1,
49
+ Intent(),
50
+ pendingFlags
160
51
  )
161
52
 
162
- val notificationManager = context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
163
- // ... ensure channel is created ...
164
- notificationManager.notify(notificationId, builder.build())
165
-
53
+ val intentToActivity = Intent(context, AcceptCallActivity::class.java).apply {
54
+ this.action = "ACTION_SHOW_UI_$uuid"
55
+ data.forEach { (key, value) -> this.putExtra(key, value) }
56
+ this.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TOP)
57
+ }
58
+
59
+ val fullScreenPendingIntent = PendingIntent.getActivity(
60
+ context,
61
+ notificationId,
62
+ intentToActivity,
63
+ pendingFlags
64
+ )
65
+
66
+ val rejectIntent = Intent(context, CallActionReceiver::class.java).apply {
67
+ this.action = "ACTION_REJECT_$uuid"
68
+ this.putExtra("EXTRA_CALL_UUID", uuid)
69
+ data.forEach { (key, value) -> this.putExtra(key, value) }
70
+ }
71
+
72
+ val rejectPendingIntent = PendingIntent.getBroadcast(
73
+ context,
74
+ notificationId,
75
+ rejectIntent,
76
+ pendingFlags
77
+ )
78
+
79
+ val notificationManager = context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
80
+
81
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
82
+ val channel = NotificationChannel(
83
+ channelId,
84
+ "Incoming Calls",
85
+ NotificationManager.IMPORTANCE_HIGH // NotificationManager.IMPORTANCE_HIGH
86
+ ).apply {
87
+ enableVibration(true)
88
+ vibrationPattern = longArrayOf(0, 500, 500, 500)
89
+ lightColor = Color.GREEN
90
+ setBypassDnd(true)
91
+ lockscreenVisibility = NotificationCompat.VISIBILITY_PUBLIC
92
+ setSound(null, null)
93
+ }
94
+ notificationManager.createNotificationChannel(channel)
95
+ }
96
+
97
+ val builder = NotificationCompat.Builder(context, channelId)
98
+ .setSmallIcon(context.applicationInfo.icon)
99
+ .setContentTitle("Incoming $callType call")
100
+ .setContentText(name)
101
+ .setPriority(NotificationCompat.PRIORITY_MAX) // PRIORITY_HIGH
102
+ .setCategory(NotificationCompat.CATEGORY_CALL) // CATEGORY_CALL
103
+ .setOngoing(true)
104
+ .setAutoCancel(false)
105
+ .setVisibility(NotificationCompat.VISIBILITY_PUBLIC)
106
+ .setFullScreenIntent(fullScreenPendingIntent, true)
107
+ .setContentIntent(noOpIntent)
108
+ .addAction(0, "Answer", fullScreenPendingIntent)
109
+ .addAction(0, "Decline", rejectPendingIntent)
110
+
111
+ notificationManager.notify(notificationId, builder.build())
112
+
166
113
  try {
167
114
  val ringtoneUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_RINGTONE)
168
115
  ringtone = RingtoneManager.getRingtone(context, ringtoneUri)
@@ -173,17 +120,110 @@ fun handleIncomingPush(context: Context, data: Map<String, String>) {
173
120
  } catch (e: Exception) {
174
121
  e.printStackTrace()
175
122
  }
176
- }
177
-
178
- fun stopRingtone() {
179
- try {
180
- ringtone?.let { if (it.isPlaying) it.stop() }
181
- ringtone = null
182
- } catch (e: Exception) {
183
- ringtone = null
184
- }
185
123
  }
186
124
 
125
+ // fun handleIncomingPush(context: Context, data: Map<String, String>) {
126
+ // val uuid = data["callUuid"] ?: return
127
+ // stopRingtone()
128
+
129
+ // val name = data["name"] ?: "Incoming Call"
130
+ // val callType = data["callType"] ?: "audio"
131
+ // val notificationId = uuid.hashCode()
132
+
133
+ // val pendingFlags = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
134
+ // PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_MUTABLE
135
+ // } else {
136
+ // PendingIntent.FLAG_UPDATE_CURRENT
137
+ // }
138
+
139
+ // // 1. Setup the Intents
140
+ // val intentToActivity = Intent(context, AcceptCallActivity::class.java).apply {
141
+ // this.action = "ACTION_ANSWER_$uuid"
142
+ // data.forEach { (key, value) -> this.putExtra(key, value) }
143
+ // this.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TOP)
144
+ // }
145
+
146
+ // val fullScreenPendingIntent = PendingIntent.getActivity(
147
+ // context, notificationId, intentToActivity, pendingFlags
148
+ // )
149
+
150
+ // val rejectIntent = Intent(context, CallActionReceiver::class.java).apply {
151
+ // this.action = "ACTION_REJECT_$uuid"
152
+ // this.putExtra("EXTRA_CALL_UUID", uuid)
153
+ // data.forEach { (key, value) -> this.putExtra(key, value) }
154
+ // }
155
+
156
+ // // Fix: Define the missing rejectPendingIntent
157
+ // val rejectPendingIntent = PendingIntent.getBroadcast(
158
+ // context, notificationId, rejectIntent, pendingFlags
159
+ // )
160
+
161
+ // // 2. Create the Person object for CallStyle
162
+ // val caller = Person.Builder()
163
+ // .setName(name)
164
+ // .setImportant(true)
165
+ // .build()
166
+
167
+ // val notificationManager = context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
168
+
169
+ // // 3. Setup Channel
170
+ // if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
171
+ // val channel = NotificationChannel(
172
+ // channelId,
173
+ // "Incoming Calls",
174
+ // NotificationManager.IMPORTANCE_HIGH
175
+ // ).apply {
176
+ // enableVibration(true)
177
+ // vibrationPattern = longArrayOf(0, 500, 500, 500)
178
+ // lightColor = Color.GREEN
179
+ // setBypassDnd(true)
180
+ // setSound(null, null)
181
+ // }
182
+ // notificationManager.createNotificationChannel(channel)
183
+ // }
184
+
185
+ // // 4. Build with CallStyle
186
+ // val builder = NotificationCompat.Builder(context, channelId)
187
+ // .setSmallIcon(context.applicationInfo.icon)
188
+ // .setPriority(NotificationCompat.PRIORITY_MAX)
189
+ // .setCategory(NotificationCompat.CATEGORY_CALL)
190
+ // .setOngoing(true)
191
+ // .setAutoCancel(false)
192
+ // .setVisibility(NotificationCompat.VISIBILITY_PUBLIC)
193
+ // .setFullScreenIntent(fullScreenPendingIntent, true)
194
+ // .setStyle(
195
+ // NotificationCompat.CallStyle.forIncomingCall(
196
+ // caller,
197
+ // rejectPendingIntent,
198
+ // fullScreenPendingIntent
199
+ // )
200
+ // )
201
+
202
+ // notificationManager.notify(notificationId, builder.build())
203
+
204
+ // // 5. Start Ringtone
205
+ // try {
206
+ // val ringtoneUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_RINGTONE)
207
+ // ringtone = RingtoneManager.getRingtone(context, ringtoneUri)
208
+ // if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
209
+ // ringtone?.isLooping = true
210
+ // }
211
+ // ringtone?.play()
212
+ // } catch (e: Exception) {
213
+ // e.printStackTrace()
214
+ // }
215
+ // }
216
+
217
+
218
+ // fun stopRingtone() {
219
+ // try {
220
+ // ringtone?.let { if (it.isPlaying) it.stop() }
221
+ // ringtone = null
222
+ // } catch (e: Exception) {
223
+ // ringtone = null
224
+ // }
225
+ // }
226
+
187
227
  fun connecting(context: Context, uuid: String, name: String, callType: String) {
188
228
  val notificationId = uuid.hashCode()
189
229
  val notificationManager = context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
@@ -222,7 +262,6 @@ fun aborting(context: Context, uuid: String, name: String, callType: String) {
222
262
  notificationManager.notify(notificationId, builder.build())
223
263
  }
224
264
 
225
-
226
265
  fun dismissIncomingCall(context: Context, uuid: String?) {
227
266
  stopRingtone()
228
267
  val notificationManager = context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "rns-nativecall",
3
- "version": "0.7.3",
3
+ "version": "0.7.5",
4
4
  "description": "High-performance React Native module for handling native VoIP call UI on Android and iOS.",
5
5
  "main": "index.js",
6
6
  "types": "index.d.ts",