rns-nativecall 0.7.2 → 0.7.4
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,7 +13,6 @@ class AcceptCallActivity : Activity() {
|
|
|
13
13
|
override fun onCreate(savedInstanceState: Bundle?) {
|
|
14
14
|
super.onCreate(savedInstanceState)
|
|
15
15
|
|
|
16
|
-
// Ensure we show over the lockscreen
|
|
17
16
|
window.addFlags(
|
|
18
17
|
WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED or
|
|
19
18
|
WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON or
|
|
@@ -23,6 +22,14 @@ class AcceptCallActivity : Activity() {
|
|
|
23
22
|
val keyguardManager = getSystemService(Context.KEYGUARD_SERVICE) as KeyguardManager
|
|
24
23
|
keyguardManager.requestDismissKeyguard(this, null)
|
|
25
24
|
|
|
25
|
+
// Check: Did the user actually press "Answer" or did the system auto-launch?
|
|
26
|
+
// If the action is null or doesn't match your Answer action,
|
|
27
|
+
// it means the system is just "preparing" the activity.
|
|
28
|
+
if (intent.action?.startsWith("ACTION_ANSWER") != true) {
|
|
29
|
+
// If it's just an auto-launch, we don't fire the JS event!
|
|
30
|
+
// We can either finish() or show a tiny "Swipe to Answer" UI.
|
|
31
|
+
return
|
|
32
|
+
}
|
|
26
33
|
processCallIntent(intent)
|
|
27
34
|
}
|
|
28
35
|
|
|
@@ -35,30 +42,36 @@ class AcceptCallActivity : Activity() {
|
|
|
35
42
|
val notificationManager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
|
|
36
43
|
uuid?.let { notificationManager.cancel(it.hashCode()) }
|
|
37
44
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
extras.get(key)?.let { dataMap[key] = it.toString() }
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
// 1. Set the data for JS (Cold start support)
|
|
44
|
-
CallModule.setPendingCallData("onCallAccepted_pending", dataMap)
|
|
45
|
-
|
|
46
|
-
// 2. Fire event immediately if JS is alive
|
|
47
|
-
if (CallModule.isReady()) {
|
|
48
|
-
CallModule.sendEventToJS("onCallAccepted", dataMap)
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
// 3. Bring the Main App to the front
|
|
45
|
+
// ✅ WE STOP SENDING THE JS EVENT HERE.
|
|
46
|
+
// Instead, we pass the intent to MainActivity with a specific ACTION.
|
|
52
47
|
openMainApp(extras)
|
|
53
48
|
finish()
|
|
54
49
|
}
|
|
55
50
|
|
|
56
51
|
private fun openMainApp(extras: Bundle?) {
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
52
|
+
try {
|
|
53
|
+
// Get the actual MainActivity class name (e.g., com.yourapp.MainActivity)
|
|
54
|
+
val mainActivityClassName = "${packageName}.MainActivity"
|
|
55
|
+
|
|
56
|
+
val intent = Intent().apply {
|
|
57
|
+
setClassName(packageName, mainActivityClassName)
|
|
58
|
+
action = "com.rnsnativecall.ACTION_ANSWER"
|
|
59
|
+
addFlags(Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_SINGLE_TOP)
|
|
60
|
+
|
|
61
|
+
// Ensure extras are carried over
|
|
62
|
+
extras?.let { putExtras(it) }
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
startActivity(intent)
|
|
66
|
+
} catch (e: Exception) {
|
|
67
|
+
// Fallback: If explicit mapping fails, try the launch intent but force the action
|
|
68
|
+
val launchIntent = packageManager.getLaunchIntentForPackage(packageName)
|
|
69
|
+
launchIntent?.apply {
|
|
70
|
+
action = "com.rnsnativecall.ACTION_ANSWER"
|
|
71
|
+
addFlags(Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_SINGLE_TOP)
|
|
72
|
+
extras?.let { putExtras(it) }
|
|
73
|
+
startActivity(this)
|
|
74
|
+
}
|
|
62
75
|
}
|
|
63
76
|
}
|
|
64
77
|
}
|
|
@@ -6,17 +6,112 @@ 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
|
|
13
12
|
|
|
13
|
+
import androidx.core.app.Person
|
|
14
|
+
import androidx.core.app.NotificationCompat
|
|
15
|
+
|
|
14
16
|
object NativeCallManager {
|
|
15
17
|
|
|
16
18
|
private var ringtone: Ringtone? = null
|
|
17
19
|
const val channelId = "CALL_CHANNEL_ID"
|
|
18
20
|
|
|
19
|
-
fun handleIncomingPush(context: Context, data: Map<String, String>) {
|
|
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>) {
|
|
20
115
|
val uuid = data["callUuid"] ?: return
|
|
21
116
|
stopRingtone()
|
|
22
117
|
|
|
@@ -30,24 +125,15 @@ object NativeCallManager {
|
|
|
30
125
|
PendingIntent.FLAG_UPDATE_CURRENT
|
|
31
126
|
}
|
|
32
127
|
|
|
33
|
-
|
|
34
|
-
context,
|
|
35
|
-
notificationId + 1,
|
|
36
|
-
Intent(),
|
|
37
|
-
pendingFlags
|
|
38
|
-
)
|
|
39
|
-
|
|
128
|
+
// 1. Setup the Intents
|
|
40
129
|
val intentToActivity = Intent(context, AcceptCallActivity::class.java).apply {
|
|
41
|
-
this.action = "
|
|
130
|
+
this.action = "ACTION_ANSWER_$uuid"
|
|
42
131
|
data.forEach { (key, value) -> this.putExtra(key, value) }
|
|
43
132
|
this.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TOP)
|
|
44
133
|
}
|
|
45
134
|
|
|
46
135
|
val fullScreenPendingIntent = PendingIntent.getActivity(
|
|
47
|
-
context,
|
|
48
|
-
notificationId,
|
|
49
|
-
intentToActivity,
|
|
50
|
-
pendingFlags
|
|
136
|
+
context, notificationId, intentToActivity, pendingFlags
|
|
51
137
|
)
|
|
52
138
|
|
|
53
139
|
val rejectIntent = Intent(context, CallActionReceiver::class.java).apply {
|
|
@@ -56,47 +142,55 @@ object NativeCallManager {
|
|
|
56
142
|
data.forEach { (key, value) -> this.putExtra(key, value) }
|
|
57
143
|
}
|
|
58
144
|
|
|
145
|
+
// Fix: Define the missing rejectPendingIntent
|
|
59
146
|
val rejectPendingIntent = PendingIntent.getBroadcast(
|
|
60
|
-
context,
|
|
61
|
-
notificationId,
|
|
62
|
-
rejectIntent,
|
|
63
|
-
pendingFlags
|
|
147
|
+
context, notificationId, rejectIntent, pendingFlags
|
|
64
148
|
)
|
|
65
149
|
|
|
150
|
+
// 2. Create the Person object for CallStyle
|
|
151
|
+
val caller = Person.Builder()
|
|
152
|
+
.setName(name)
|
|
153
|
+
.setImportant(true)
|
|
154
|
+
.build()
|
|
155
|
+
|
|
66
156
|
val notificationManager = context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
|
|
67
157
|
|
|
158
|
+
// 3. Setup Channel
|
|
68
159
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
|
69
160
|
val channel = NotificationChannel(
|
|
70
161
|
channelId,
|
|
71
162
|
"Incoming Calls",
|
|
72
|
-
NotificationManager.IMPORTANCE_HIGH
|
|
163
|
+
NotificationManager.IMPORTANCE_HIGH
|
|
73
164
|
).apply {
|
|
74
165
|
enableVibration(true)
|
|
75
166
|
vibrationPattern = longArrayOf(0, 500, 500, 500)
|
|
76
167
|
lightColor = Color.GREEN
|
|
77
168
|
setBypassDnd(true)
|
|
78
|
-
lockscreenVisibility = NotificationCompat.VISIBILITY_PUBLIC
|
|
79
169
|
setSound(null, null)
|
|
80
170
|
}
|
|
81
171
|
notificationManager.createNotificationChannel(channel)
|
|
82
172
|
}
|
|
83
173
|
|
|
174
|
+
// 4. Build with CallStyle
|
|
84
175
|
val builder = NotificationCompat.Builder(context, channelId)
|
|
85
176
|
.setSmallIcon(context.applicationInfo.icon)
|
|
86
|
-
.
|
|
87
|
-
.
|
|
88
|
-
.setPriority(NotificationCompat.PRIORITY_MAX) // PRIORITY_HIGH
|
|
89
|
-
.setCategory(NotificationCompat.CATEGORY_CALL) // CATEGORY_CALL
|
|
177
|
+
.setPriority(NotificationCompat.PRIORITY_MAX)
|
|
178
|
+
.setCategory(NotificationCompat.CATEGORY_CALL)
|
|
90
179
|
.setOngoing(true)
|
|
91
180
|
.setAutoCancel(false)
|
|
92
181
|
.setVisibility(NotificationCompat.VISIBILITY_PUBLIC)
|
|
93
182
|
.setFullScreenIntent(fullScreenPendingIntent, true)
|
|
94
|
-
.
|
|
95
|
-
|
|
96
|
-
|
|
183
|
+
.setStyle(
|
|
184
|
+
NotificationCompat.CallStyle.forIncomingCall(
|
|
185
|
+
caller,
|
|
186
|
+
rejectPendingIntent,
|
|
187
|
+
fullScreenPendingIntent
|
|
188
|
+
)
|
|
189
|
+
)
|
|
97
190
|
|
|
98
191
|
notificationManager.notify(notificationId, builder.build())
|
|
99
192
|
|
|
193
|
+
// 5. Start Ringtone
|
|
100
194
|
try {
|
|
101
195
|
val ringtoneUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_RINGTONE)
|
|
102
196
|
ringtone = RingtoneManager.getRingtone(context, ringtoneUri)
|
|
@@ -109,6 +203,7 @@ object NativeCallManager {
|
|
|
109
203
|
}
|
|
110
204
|
}
|
|
111
205
|
|
|
206
|
+
|
|
112
207
|
fun stopRingtone() {
|
|
113
208
|
try {
|
|
114
209
|
ringtone?.let { if (it.isPlaying) it.stop() }
|
|
@@ -156,7 +251,6 @@ fun aborting(context: Context, uuid: String, name: String, callType: String) {
|
|
|
156
251
|
notificationManager.notify(notificationId, builder.build())
|
|
157
252
|
}
|
|
158
253
|
|
|
159
|
-
|
|
160
254
|
fun dismissIncomingCall(context: Context, uuid: String?) {
|
|
161
255
|
stopRingtone()
|
|
162
256
|
val notificationManager = context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
|