rns-nativecall 0.7.4 → 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.
@@ -13,110 +13,28 @@ import android.graphics.Color
13
13
  import androidx.core.app.Person
14
14
  import androidx.core.app.NotificationCompat
15
15
 
16
+ import android.app.KeyguardManager
17
+
18
+
16
19
  object NativeCallManager {
17
20
 
18
21
  private var ringtone: Ringtone? = null
19
22
  const val channelId = "CALL_CHANNEL_ID"
20
23
 
21
- // fun handleIncomingPush(context: Context, data: Map<String, String>) {
22
- // val uuid = data["callUuid"] ?: return
23
- // stopRingtone()
24
-
25
- // val name = data["name"] ?: "Incoming Call"
26
- // val callType = data["callType"] ?: "audio"
27
- // val notificationId = uuid.hashCode()
28
-
29
- // val pendingFlags = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
30
- // PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_MUTABLE
31
- // } else {
32
- // PendingIntent.FLAG_UPDATE_CURRENT
33
- // }
34
-
35
- // val noOpIntent = PendingIntent.getActivity(
36
- // context,
37
- // notificationId + 1,
38
- // Intent(),
39
- // pendingFlags
40
- // )
41
-
42
- // val intentToActivity = Intent(context, AcceptCallActivity::class.java).apply {
43
- // this.action = "ACTION_SHOW_UI_$uuid"
44
- // data.forEach { (key, value) -> this.putExtra(key, value) }
45
- // this.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TOP)
46
- // }
47
-
48
- // val fullScreenPendingIntent = PendingIntent.getActivity(
49
- // context,
50
- // notificationId,
51
- // intentToActivity,
52
- // pendingFlags
53
- // )
54
-
55
- // val rejectIntent = Intent(context, CallActionReceiver::class.java).apply {
56
- // this.action = "ACTION_REJECT_$uuid"
57
- // this.putExtra("EXTRA_CALL_UUID", uuid)
58
- // data.forEach { (key, value) -> this.putExtra(key, value) }
59
- // }
60
-
61
- // val rejectPendingIntent = PendingIntent.getBroadcast(
62
- // context,
63
- // notificationId,
64
- // rejectIntent,
65
- // pendingFlags
66
- // )
67
-
68
- // val notificationManager = context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
69
-
70
- // if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
71
- // val channel = NotificationChannel(
72
- // channelId,
73
- // "Incoming Calls",
74
- // NotificationManager.IMPORTANCE_HIGH // NotificationManager.IMPORTANCE_HIGH
75
- // ).apply {
76
- // enableVibration(true)
77
- // vibrationPattern = longArrayOf(0, 500, 500, 500)
78
- // lightColor = Color.GREEN
79
- // setBypassDnd(true)
80
- // lockscreenVisibility = NotificationCompat.VISIBILITY_PUBLIC
81
- // setSound(null, null)
82
- // }
83
- // notificationManager.createNotificationChannel(channel)
84
- // }
85
-
86
- // val builder = NotificationCompat.Builder(context, channelId)
87
- // .setSmallIcon(context.applicationInfo.icon)
88
- // .setContentTitle("Incoming $callType call")
89
- // .setContentText(name)
90
- // .setPriority(NotificationCompat.PRIORITY_MAX) // PRIORITY_HIGH
91
- // .setCategory(NotificationCompat.CATEGORY_CALL) // CATEGORY_CALL
92
- // .setOngoing(true)
93
- // .setAutoCancel(false)
94
- // .setVisibility(NotificationCompat.VISIBILITY_PUBLIC)
95
- // .setFullScreenIntent(fullScreenPendingIntent, true)
96
- // .setContentIntent(noOpIntent)
97
- // .addAction(0, "Answer", fullScreenPendingIntent)
98
- // .addAction(0, "Decline", rejectPendingIntent)
99
-
100
- // notificationManager.notify(notificationId, builder.build())
101
-
102
- // try {
103
- // val ringtoneUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_RINGTONE)
104
- // ringtone = RingtoneManager.getRingtone(context, ringtoneUri)
105
- // if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
106
- // ringtone?.isLooping = true
107
- // }
108
- // ringtone?.play()
109
- // } catch (e: Exception) {
110
- // e.printStackTrace()
111
- // }
112
- // }
113
-
114
- fun handleIncomingPush(context: Context, data: Map<String, String>) {
24
+ fun handleIncomingPush(context: Context, data: Map<String, String>) {
115
25
  val uuid = data["callUuid"] ?: return
116
26
  stopRingtone()
117
27
 
118
28
  val name = data["name"] ?: "Incoming Call"
119
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
37
+ }
120
38
  val notificationId = uuid.hashCode()
121
39
 
122
40
  val pendingFlags = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
@@ -125,15 +43,24 @@ object NativeCallManager {
125
43
  PendingIntent.FLAG_UPDATE_CURRENT
126
44
  }
127
45
 
128
- // 1. Setup the Intents
46
+ val noOpIntent = PendingIntent.getActivity(
47
+ context,
48
+ notificationId + 1,
49
+ Intent(),
50
+ pendingFlags
51
+ )
52
+
129
53
  val intentToActivity = Intent(context, AcceptCallActivity::class.java).apply {
130
- this.action = "ACTION_ANSWER_$uuid"
54
+ this.action = "ACTION_SHOW_UI_$uuid"
131
55
  data.forEach { (key, value) -> this.putExtra(key, value) }
132
56
  this.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TOP)
133
57
  }
134
58
 
135
59
  val fullScreenPendingIntent = PendingIntent.getActivity(
136
- context, notificationId, intentToActivity, pendingFlags
60
+ context,
61
+ notificationId,
62
+ intentToActivity,
63
+ pendingFlags
137
64
  )
138
65
 
139
66
  val rejectIntent = Intent(context, CallActionReceiver::class.java).apply {
@@ -142,55 +69,47 @@ object NativeCallManager {
142
69
  data.forEach { (key, value) -> this.putExtra(key, value) }
143
70
  }
144
71
 
145
- // Fix: Define the missing rejectPendingIntent
146
72
  val rejectPendingIntent = PendingIntent.getBroadcast(
147
- context, notificationId, rejectIntent, pendingFlags
73
+ context,
74
+ notificationId,
75
+ rejectIntent,
76
+ pendingFlags
148
77
  )
149
78
 
150
- // 2. Create the Person object for CallStyle
151
- val caller = Person.Builder()
152
- .setName(name)
153
- .setImportant(true)
154
- .build()
155
-
156
79
  val notificationManager = context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
157
80
 
158
- // 3. Setup Channel
159
81
  if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
160
82
  val channel = NotificationChannel(
161
83
  channelId,
162
84
  "Incoming Calls",
163
- NotificationManager.IMPORTANCE_HIGH
85
+ NotificationManager.IMPORTANCE_HIGH // NotificationManager.IMPORTANCE_HIGH
164
86
  ).apply {
165
87
  enableVibration(true)
166
88
  vibrationPattern = longArrayOf(0, 500, 500, 500)
167
89
  lightColor = Color.GREEN
168
90
  setBypassDnd(true)
91
+ lockscreenVisibility = NotificationCompat.VISIBILITY_PUBLIC
169
92
  setSound(null, null)
170
93
  }
171
94
  notificationManager.createNotificationChannel(channel)
172
95
  }
173
96
 
174
- // 4. Build with CallStyle
175
97
  val builder = NotificationCompat.Builder(context, channelId)
176
98
  .setSmallIcon(context.applicationInfo.icon)
177
- .setPriority(NotificationCompat.PRIORITY_MAX)
178
- .setCategory(NotificationCompat.CATEGORY_CALL)
99
+ .setContentTitle("Incoming $callType call")
100
+ .setContentText(name)
101
+ .setPriority(NotificationCompat.PRIORITY_MAX) // PRIORITY_HIGH
102
+ .setCategory(NotificationCompat.CATEGORY_CALL) // CATEGORY_CALL
179
103
  .setOngoing(true)
180
104
  .setAutoCancel(false)
181
105
  .setVisibility(NotificationCompat.VISIBILITY_PUBLIC)
182
106
  .setFullScreenIntent(fullScreenPendingIntent, true)
183
- .setStyle(
184
- NotificationCompat.CallStyle.forIncomingCall(
185
- caller,
186
- rejectPendingIntent,
187
- fullScreenPendingIntent
188
- )
189
- )
107
+ .setContentIntent(noOpIntent)
108
+ .addAction(0, "Answer", fullScreenPendingIntent)
109
+ .addAction(0, "Decline", rejectPendingIntent)
190
110
 
191
111
  notificationManager.notify(notificationId, builder.build())
192
112
 
193
- // 5. Start Ringtone
194
113
  try {
195
114
  val ringtoneUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_RINGTONE)
196
115
  ringtone = RingtoneManager.getRingtone(context, ringtoneUri)
@@ -203,15 +122,107 @@ object NativeCallManager {
203
122
  }
204
123
  }
205
124
 
206
-
207
- fun stopRingtone() {
208
- try {
209
- ringtone?.let { if (it.isPlaying) it.stop() }
210
- ringtone = null
211
- } catch (e: Exception) {
212
- ringtone = null
213
- }
214
- }
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
+ // }
215
226
 
216
227
  fun connecting(context: Context, uuid: String, name: String, callType: String) {
217
228
  val notificationId = uuid.hashCode()
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "rns-nativecall",
3
- "version": "0.7.4",
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",