@qusaieilouti99/call-manager 0.1.86 → 0.1.87
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.
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
package com.margelo.nitro.qusaieilouti99.callmanager
|
|
3
3
|
|
|
4
4
|
import android.app.Activity
|
|
5
|
+
import android.app.KeyguardManager
|
|
6
|
+
import android.content.Context
|
|
5
7
|
import android.os.Build
|
|
6
8
|
import android.os.Bundle
|
|
7
9
|
import android.os.Handler
|
|
@@ -12,8 +14,7 @@ import android.widget.Button
|
|
|
12
14
|
import android.widget.TextView
|
|
13
15
|
|
|
14
16
|
/**
|
|
15
|
-
*
|
|
16
|
-
* so it always auto‐finishes when the engine ends the call.
|
|
17
|
+
* Enhanced CallActivity with better lock screen bypass for Samsung devices
|
|
17
18
|
*/
|
|
18
19
|
class CallActivity : Activity(), CallEngine.CallEndListener {
|
|
19
20
|
|
|
@@ -39,29 +40,57 @@ class CallActivity : Activity(), CallEngine.CallEndListener {
|
|
|
39
40
|
super.onCreate(savedInstanceState)
|
|
40
41
|
Log.d(TAG, "CallActivity onCreate")
|
|
41
42
|
|
|
42
|
-
//
|
|
43
|
+
// Enhanced lock screen bypass for Samsung devices
|
|
44
|
+
setupLockScreenBypass()
|
|
45
|
+
|
|
46
|
+
setContentView(R.layout.activity_call)
|
|
47
|
+
|
|
48
|
+
// Read incoming call params
|
|
49
|
+
callId = intent.getStringExtra("callId") ?: ""
|
|
50
|
+
callType = intent.getStringExtra("callType") ?: "Audio"
|
|
51
|
+
Log.d(TAG, "CallActivity received callId: $callId, callType: $callType")
|
|
52
|
+
|
|
53
|
+
// Register for call-end callbacks
|
|
54
|
+
CallEngine.registerCallEndListener(this)
|
|
55
|
+
|
|
56
|
+
// Bind UI
|
|
57
|
+
setupUI()
|
|
58
|
+
|
|
59
|
+
// Start auto-timeout
|
|
60
|
+
timeoutHandler.postDelayed(timeoutRunnable, 60_000)
|
|
61
|
+
Log.d(TAG, "CallActivity setup complete")
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
private fun setupLockScreenBypass() {
|
|
65
|
+
// For Android O_MR1 and above
|
|
43
66
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O_MR1) {
|
|
44
67
|
setShowWhenLocked(true)
|
|
45
68
|
setTurnScreenOn(true)
|
|
69
|
+
|
|
70
|
+
// Additional Samsung-specific setup
|
|
71
|
+
val keyguardManager = getSystemService(Context.KEYGUARD_SERVICE) as KeyguardManager
|
|
72
|
+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
|
73
|
+
keyguardManager.requestDismissKeyguard(this, null)
|
|
74
|
+
}
|
|
46
75
|
} else {
|
|
76
|
+
// For older versions
|
|
47
77
|
window.addFlags(
|
|
48
78
|
WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED or
|
|
49
79
|
WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON or
|
|
50
|
-
WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD
|
|
80
|
+
WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD or
|
|
81
|
+
WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON
|
|
51
82
|
)
|
|
52
83
|
}
|
|
53
84
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
// Register for call‐end callbacks BEFORE timeout or user can dismiss
|
|
62
|
-
CallEngine.registerCallEndListener(this)
|
|
85
|
+
// Additional flags for better compatibility
|
|
86
|
+
window.addFlags(
|
|
87
|
+
WindowManager.LayoutParams.FLAG_FULLSCREEN or
|
|
88
|
+
WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN or
|
|
89
|
+
WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS
|
|
90
|
+
)
|
|
91
|
+
}
|
|
63
92
|
|
|
64
|
-
|
|
93
|
+
private fun setupUI() {
|
|
65
94
|
val callerName = intent.getStringExtra("callerName") ?: "Unknown"
|
|
66
95
|
findViewById<TextView>(R.id.caller_name).text = callerName
|
|
67
96
|
|
|
@@ -82,23 +111,15 @@ class CallActivity : Activity(), CallEngine.CallEndListener {
|
|
|
82
111
|
CallEngine.endCall(callId)
|
|
83
112
|
finishCallActivity()
|
|
84
113
|
}
|
|
85
|
-
|
|
86
|
-
// Start auto‐timeout
|
|
87
|
-
timeoutHandler.postDelayed(timeoutRunnable, 60_000)
|
|
88
|
-
Log.d(TAG, "CallActivity setup complete")
|
|
89
114
|
}
|
|
90
115
|
|
|
91
116
|
override fun onDestroy() {
|
|
92
117
|
super.onDestroy()
|
|
93
118
|
Log.d(TAG, "CallActivity onDestroy for callId: $callId. Reason: $finishReason")
|
|
94
119
|
|
|
95
|
-
// Unregister listener
|
|
96
120
|
CallEngine.unregisterCallEndListener(this)
|
|
97
|
-
|
|
98
|
-
// Cancel timeout
|
|
99
121
|
timeoutHandler.removeCallbacks(timeoutRunnable)
|
|
100
122
|
|
|
101
|
-
// If user never answered, clean up ringtone/UI
|
|
102
123
|
if (finishReason != FinishReason.ANSWER) {
|
|
103
124
|
CallEngine.stopRingtone()
|
|
104
125
|
CallEngine.cancelIncomingCallUI()
|
|
@@ -114,10 +135,6 @@ class CallActivity : Activity(), CallEngine.CallEndListener {
|
|
|
114
135
|
finishCallActivity()
|
|
115
136
|
}
|
|
116
137
|
|
|
117
|
-
/**
|
|
118
|
-
* Called by CallEngine whenever ANY call ends.
|
|
119
|
-
* We only care about our own callId.
|
|
120
|
-
*/
|
|
121
138
|
override fun onCallEnded(endedCallId: String) {
|
|
122
139
|
if (endedCallId == callId && !isFinishing) {
|
|
123
140
|
Log.d(TAG, "CallActivity onCallEnded callback for callId: $callId")
|
|
@@ -918,12 +918,34 @@ object CallEngine {
|
|
|
918
918
|
val notificationManager =
|
|
919
919
|
context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
|
|
920
920
|
|
|
921
|
+
// Enhanced full screen intent
|
|
922
|
+
val fullScreenIntent = Intent(context, CallActivity::class.java).apply {
|
|
923
|
+
addFlags(
|
|
924
|
+
Intent.FLAG_ACTIVITY_NEW_TASK or
|
|
925
|
+
Intent.FLAG_ACTIVITY_CLEAR_TASK or
|
|
926
|
+
Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS or
|
|
927
|
+
Intent.FLAG_ACTIVITY_NO_ANIMATION or
|
|
928
|
+
Intent.FLAG_ACTIVITY_SINGLE_TOP
|
|
929
|
+
)
|
|
930
|
+
putExtra("callId", callId)
|
|
931
|
+
putExtra("callerName", callerName)
|
|
932
|
+
putExtra("callType", callType)
|
|
933
|
+
}
|
|
934
|
+
|
|
935
|
+
val fullScreenPendingIntent = PendingIntent.getActivity(
|
|
936
|
+
context,
|
|
937
|
+
callId.hashCode(), // Use unique request code
|
|
938
|
+
fullScreenIntent,
|
|
939
|
+
PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
|
|
940
|
+
)
|
|
941
|
+
|
|
942
|
+
// Answer and decline intents
|
|
921
943
|
val answerIntent = Intent(context, CallNotificationActionReceiver::class.java).apply {
|
|
922
944
|
action = "com.qusaieilouti99.callmanager.ANSWER_CALL"
|
|
923
945
|
putExtra("callId", callId)
|
|
924
946
|
}
|
|
925
947
|
val answerPendingIntent = PendingIntent.getBroadcast(
|
|
926
|
-
context,
|
|
948
|
+
context, callId.hashCode() + 1, answerIntent,
|
|
927
949
|
PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
|
|
928
950
|
)
|
|
929
951
|
|
|
@@ -932,18 +954,7 @@ object CallEngine {
|
|
|
932
954
|
putExtra("callId", callId)
|
|
933
955
|
}
|
|
934
956
|
val declinePendingIntent = PendingIntent.getBroadcast(
|
|
935
|
-
context,
|
|
936
|
-
PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
|
|
937
|
-
)
|
|
938
|
-
|
|
939
|
-
val fullScreenIntent = Intent(context, CallActivity::class.java).apply {
|
|
940
|
-
addFlags(Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_SINGLE_TOP)
|
|
941
|
-
putExtra("callId", callId)
|
|
942
|
-
putExtra("callerName", callerName)
|
|
943
|
-
putExtra("callType", callType)
|
|
944
|
-
}
|
|
945
|
-
val fullScreenPendingIntent = PendingIntent.getActivity(
|
|
946
|
-
context, 2, fullScreenIntent,
|
|
957
|
+
context, callId.hashCode() + 2, declineIntent,
|
|
947
958
|
PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
|
|
948
959
|
)
|
|
949
960
|
|
|
@@ -964,13 +975,15 @@ object CallEngine {
|
|
|
964
975
|
.setFullScreenIntent(fullScreenPendingIntent, true)
|
|
965
976
|
.setOngoing(true)
|
|
966
977
|
.setAutoCancel(false)
|
|
978
|
+
.setCategory(Notification.CATEGORY_CALL)
|
|
979
|
+
.setPriority(Notification.PRIORITY_MAX)
|
|
967
980
|
.build()
|
|
968
981
|
} else {
|
|
969
982
|
Notification.Builder(context, NOTIF_CHANNEL_ID)
|
|
970
983
|
.setSmallIcon(android.R.drawable.sym_call_incoming)
|
|
971
984
|
.setContentTitle("Incoming Call")
|
|
972
985
|
.setContentText(callerName)
|
|
973
|
-
.setPriority(Notification.
|
|
986
|
+
.setPriority(Notification.PRIORITY_MAX)
|
|
974
987
|
.setCategory(Notification.CATEGORY_CALL)
|
|
975
988
|
.setFullScreenIntent(fullScreenPendingIntent, true)
|
|
976
989
|
.addAction(android.R.drawable.sym_action_call, "Answer", answerPendingIntent)
|
|
@@ -981,6 +994,14 @@ object CallEngine {
|
|
|
981
994
|
}
|
|
982
995
|
|
|
983
996
|
notificationManager.notify(NOTIF_ID, notification)
|
|
997
|
+
|
|
998
|
+
// Also try to launch the activity directly as a backup
|
|
999
|
+
try {
|
|
1000
|
+
context.startActivity(fullScreenIntent)
|
|
1001
|
+
} catch (e: Exception) {
|
|
1002
|
+
Log.w(TAG, "Could not start activity directly: ${e.message}")
|
|
1003
|
+
}
|
|
1004
|
+
|
|
984
1005
|
playRingtone()
|
|
985
1006
|
setInitialAudioRoute(callType)
|
|
986
1007
|
}
|