@qusaieilouti99/call-manager 0.1.76 → 0.1.77

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.
@@ -28,18 +28,27 @@ class CallActivity : Activity() {
28
28
  private val timeoutRunnable = Runnable {
29
29
  Log.d(TAG, "CallActivity timeout triggered for callId: $callId")
30
30
  finishReason = FinishReason.TIMEOUT
31
+ CallEngine.stopRingtone()
32
+ CallEngine.cancelIncomingCallUI()
31
33
  CallEngine.endCall(callId)
32
34
  finishCallActivity()
33
35
  }
34
36
 
35
- // NEW: Broadcast receiver to listen for close events
36
37
  private val closeReceiver = object : BroadcastReceiver() {
37
38
  override fun onReceive(context: Context?, intent: Intent?) {
38
39
  val receivedCallId = intent?.getStringExtra("callId")
39
- if (receivedCallId == callId) {
40
+ Log.d(TAG, "Broadcast received for callId: $receivedCallId, current callId: $callId")
41
+
42
+ if (receivedCallId == callId || receivedCallId.isNullOrEmpty()) {
40
43
  Log.d(TAG, "Received close broadcast for $callId")
41
44
  finishReason = FinishReason.EXTERNAL_END
42
- finishCallActivity()
45
+
46
+ // Ensure we're on main thread and activity isn't finishing
47
+ runOnUiThread {
48
+ if (!isFinishing) {
49
+ finishCallActivity()
50
+ }
51
+ }
43
52
  }
44
53
  }
45
54
  }
@@ -67,8 +76,8 @@ class CallActivity : Activity() {
67
76
  callType = intent.getStringExtra("callType") ?: "Audio"
68
77
  Log.d(TAG, "CallActivity received callId: $callId, callType: $callType")
69
78
 
70
- // FIXED: Immediate cleanup of notifications when CallActivity is shown
71
- CallEngine.cancelIncomingCallUI()
79
+ // FIXED: Don't immediately cancel ringtone and notification - let them play
80
+ // CallEngine.cancelIncomingCallUI() // REMOVED
72
81
 
73
82
  val callerName = intent.getStringExtra("callerName") ?: "Unknown"
74
83
  val nameView = findViewById<TextView>(R.id.caller_name)
@@ -80,6 +89,9 @@ class CallActivity : Activity() {
80
89
  answerBtn.setOnClickListener {
81
90
  Log.d(TAG, "CallActivity: Answer button clicked for callId: $callId")
82
91
  finishReason = FinishReason.ANSWER
92
+ // Stop ringtone and notification when user answers
93
+ CallEngine.stopRingtone()
94
+ CallEngine.cancelIncomingCallUI()
83
95
  CallEngine.answerCall(callId)
84
96
  finishCallActivity()
85
97
  }
@@ -87,54 +99,71 @@ class CallActivity : Activity() {
87
99
  declineBtn.setOnClickListener {
88
100
  Log.d(TAG, "CallActivity: Decline button clicked for callId: $callId")
89
101
  finishReason = FinishReason.DECLINE
102
+ // Stop ringtone and notification when user declines
103
+ CallEngine.stopRingtone()
104
+ CallEngine.cancelIncomingCallUI()
90
105
  CallEngine.endCall(callId)
91
106
  finishCallActivity()
92
107
  }
93
108
 
94
- // NEW: Register broadcast receiver
95
- val filter = IntentFilter("com.qusaieilouti99.callmanager.CLOSE_CALL_ACTIVITY")
96
- try {
97
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
98
- registerReceiver(closeReceiver, filter, Context.RECEIVER_NOT_EXPORTED)
99
- Log.d(TAG, "Broadcast receiver registered successfully (API 33+)")
100
- } else {
101
- registerReceiver(closeReceiver, filter)
102
- Log.d(TAG, "Broadcast receiver registered successfully (API < 33)")
103
- }
104
- } catch (e: Exception) {
105
- Log.e(TAG, "Failed to register broadcast receiver: ${e.message}", e)
106
- }
107
-
108
- timeoutHandler.postDelayed(timeoutRunnable, 60_000)
109
- Log.d(TAG, "CallActivity onCreate - END")
109
+ // Enhanced broadcast receiver registration
110
+ val filter = IntentFilter("com.qusaieilouti99.callmanager.CLOSE_CALL_ACTIVITY")
111
+ try {
112
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
113
+ registerReceiver(closeReceiver, filter, Context.RECEIVER_NOT_EXPORTED)
114
+ } else {
115
+ registerReceiver(closeReceiver, filter)
116
+ }
117
+ Log.d(TAG, "Broadcast receiver registered successfully for callId: $callId")
118
+ } catch (e: Exception) {
119
+ Log.e(TAG, "Failed to register broadcast receiver: ${e.message}", e)
120
+ }
121
+
122
+ // Set timeout for incoming call
123
+ timeoutHandler.postDelayed(timeoutRunnable, 60_000)
124
+ Log.d(TAG, "CallActivity onCreate - END")
110
125
  }
111
126
 
112
127
  override fun onDestroy() {
113
128
  super.onDestroy()
114
129
  Log.d(TAG, "CallActivity onDestroy for callId: $callId. Reason: $finishReason")
130
+
131
+ // Clean up timeout handler
115
132
  timeoutHandler.removeCallbacks(timeoutRunnable)
116
133
 
117
- // NEW: Unregister broadcast receiver
134
+ // Unregister broadcast receiver with better error handling
118
135
  try {
119
136
  unregisterReceiver(closeReceiver)
137
+ Log.d(TAG, "Broadcast receiver unregistered for callId: $callId")
138
+ } catch (e: IllegalArgumentException) {
139
+ Log.w(TAG, "Receiver was not registered: ${e.message}")
120
140
  } catch (e: Exception) {
121
- Log.w(TAG, "Receiver already unregistered: ${e.message}")
141
+ Log.e(TAG, "Error unregistering receiver: ${e.message}", e)
122
142
  }
123
143
 
124
- // FIXED: Ensure cleanup happens regardless of how activity ends
125
- CallEngine.stopRingtone()
126
- CallEngine.cancelIncomingCallUI()
144
+ // Clean up ringtone and notification if call wasn't answered
145
+ if (finishReason != FinishReason.ANSWER) {
146
+ CallEngine.stopRingtone()
147
+ CallEngine.cancelIncomingCallUI()
148
+ }
127
149
  }
128
150
 
129
151
  override fun onBackPressed() {
130
152
  Log.d(TAG, "CallActivity onBackPressed for callId: $callId. Treating as decline/dismiss.")
131
153
  finishReason = FinishReason.MANUAL_DISMISS
154
+ CallEngine.stopRingtone()
155
+ CallEngine.cancelIncomingCallUI()
132
156
  CallEngine.endCall(callId)
133
157
  finishCallActivity()
134
158
  }
135
159
 
136
160
  private fun finishCallActivity() {
137
- Log.d(TAG, "Finishing CallActivity.")
161
+ if (isFinishing) {
162
+ Log.d(TAG, "Activity is already finishing, skipping finishCallActivity")
163
+ return
164
+ }
165
+
166
+ Log.d(TAG, "Finishing CallActivity for callId: $callId")
138
167
  if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
139
168
  finishAndRemoveTask()
140
169
  } else {
@@ -602,13 +602,35 @@ object CallEngine {
602
602
  currentCallId = activeCalls.filter { it.value.state != CallState.ENDED }.keys.firstOrNull()
603
603
  }
604
604
 
605
- // NEW: Send broadcast to close CallActivity
605
+ // ENHANCED: Multiple broadcast attempts with delays for better reliability
606
606
  val context = requireContext()
607
607
  val closeActivityIntent = Intent("com.qusaieilouti99.callmanager.CLOSE_CALL_ACTIVITY")
608
608
  closeActivityIntent.putExtra("callId", callId)
609
+
609
610
  try {
611
+ // Send immediate broadcast
610
612
  context.sendBroadcast(closeActivityIntent)
611
613
  Log.d(TAG, "Sent close broadcast for CallActivity: $callId")
614
+
615
+ // Send additional broadcasts with delays to handle timing issues
616
+ Handler(Looper.getMainLooper()).postDelayed({
617
+ try {
618
+ context.sendBroadcast(closeActivityIntent)
619
+ Log.d(TAG, "Sent delayed close broadcast (100ms) for CallActivity: $callId")
620
+ } catch (e: Exception) {
621
+ Log.w(TAG, "Failed to send delayed close broadcast (100ms): ${e.message}")
622
+ }
623
+ }, 100L)
624
+
625
+ Handler(Looper.getMainLooper()).postDelayed({
626
+ try {
627
+ context.sendBroadcast(closeActivityIntent)
628
+ Log.d(TAG, "Sent delayed close broadcast (500ms) for CallActivity: $callId")
629
+ } catch (e: Exception) {
630
+ Log.w(TAG, "Failed to send delayed close broadcast (500ms): ${e.message}")
631
+ }
632
+ }, 500L)
633
+
612
634
  } catch (e: Exception) {
613
635
  Log.w(TAG, "Failed to send close broadcast: ${e.message}")
614
636
  }
@@ -1091,7 +1113,7 @@ object CallEngine {
1091
1113
  )
1092
1114
  }
1093
1115
 
1094
- // --- Media Management ---
1116
+ // --- Media Management (SIMPLIFIED - NO AUDIO FOCUS) ---
1095
1117
  private fun playRingtone() {
1096
1118
  val context = requireContext()
1097
1119
  Log.d(TAG, "playRingtone() called")
@@ -1103,7 +1125,7 @@ object CallEngine {
1103
1125
  ringtone = RingtoneManager.getRingtone(context, uri)
1104
1126
  if (ringtone != null) {
1105
1127
  ringtone?.play()
1106
- Log.d(TAG, "Ringtone started playing successfully")
1128
+ Log.d(TAG, "Ringtone started playing successfully (system handles audio focus)")
1107
1129
  } else {
1108
1130
  Log.w(TAG, "Ringtone is null, cannot play")
1109
1131
  }
@@ -1115,6 +1137,7 @@ object CallEngine {
1115
1137
  fun stopRingtone() {
1116
1138
  try {
1117
1139
  ringtone?.stop()
1140
+ Log.d(TAG, "Ringtone stopped")
1118
1141
  } catch (e: Exception) {
1119
1142
  Log.e(TAG, "Error stopping ringtone: ${e.message}")
1120
1143
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@qusaieilouti99/call-manager",
3
- "version": "0.1.76",
3
+ "version": "0.1.77",
4
4
  "description": "Call manager",
5
5
  "main": "./lib/module/index.js",
6
6
  "types": "./lib/typescript/src/index.d.ts",