rns-nativecall 0.7.4 → 0.7.6
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.
|
@@ -9,132 +9,72 @@ import android.os.Build
|
|
|
9
9
|
import android.media.Ringtone
|
|
10
10
|
import android.media.RingtoneManager
|
|
11
11
|
import android.graphics.Color
|
|
12
|
-
|
|
13
12
|
import androidx.core.app.Person
|
|
14
13
|
import androidx.core.app.NotificationCompat
|
|
14
|
+
import android.app.KeyguardManager
|
|
15
15
|
|
|
16
16
|
object NativeCallManager {
|
|
17
17
|
|
|
18
18
|
private var ringtone: Ringtone? = null
|
|
19
19
|
const val channelId = "CALL_CHANNEL_ID"
|
|
20
20
|
|
|
21
|
-
//
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
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)
|
|
21
|
+
// ✅ ADDED: stopRingtone definition
|
|
22
|
+
fun stopRingtone() {
|
|
23
|
+
try {
|
|
24
|
+
ringtone?.let { if (it.isPlaying) it.stop() }
|
|
25
|
+
ringtone = null
|
|
26
|
+
} catch (e: Exception) {
|
|
27
|
+
ringtone = null
|
|
28
|
+
}
|
|
29
|
+
}
|
|
99
30
|
|
|
100
|
-
//
|
|
31
|
+
// ✅ ADDED: showMissedCallNotification definition
|
|
32
|
+
fun showMissedCallNotification(context: Context, data: Map<String, String>, uuid: String) {
|
|
33
|
+
val name = data["name"] ?: "Unknown Caller"
|
|
34
|
+
val notificationManager = context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
|
|
35
|
+
|
|
36
|
+
val builder = NotificationCompat.Builder(context, channelId)
|
|
37
|
+
.setSmallIcon(context.applicationInfo.icon)
|
|
38
|
+
.setContentTitle("Missed Call")
|
|
39
|
+
.setContentText("Incoming call from $name")
|
|
40
|
+
.setPriority(NotificationCompat.PRIORITY_HIGH)
|
|
41
|
+
.setAutoCancel(true)
|
|
101
42
|
|
|
102
|
-
|
|
103
|
-
|
|
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
|
-
// }
|
|
43
|
+
notificationManager.notify(uuid.hashCode(), builder.build())
|
|
44
|
+
}
|
|
113
45
|
|
|
114
|
-
|
|
46
|
+
fun handleIncomingPush(context: Context, data: Map<String, String>) {
|
|
115
47
|
val uuid = data["callUuid"] ?: return
|
|
116
48
|
stopRingtone()
|
|
117
49
|
|
|
118
50
|
val name = data["name"] ?: "Incoming Call"
|
|
119
51
|
val callType = data["callType"] ?: "audio"
|
|
120
|
-
val notificationId = uuid.hashCode()
|
|
121
52
|
|
|
53
|
+
// --- LOCK SCREEN GATEKEEPER ---
|
|
54
|
+
val keyguardManager = context.getSystemService(Context.KEYGUARD_SERVICE) as KeyguardManager
|
|
55
|
+
if (keyguardManager.isKeyguardLocked) {
|
|
56
|
+
// Device is locked? We bounce it!
|
|
57
|
+
CallState.markCanceled(uuid, context)
|
|
58
|
+
showMissedCallNotification(context, data, uuid)
|
|
59
|
+
return // 🛑 Flow stops here
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
val notificationId = uuid.hashCode()
|
|
122
63
|
val pendingFlags = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
|
|
123
64
|
PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_MUTABLE
|
|
124
65
|
} else {
|
|
125
66
|
PendingIntent.FLAG_UPDATE_CURRENT
|
|
126
67
|
}
|
|
127
68
|
|
|
128
|
-
|
|
69
|
+
val noOpIntent = PendingIntent.getActivity(context, notificationId + 1, Intent(), pendingFlags)
|
|
70
|
+
|
|
129
71
|
val intentToActivity = Intent(context, AcceptCallActivity::class.java).apply {
|
|
130
|
-
this.action = "
|
|
72
|
+
this.action = "ACTION_SHOW_UI_$uuid"
|
|
131
73
|
data.forEach { (key, value) -> this.putExtra(key, value) }
|
|
132
74
|
this.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TOP)
|
|
133
75
|
}
|
|
134
76
|
|
|
135
|
-
val fullScreenPendingIntent = PendingIntent.getActivity(
|
|
136
|
-
context, notificationId, intentToActivity, pendingFlags
|
|
137
|
-
)
|
|
77
|
+
val fullScreenPendingIntent = PendingIntent.getActivity(context, notificationId, intentToActivity, pendingFlags)
|
|
138
78
|
|
|
139
79
|
val rejectIntent = Intent(context, CallActionReceiver::class.java).apply {
|
|
140
80
|
this.action = "ACTION_REJECT_$uuid"
|
|
@@ -142,55 +82,38 @@ object NativeCallManager {
|
|
|
142
82
|
data.forEach { (key, value) -> this.putExtra(key, value) }
|
|
143
83
|
}
|
|
144
84
|
|
|
145
|
-
|
|
146
|
-
val rejectPendingIntent = PendingIntent.getBroadcast(
|
|
147
|
-
context, notificationId, rejectIntent, pendingFlags
|
|
148
|
-
)
|
|
149
|
-
|
|
150
|
-
// 2. Create the Person object for CallStyle
|
|
151
|
-
val caller = Person.Builder()
|
|
152
|
-
.setName(name)
|
|
153
|
-
.setImportant(true)
|
|
154
|
-
.build()
|
|
85
|
+
val rejectPendingIntent = PendingIntent.getBroadcast(context, notificationId, rejectIntent, pendingFlags)
|
|
155
86
|
|
|
156
87
|
val notificationManager = context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
|
|
157
88
|
|
|
158
|
-
// 3. Setup Channel
|
|
159
89
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
|
160
|
-
val channel = NotificationChannel(
|
|
161
|
-
channelId,
|
|
162
|
-
"Incoming Calls",
|
|
163
|
-
NotificationManager.IMPORTANCE_HIGH
|
|
164
|
-
).apply {
|
|
90
|
+
val channel = NotificationChannel(channelId, "Incoming Calls", NotificationManager.IMPORTANCE_HIGH).apply {
|
|
165
91
|
enableVibration(true)
|
|
166
92
|
vibrationPattern = longArrayOf(0, 500, 500, 500)
|
|
167
93
|
lightColor = Color.GREEN
|
|
168
94
|
setBypassDnd(true)
|
|
95
|
+
lockscreenVisibility = NotificationCompat.VISIBILITY_PUBLIC
|
|
169
96
|
setSound(null, null)
|
|
170
97
|
}
|
|
171
98
|
notificationManager.createNotificationChannel(channel)
|
|
172
99
|
}
|
|
173
100
|
|
|
174
|
-
// 4. Build with CallStyle
|
|
175
101
|
val builder = NotificationCompat.Builder(context, channelId)
|
|
176
102
|
.setSmallIcon(context.applicationInfo.icon)
|
|
103
|
+
.setContentTitle("Incoming $callType call")
|
|
104
|
+
.setContentText(name)
|
|
177
105
|
.setPriority(NotificationCompat.PRIORITY_MAX)
|
|
178
106
|
.setCategory(NotificationCompat.CATEGORY_CALL)
|
|
179
107
|
.setOngoing(true)
|
|
180
108
|
.setAutoCancel(false)
|
|
181
109
|
.setVisibility(NotificationCompat.VISIBILITY_PUBLIC)
|
|
182
110
|
.setFullScreenIntent(fullScreenPendingIntent, true)
|
|
183
|
-
.
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
rejectPendingIntent,
|
|
187
|
-
fullScreenPendingIntent
|
|
188
|
-
)
|
|
189
|
-
)
|
|
111
|
+
.setContentIntent(noOpIntent)
|
|
112
|
+
.addAction(0, "Answer", fullScreenPendingIntent)
|
|
113
|
+
.addAction(0, "Decline", rejectPendingIntent)
|
|
190
114
|
|
|
191
115
|
notificationManager.notify(notificationId, builder.build())
|
|
192
116
|
|
|
193
|
-
// 5. Start Ringtone
|
|
194
117
|
try {
|
|
195
118
|
val ringtoneUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_RINGTONE)
|
|
196
119
|
ringtone = RingtoneManager.getRingtone(context, ringtoneUri)
|
|
@@ -203,53 +126,35 @@ object NativeCallManager {
|
|
|
203
126
|
}
|
|
204
127
|
}
|
|
205
128
|
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
129
|
+
fun connecting(context: Context, uuid: String, name: String, callType: String) {
|
|
130
|
+
val notificationId = uuid.hashCode()
|
|
131
|
+
val notificationManager = context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
|
|
132
|
+
val builder = NotificationCompat.Builder(context, channelId)
|
|
133
|
+
.setSmallIcon(context.applicationInfo.icon)
|
|
134
|
+
.setContentTitle("Incoming $callType call")
|
|
135
|
+
.setContentText("Connecting…")
|
|
136
|
+
.setPriority(NotificationCompat.PRIORITY_MAX)
|
|
137
|
+
.setCategory(NotificationCompat.CATEGORY_CALL)
|
|
138
|
+
.setOngoing(true)
|
|
139
|
+
.setVisibility(NotificationCompat.VISIBILITY_PUBLIC)
|
|
140
|
+
.setProgress(0, 0, true)
|
|
141
|
+
notificationManager.notify(notificationId, builder.build())
|
|
214
142
|
}
|
|
215
143
|
|
|
216
|
-
fun
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
.
|
|
229
|
-
|
|
230
|
-
.setProgress(0, 0, true) // ✅ system activity indicator (indeterminate progress bar)
|
|
231
|
-
|
|
232
|
-
notificationManager.notify(notificationId, builder.build())
|
|
233
|
-
}
|
|
234
|
-
|
|
235
|
-
fun aborting(context: Context, uuid: String, name: String, callType: String) {
|
|
236
|
-
val notificationId = uuid.hashCode()
|
|
237
|
-
val notificationManager = context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
|
|
238
|
-
|
|
239
|
-
val builder = NotificationCompat.Builder(context, channelId)
|
|
240
|
-
.setSmallIcon(context.applicationInfo.icon)
|
|
241
|
-
.setContentTitle("Incoming $callType call")
|
|
242
|
-
.setContentText("Aborting…") // ✅ show aborting text
|
|
243
|
-
.setSubText("Aborting…") // status line
|
|
244
|
-
.setPriority(NotificationCompat.PRIORITY_MAX)
|
|
245
|
-
.setCategory(NotificationCompat.CATEGORY_CALL)
|
|
246
|
-
.setOngoing(true)
|
|
247
|
-
.setAutoCancel(false)
|
|
248
|
-
.setVisibility(NotificationCompat.VISIBILITY_PUBLIC)
|
|
249
|
-
.setProgress(0, 0, true) // ✅ indeterminate progress indicator
|
|
250
|
-
|
|
251
|
-
notificationManager.notify(notificationId, builder.build())
|
|
252
|
-
}
|
|
144
|
+
fun aborting(context: Context, uuid: String, name: String, callType: String) {
|
|
145
|
+
val notificationId = uuid.hashCode()
|
|
146
|
+
val notificationManager = context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
|
|
147
|
+
val builder = NotificationCompat.Builder(context, channelId)
|
|
148
|
+
.setSmallIcon(context.applicationInfo.icon)
|
|
149
|
+
.setContentTitle("Incoming $callType call")
|
|
150
|
+
.setContentText("Aborting…")
|
|
151
|
+
.setPriority(NotificationCompat.PRIORITY_MAX)
|
|
152
|
+
.setCategory(NotificationCompat.CATEGORY_CALL)
|
|
153
|
+
.setOngoing(true)
|
|
154
|
+
.setVisibility(NotificationCompat.VISIBILITY_PUBLIC)
|
|
155
|
+
.setProgress(0, 0, true)
|
|
156
|
+
notificationManager.notify(notificationId, builder.build())
|
|
157
|
+
}
|
|
253
158
|
|
|
254
159
|
fun dismissIncomingCall(context: Context, uuid: String?) {
|
|
255
160
|
stopRingtone()
|