I have a problem with getting WindowManager
inside some service on some phone models.
I have written service that inherits CallScreeningService
, I use it to handle incoming calls and draw views on locked screen. On most devices my service works fine, but I found it doesn't work on some Xiaomi devices (for instance Redmi Note 7, Xiaomi MI MAX 3).
Service has problems with getting WindowManager
:
@RequiresApi(Build.VERSION_CODES.Q)
class MyCallScreeningService : CallScreeningService() {
private var windowManager: WindowManager? = null
override fun onScreenCall(details: Call.Details) {
if (details.callDirection == Call.Details.DIRECTION_INCOMING) {
details.handle?.schemeSpecificPart?.onlyDigits()?.let { phoneNumber ->
if (phoneNumber.isNotEmpty()) {
CoroutineScope(Dispatchers.IO).launch {
requestPhoneInfoFromDb(phoneNumber)?.let { phonebookEntry ->
CoroutineScope(Dispatchers.Main).launch {
showCallInfoView(phoneNumber, phonebookEntry)
respondToCall(details, CallResponse.Builder().build())
}
}
}
}
}
}
}
private fun showCallInfoView(number: String, phonebookEntry: PhonebookEntity) {
windowManager = getSystemService(Service.WINDOW_SERVICE) as WindowManager
//building view...
}
}
Error happens when I call getSystemService(Service.WINDOW_SERVICE) as WindowManager
, on Xiaomi I get an exception:
Tried to access visual service WindowManager from a non-visual Context:MyCallScreeningService@ecb7385 WindowManager should be accessed from Activity or other visual Context. Use an Activity or a Context created with Context#createWindowContext(int, Bundle), which are adjusted to the configuration and visual bounds of an area on screen.
java.lang.IllegalAccessException: Tried to access visual service WindowManager from a non-visual Context:MyCallScreeningService@ecb7385 at android.app.ContextImpl.getSystemService(ContextImpl.java:2125)
at android.content.ContextWrapper.getSystemService(ContextWrapper.java:910)
at MyCallScreeningService.x(MyCallScreeningService.kt:3)
at MyCallScreeningService.h(MyCallScreeningService.kt:1)
at MyCallScreeningService$g.invokeSuspend(MyCallScreeningService.kt:52)
at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:12)
I have tried many ways to use services's Context
here or pass it to the service, but I always got the same exception. Hope someone has any ideas about this problem. I can add more details if it will be needed.