0

I am using CallScreenService Api to detect call and show window on incoming and outgoing calls, but I want to close my overlay dialog window when calls ends or decline.

Here is my code for CallScreenService.class

class AppService : CallScreeningService() {
    @Inject
    lateinit var applicationRepository: ApplicationRepository

    @Inject
    lateinit var telephonyManager: TelephonyManager
    private val windowManagerForNumber by lazy {
        WindowManagerForNumber(this)
    }
    private var finalPhoneNumb: String? = ""
    private val callerName: String?
        get() = finalPhoneNumb?.let {
            applicationRepository.fetchNameFromPhoneNumber(
                it
            )
        }
    private val notificationManagerImpl = NotificationManagerImpl()

    private val notification by lazy {
       com.example.truecaller.calling_app.utils.notification.Notification(this)
    }

    companion object {
        fun startService(context: Context) {
            Intent(context, TrueCallerAppService::class.java).apply {
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                    startForegroundService(context, this)
                } else {
                    context.startService(this)
                }
            }
        }
    }


    override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
        super.onStartCommand(intent, flags, startId)
        startNotification()
        return START_STICKY
    }

    override fun onScreenCall(p0: Call.Details) {
        val number = getPhoneNumber(p0)
        var callResponse = CallResponse.Builder()
        callResponse = handlePhoneCall(callResponse, number)
        respondToCall(p0, callResponse.build())
    }

    private fun handlePhoneCall(
        response: CallResponse.Builder,
        phoneNumber: String
    ): CallResponse.Builder {
        if (phoneNumber == FORBIDDEN_PHONE_CALL_NUMBER) {
            response.apply {
                setRejectCall(true)
                setDisallowCall(true)
                setSkipCallLog(false)

            }
        } else {
            if (Settings.canDrawOverlays(this)) {
                finalPhoneNumb = phoneNumber
                if (PhoneNumberValidCheck.checkValidPhoneNumber(phoneNumber)) {
                    displayToast(phoneNumber)
                    Log.e("phone", "handlePhoneCall: $phoneNumber")
                }
            }
        }
        return response
    }

private fun startNotification() {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        startForeground(notification.notificationId, notification.createNotification())
    } else {
        startForeground(
            notification.notificationId,
            android.app.Notification()
        )
    }
    isForeGroundService = true
}

private fun displayToast(message: String) {
    try {
        val countryCodeOfNumber = telephonyManager.simCountryIso.toString()
        val phoneNumberUtil = PhoneNumberUtil.getInstance()
        val phoneNumber: Phonenumber.PhoneNumber =
            phoneNumberUtil.parse(message, countryCodeOfNumber.uppercase(Locale.ENGLISH))
        val incomingNumber = phoneNumberUtil.format(phoneNumber, PhoneNumberUtil.PhoneNumberFormat.E164)
        notificationManagerImpl.appRepo(applicationRepository, windowManagerForNumber, incomingNumber)
    } catch (e: Exception) {
        e.printStackTrace()
    }
}

Here is my WindowManagerClass

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 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(
                WindowManager.LayoutParams.WRAP_CONTENT,
                WindowManager.LayoutParams.WRAP_CONTENT,
                WindowManager.LayoutParams.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 {


                }*/

            }

        }


    }

    fun open() {
        try {
            if (mView?.windowToken == null) {
                if (mView?.parent == null) {
                    mWindowManager?.addView(mView, mParams)
                    bool = true
                }
            }
        } catch (e: Exception) {
            e.printStackTrace()
        }
    }

    fun close() {
        if (bool) {
            mWindowManager?.removeView(mView)
            mView?.invalidate()
            bool = false
            dialogCallerSearchBinding?.apply {
                tvCallingName.text = null
                tvCountryName.text = null
                tvCallingNumber.text = null
            }
        }
    }
}

I am using WindowManager for showing overlay dialog window and closing window when user click "x" (cross imageView) but I want to close window when call ends or decline.

Assad khan
  • 161
  • 2
  • 9

0 Answers0