rns-nativecall 0.5.0 → 0.5.2
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.
|
@@ -23,6 +23,15 @@ class CallMessagingService : FirebaseMessagingService() {
|
|
|
23
23
|
private val pendingNotifications = mutableMapOf<String, Runnable>()
|
|
24
24
|
}
|
|
25
25
|
|
|
26
|
+
// Helper to check app state
|
|
27
|
+
private fun isAppInForeground(context: Context): Boolean {
|
|
28
|
+
val activityManager = context.getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager
|
|
29
|
+
val appProcesses = activityManager.runningAppProcesses ?: return false
|
|
30
|
+
return appProcesses.any {
|
|
31
|
+
it.importance == ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND && it.processName == context.packageName
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
26
35
|
override fun onMessageReceived(remoteMessage: RemoteMessage) {
|
|
27
36
|
val data = remoteMessage.data
|
|
28
37
|
val context = applicationContext
|
|
@@ -42,25 +51,20 @@ class CallMessagingService : FirebaseMessagingService() {
|
|
|
42
51
|
if (isAppInForeground(context)) {
|
|
43
52
|
CallModule.sendEventToJS("onCallReceived", data)
|
|
44
53
|
} else {
|
|
45
|
-
// 1. Show the Full Screen Notification IMMEDIATELY
|
|
46
54
|
NativeCallManager.handleIncomingPush(context, data)
|
|
47
55
|
|
|
48
|
-
// 2. Start HeadlessJS Task as a Foreground Service
|
|
49
56
|
try {
|
|
50
57
|
val headlessIntent = Intent(context, CallHeadlessTask::class.java).apply {
|
|
51
58
|
val bundle = Bundle()
|
|
52
59
|
data.forEach { (k, v) -> bundle.putString(k, v) }
|
|
53
60
|
putExtras(bundle)
|
|
54
61
|
}
|
|
55
|
-
|
|
56
|
-
// CRITICAL: Must use startForegroundService for background starts on Android 8+
|
|
57
62
|
ContextCompat.startForegroundService(context, headlessIntent)
|
|
58
63
|
HeadlessJsTaskService.acquireWakeLockNow(context)
|
|
59
64
|
} catch (e: Exception) {
|
|
60
65
|
e.printStackTrace()
|
|
61
66
|
}
|
|
62
67
|
|
|
63
|
-
// 3. Backup Safety
|
|
64
68
|
val showNotificationRunnable = Runnable {
|
|
65
69
|
if (!isAppInForeground(context)) {
|
|
66
70
|
NativeCallManager.handleIncomingPush(context, data)
|
|
@@ -109,12 +113,4 @@ class CallMessagingService : FirebaseMessagingService() {
|
|
|
109
113
|
|
|
110
114
|
notificationManager.notify(uuid.hashCode(), builder.build())
|
|
111
115
|
}
|
|
112
|
-
|
|
113
|
-
private fun isAppInForeground(context: Context): Boolean {
|
|
114
|
-
val activityManager = context.getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager
|
|
115
|
-
val appProcesses = activityManager.runningAppProcesses ?: return false
|
|
116
|
-
return appProcesses.any {
|
|
117
|
-
it.importance == ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND && it.processName == context.packageName
|
|
118
|
-
}
|
|
119
|
-
}
|
|
120
116
|
}
|
|
@@ -4,15 +4,15 @@ import android.app.NotificationChannel
|
|
|
4
4
|
import android.app.NotificationManager
|
|
5
5
|
import android.app.PendingIntent
|
|
6
6
|
import android.content.Context
|
|
7
|
-
import android.content.Intent
|
|
7
|
+
import android.content.Intent
|
|
8
8
|
import android.os.Build
|
|
9
|
-
import android.os.Bundle
|
|
9
|
+
import android.os.Bundle
|
|
10
10
|
import androidx.core.app.NotificationCompat
|
|
11
11
|
import android.media.Ringtone
|
|
12
12
|
import android.media.RingtoneManager
|
|
13
13
|
import android.graphics.Color
|
|
14
14
|
import androidx.core.app.Person
|
|
15
|
-
import androidx.core.
|
|
15
|
+
import androidx.core.graphics.drawable.IconCompat
|
|
16
16
|
|
|
17
17
|
object NativeCallManager {
|
|
18
18
|
|
|
@@ -32,10 +32,16 @@ object NativeCallManager {
|
|
|
32
32
|
PendingIntent.FLAG_UPDATE_CURRENT
|
|
33
33
|
}
|
|
34
34
|
|
|
35
|
-
//
|
|
35
|
+
// Prepare Common Bundle
|
|
36
|
+
val extras = Bundle().apply {
|
|
37
|
+
data.forEach { (k, v) -> putString(k, v) }
|
|
38
|
+
putString("EXTRA_CALL_UUID", uuid)
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
// 1. UI Intent (When tapping the notification body)
|
|
36
42
|
val intentToActivity = Intent(context, AcceptCallActivity::class.java).apply {
|
|
37
43
|
action = "ACTION_SHOW_UI_$uuid"
|
|
38
|
-
|
|
44
|
+
putExtras(extras)
|
|
39
45
|
addFlags(Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TOP)
|
|
40
46
|
}
|
|
41
47
|
val fullScreenPendingIntent = PendingIntent.getActivity(
|
|
@@ -45,18 +51,16 @@ object NativeCallManager {
|
|
|
45
51
|
// 2. Reject Intent
|
|
46
52
|
val rejectIntent = Intent(context, CallActionReceiver::class.java).apply {
|
|
47
53
|
action = "ACTION_REJECT_$uuid"
|
|
48
|
-
|
|
49
|
-
data.forEach { (key, value) -> putExtra(key, value) }
|
|
54
|
+
putExtras(extras)
|
|
50
55
|
}
|
|
51
56
|
val rejectPendingIntent = PendingIntent.getBroadcast(
|
|
52
57
|
context, uuid.hashCode() + 1, rejectIntent, pendingFlags
|
|
53
58
|
)
|
|
54
59
|
|
|
55
|
-
// 3. Answer Intent
|
|
60
|
+
// 3. Answer Intent
|
|
56
61
|
val answerIntent = Intent(context, CallActionReceiver::class.java).apply {
|
|
57
|
-
action = "ACTION_ACCEPT_$uuid"
|
|
58
|
-
|
|
59
|
-
data.forEach { (key, value) -> putExtra(key, value) }
|
|
62
|
+
action = "ACTION_ACCEPT_$uuid"
|
|
63
|
+
putExtras(extras)
|
|
60
64
|
}
|
|
61
65
|
val answerPendingIntent = PendingIntent.getBroadcast(
|
|
62
66
|
context, uuid.hashCode() + 2, answerIntent, pendingFlags
|
|
@@ -74,33 +78,24 @@ object NativeCallManager {
|
|
|
74
78
|
notificationManager.createNotificationChannel(channel)
|
|
75
79
|
}
|
|
76
80
|
|
|
77
|
-
val caller = Person.Builder()
|
|
78
|
-
.setName(name)
|
|
79
|
-
.setImportant(true)
|
|
80
|
-
.setIcon(context.applicationInfo.icon)
|
|
81
|
-
.build()
|
|
82
|
-
|
|
83
81
|
val builder = NotificationCompat.Builder(context, CALL_CHANNEL_ID)
|
|
84
|
-
//.setSmallIcon(context.applicationInfo.icon)
|
|
85
82
|
.setContentTitle("Incoming $callType call")
|
|
86
83
|
.setContentText(name)
|
|
87
84
|
.setPriority(NotificationCompat.PRIORITY_MAX)
|
|
88
85
|
.setCategory(NotificationCompat.CATEGORY_CALL)
|
|
89
86
|
.setOngoing(true)
|
|
90
87
|
.setAutoCancel(false)
|
|
91
|
-
.setFullScreenIntent(fullScreenPendingIntent, true)
|
|
88
|
+
.setFullScreenIntent(fullScreenPendingIntent, true) // Essential for waking screen
|
|
92
89
|
.setColor(Color.parseColor("#28a745"))
|
|
93
90
|
.setColorized(true)
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
)
|
|
100
|
-
)
|
|
101
|
-
|
|
91
|
+
// ADDING ACTIONS MANUALLY TO CONTROL ORDER
|
|
92
|
+
// First Action added = Leftmost button
|
|
93
|
+
.addAction(0, "Answer", answerPendingIntent)
|
|
94
|
+
.addAction(0, "Decline", rejectPendingIntent)
|
|
95
|
+
|
|
102
96
|
notificationManager.notify(uuid.hashCode(), builder.build())
|
|
103
97
|
|
|
98
|
+
// Start Ringtone
|
|
104
99
|
try {
|
|
105
100
|
val ringtoneUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_RINGTONE)
|
|
106
101
|
ringtone = RingtoneManager.getRingtone(context, ringtoneUri)
|
|
@@ -111,14 +106,9 @@ object NativeCallManager {
|
|
|
111
106
|
|
|
112
107
|
fun stopRingtone() {
|
|
113
108
|
try {
|
|
114
|
-
ringtone?.let {
|
|
115
|
-
if (it.isPlaying) it.stop()
|
|
116
|
-
}
|
|
117
|
-
ringtone = null
|
|
118
|
-
} catch (e: Exception) {
|
|
119
|
-
e.printStackTrace()
|
|
109
|
+
ringtone?.let { if (it.isPlaying) it.stop() }
|
|
120
110
|
ringtone = null
|
|
121
|
-
}
|
|
111
|
+
} catch (e: Exception) { e.printStackTrace() }
|
|
122
112
|
}
|
|
123
113
|
|
|
124
114
|
fun dismissIncomingCall(context: Context, uuid: String?) {
|
package/package.json
CHANGED