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
|
-
|
|
23
|
-
|
|
24
|
-
|
|
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
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
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
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
PendingIntent.FLAG_UPDATE_CURRENT
|
|
141
|
-
|
|
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
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
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
|
-
|
|
163
|
-
|
|
164
|
-
|
|
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
|