I am displaying one overlay view using Window Manager on incoming or outgoing call. When I receive one call my overlay window appears on screen but when I receive another call overlay window appears again on the previous displayng window and so on.
I am expecting to remove previously displaying overlay view when I receive call again and only display one overlay view at a time. Here is my WindowManager class.
class WindowManagerForNumber(private val context: Context) {
private var mView: View? = null
private var mParams: WindowManager.LayoutParams? = null
private var mWindowManager: WindowManager? = null
private var layoutInflater: LayoutInflater? = null
private var bool: Boolean = false
private var isWindowOpen = false
private var callerNumber: String? = null
private var callerName: String? = null
private var dialogCallerSearchBinding: DialogCallerSearchBinding? = null
private val scope = CoroutineScope(Job())
init {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
mParams = WindowManager.LayoutParams(
WRAP_CONTENT,
WRAP_CONTENT,
TYPE_APPLICATION_OVERLAY,
FLAG_NOT_FOCUSABLE or FLAG_SHOW_WHEN_LOCKED,
PixelFormat.TRANSLUCENT
)
}
layoutInflater = context.getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater
layoutInflater?.let {
dialogCallerSearchBinding =
DialogCallerSearchBinding.inflate(it, null, false)
mView = dialogCallerSearchBinding?.root
// mView?.isFocusableInTouchMode = true
// mView?.requestFocus()
/*mView?.setOnKeyListener { v,keyCode,event ->
if(keyCode == KeyEvent.KEYCODE_BACK){
close()
return@setOnKeyListener true
}
return@setOnKeyListener false
}*/
dialogCallerSearchBinding?.apply {
tvCallingName.text = callerName
tvCallingNumber.text = callerNumber
ivClose.onClickListener {
close()
}
}
mParams?.gravity = Gravity.CENTER
mWindowManager = context.getSystemService(WINDOW_SERVICE) as WindowManager
}
}
fun setData(
name: String,
number: String?,
appRepository: ApplicationRepository,
isDataSet: (Boolean) -> Unit
) {
scope.launch(Dispatchers.Main) {
dialogCallerSearchBinding?.apply {
number?.let {
when (val data = appRepository.fetchContactData(it)) {
is ResultOfResponse.ResponseEmpty -> {
progressBar.isVisible = false
contactDetail.isVisible = true
tvCallingName.text =
context.resources.getString(R.string.no_name_found)
tvCountryName.isVisible = false
tvCallingNumber.text = number
isDataSet(true)
}
is ResultOfResponse.ResponseError -> {
progressBar.isVisible = false
contactDetail.isVisible = true
tvCallingName.text =
context.resources.getString(R.string.no_name_found)
tvCountryName.isVisible = false
tvCallingNumber.text = number
isDataSet(true)
}
ResultOfResponse.ResponseLoading -> {
}
is ResultOfResponse.ResponseSuccess -> {
progressBar.isVisible = false
contactDetail.isVisible = true
tvCountryName.isVisible = true
tvCallingName.text = data.data.ContactName
tvCallingNumber.text = data.data.ContactUuid
tvCountryName.text = data.data.ContactCountry
dialogCallerSearchBinding?.ivContactImage?.let { it1 ->
appRepository.fetchContactImage(
it,
it1, name
)
}
isDataSet(true)
}
}
}
/*if (name.contentEquals(PRIVATE_NUMBER)) {
progressBar.isVisible = false
contactDetail.isVisible = true
tvCallingName.text = PRIVATE_NUMBER
tvCountryName.visibility = View.INVISIBLE
tvCallingNumber.text = number
isDataSet(true)
} else {
}*/
}
}
// hideView()
}
fun open() {
try {
if (mView?.windowToken == null) {
if (mView?.parent == null) {
mWindowManager?.addView(mView, mParams)
bool = true
setDialogWindowStatus(true)
}
}
} catch (e: Exception) {
e.printStackTrace()
}
}
fun close() {
if (bool) {
mWindowManager?.removeView(mView)
mView?.invalidate()
bool = false
setDialogWindowStatus(false)
Log.i("check", "isWindowOpenInClose =$isWindowOpen")
dialogCallerSearchBinding?.apply {
tvCallingName.text = null
tvCountryName.text = null
tvCallingNumber.text = null
}
}
}
Now if I receive 5 calls I have to click my imageView 5 times to close all overlay windows. Appreciate your efforts in advance.
You are creating new view everytime you get the events i would suggest you to use the same and just change the data whenever you get new events.
For your answer you view is intialised as null so when inflating new view you can check if your view is already intialised then you can remvove it from windowManageer and then reinitialise it .
instead do this
that way you can remove your previously added view and have new one !