You might want to use a mix of a BroadcastReceiver
, a Service
, and a WindowManager
with the suitable flags. Here’s a step-by-step information:
- Create a BroadcastReceiver to pay attention for the incoming name occasion:
class CallReceiver : BroadcastReceiver() {
override enjoyable onReceive(context: Context, intent: Intent) {
val serviceIntent = Intent(context, CallService::class.java)
context.startService(serviceIntent)
}
}
- Create a Service to deal with the show of the full-screen view:
class CallService : Service() {
personal lateinit var windowManager: WindowManager
personal lateinit var callView: View
override enjoyable onBind(intent: Intent?): IBinder? {
return null
}
override enjoyable onCreate() {
tremendous.onCreate()
windowManager = getSystemService(WINDOW_SERVICE) as WindowManager
callView = LayoutInflater.from(this).inflate(R.structure.call_layout, null)
val params = WindowManager.LayoutParams(
WindowManager.LayoutParams.MATCH_PARENT,
WindowManager.LayoutParams.MATCH_PARENT,
WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY,
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE or
WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON or
WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED or
WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON,
PixelFormat.TRANSLUCENT
)
windowManager.addView(callView, params)
}
override enjoyable onDestroy() {
tremendous.onDestroy()
if (::callView.isInitialized) {
windowManager.removeView(callView)
}
}
}
- Declare the Service and BroadcastReceiver in your
AndroidManifest.xml
:
- Request the required permissions in your
AndroidManifest.xml
:
- Set off the BroadcastReceiver when an incoming name is detected:
val intent = Intent("com.instance.INCOMING_CALL")
sendBroadcast(intent)
For iOS, you need to use CallKit
to attain related performance. Here’s a primary instance:
- Create a brand new
CXProvider
and configure it:
import CallKit
class CallManager {
personal let supplier: CXProvider
init() {
let providerConfiguration = CXProviderConfiguration(localizedName: "YourApp")
providerConfiguration.supportsVideo = true
providerConfiguration.maximumCallsPerCallGroup = 1
providerConfiguration.supportedHandleTypes = [.phoneNumber]
supplier = CXProvider(configuration: providerConfiguration)
supplier.setDelegate(self, queue: nil)
}
func reportIncomingCall(uuid: UUID, deal with: String) {
let replace = CXCallUpdate()
replace.remoteHandle = CXHandle(kind: .phoneNumber, worth: deal with)
replace.hasVideo = true
supplier.reportNewIncomingCall(with: uuid, replace: replace) { error in
if let error = error {
print("Error reporting incoming name: (error.localizedDescription)")
}
}
}
}
extension CallManager: CXProviderDelegate {
func providerDidReset(_ supplier: CXProvider) {
// Deal with supplier reset
}
func supplier(_ supplier: CXProvider, carry out motion: CXAnswerCallAction) {
// Deal with name reply
motion.fulfill()
}
func supplier(_ supplier: CXProvider, carry out motion: CXEndCallAction) {
// Deal with name finish
motion.fulfill()
}
}
- Use the
CallManager
to report an incoming name:
let callManager = CallManager()
let uuid = UUID()
callManager.reportIncomingCall(uuid: uuid, deal with: "1234567890")
This setup will mean you can show a customized full-screen UI for incoming calls on each Android and iOS, even when the display screen is locked.