@qusaieilouti99/call-manager 0.1.75 → 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,47 +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
|
-
//
|
|
109
|
+
// Enhanced broadcast receiver registration
|
|
95
110
|
val filter = IntentFilter("com.qusaieilouti99.callmanager.CLOSE_CALL_ACTIVITY")
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
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)
|
|
100
120
|
}
|
|
101
121
|
|
|
122
|
+
// Set timeout for incoming call
|
|
102
123
|
timeoutHandler.postDelayed(timeoutRunnable, 60_000)
|
|
124
|
+
Log.d(TAG, "CallActivity onCreate - END")
|
|
103
125
|
}
|
|
104
126
|
|
|
105
127
|
override fun onDestroy() {
|
|
106
128
|
super.onDestroy()
|
|
107
129
|
Log.d(TAG, "CallActivity onDestroy for callId: $callId. Reason: $finishReason")
|
|
130
|
+
|
|
131
|
+
// Clean up timeout handler
|
|
108
132
|
timeoutHandler.removeCallbacks(timeoutRunnable)
|
|
109
133
|
|
|
110
|
-
//
|
|
134
|
+
// Unregister broadcast receiver with better error handling
|
|
111
135
|
try {
|
|
112
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}")
|
|
113
140
|
} catch (e: Exception) {
|
|
114
|
-
Log.
|
|
141
|
+
Log.e(TAG, "Error unregistering receiver: ${e.message}", e)
|
|
115
142
|
}
|
|
116
143
|
|
|
117
|
-
//
|
|
118
|
-
|
|
119
|
-
|
|
144
|
+
// Clean up ringtone and notification if call wasn't answered
|
|
145
|
+
if (finishReason != FinishReason.ANSWER) {
|
|
146
|
+
CallEngine.stopRingtone()
|
|
147
|
+
CallEngine.cancelIncomingCallUI()
|
|
148
|
+
}
|
|
120
149
|
}
|
|
121
150
|
|
|
122
151
|
override fun onBackPressed() {
|
|
123
152
|
Log.d(TAG, "CallActivity onBackPressed for callId: $callId. Treating as decline/dismiss.")
|
|
124
153
|
finishReason = FinishReason.MANUAL_DISMISS
|
|
154
|
+
CallEngine.stopRingtone()
|
|
155
|
+
CallEngine.cancelIncomingCallUI()
|
|
125
156
|
CallEngine.endCall(callId)
|
|
126
157
|
finishCallActivity()
|
|
127
158
|
}
|
|
128
159
|
|
|
129
160
|
private fun finishCallActivity() {
|
|
130
|
-
|
|
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")
|
|
131
167
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
|
132
168
|
finishAndRemoveTask()
|
|
133
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,25 +1113,31 @@ 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
|
-
|
|
1098
|
-
return // System handles it
|
|
1099
|
-
}
|
|
1119
|
+
Log.d(TAG, "playRingtone() called")
|
|
1100
1120
|
|
|
1101
1121
|
try {
|
|
1102
1122
|
val uri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_RINGTONE)
|
|
1123
|
+
Log.d(TAG, "Ringtone URI: $uri")
|
|
1124
|
+
|
|
1103
1125
|
ringtone = RingtoneManager.getRingtone(context, uri)
|
|
1104
|
-
ringtone
|
|
1126
|
+
if (ringtone != null) {
|
|
1127
|
+
ringtone?.play()
|
|
1128
|
+
Log.d(TAG, "Ringtone started playing successfully (system handles audio focus)")
|
|
1129
|
+
} else {
|
|
1130
|
+
Log.w(TAG, "Ringtone is null, cannot play")
|
|
1131
|
+
}
|
|
1105
1132
|
} catch (e: Exception) {
|
|
1106
|
-
Log.e(TAG, "Failed to play ringtone: ${e.message}")
|
|
1133
|
+
Log.e(TAG, "Failed to play ringtone: ${e.message}", e)
|
|
1107
1134
|
}
|
|
1108
1135
|
}
|
|
1109
1136
|
|
|
1110
1137
|
fun stopRingtone() {
|
|
1111
1138
|
try {
|
|
1112
1139
|
ringtone?.stop()
|
|
1140
|
+
Log.d(TAG, "Ringtone stopped")
|
|
1113
1141
|
} catch (e: Exception) {
|
|
1114
1142
|
Log.e(TAG, "Error stopping ringtone: ${e.message}")
|
|
1115
1143
|
}
|