@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
|
-
|
|
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
|
-
|
|
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:
|
|
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
|
-
//
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
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
|
-
//
|
|
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.
|
|
141
|
+
Log.e(TAG, "Error unregistering receiver: ${e.message}", e)
|
|
122
142
|
}
|
|
123
143
|
|
|
124
|
-
//
|
|
125
|
-
|
|
126
|
-
|
|
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
|
-
|
|
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
|
-
//
|
|
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
|
}
|