Android Bind Service [communicate with fragment and service ]
https://ift.tt/2TWuAhO
Fragment .kt ___________________________________________________________________________ // messenger for communicating with service private var mService: Messenger? = null // flag to check service bouded or not private var mIsBound = false // messenger for communicating with activity private var mMessenger: Messenger? = null override fun onStart() {     super.onStart()     LogUtils.e(CommonTAG, "FN--> onStart() --> ")     if (!mRegisterMessenger) doBindService() } /*service start and bound with fragment */ private fun doBindService() {     LogUtils.e(CommonTAG, "FN--> doBindService() --> ")     //Create Intent of service     val intent = Intent(activity, CallServices::class.java).apply {       replaceExtras(arguments)     }     //Start Service if it's not already started     if (!isMyServiceRunning(context!!, CallServices::class.java)) {       activity?.startService(intent)     }     //Bind the Service     if (!mIsBound) {       activity?.bindService(intent, mConnection, Context.BIND_AUTO_CREATE)       mIsBound = true     } } /*service unbounded fun to fragment*/ private fun doUnbindService(isStop: Boolean = false) {     if (mIsBound) {       if (mService != null) {         try {           LogUtils.e(CommonTAG, "CN->CallsFragment FN--> doUnbindService() --> MSG_UNREGISTER_CLIENT mMessenger")           val msg: Message = Message.obtain(null, SERVICE_UNREGISTER_UNBIND)           msg.replyTo = mMessenger           mService!!.send(msg)           mRegisterMessenger = false         } catch (e: RemoteException) {           LogUtils.e(CommonTAG, "CN->CallsFragment FN--> doUnbindService() --> There is nothing special we need to do if the service has crashed")           e.printStackTrace()         }       }       activity?.unbindService(mConnection)       mIsBound = false     }     if (isStop) {       val intent = Intent(activity, CallServices::class.java)       activity?.stopService(intent)     } } /*service connection listner */ private val mConnection: ServiceConnection = object : ServiceConnection {     override fun onServiceConnected(className: ComponentName, service: IBinder) {       /**        * This is called when the connection with the service has been established, giving us the service object we can use to        * interact with the service. We are communicating with our service through an IDL interface, so get a client-side        * representation of that from the raw service object.        */       LogUtils.e(CommonTAG, "CN->CallsFragment FN--> onServiceConnected() --> ")       mService = Messenger(service)       try {         val msg: Message = Message.obtain(null, SERVICE_REGISTER_BIND)         msg.replyTo = mMessenger         msg.obj = createBundleForService()         mService!!.send(msg)         mRegisterMessenger = true       } catch (e: RemoteException) {         LogUtils.e(CommonTAG, "CN->CallsFragment FN--> onServiceConnected() --> Error ${e.printStackTrace()}")         e.printStackTrace()       }     }     override fun onServiceDisconnected(className: ComponentName) {       mService = null       LogUtils.e(CommonTAG, "CN->CallsFragment FN--> onServiceDisconnected() --> Service Disconnected")     } } /*get service request here*/ class IncomingHandler(var callsFragment: CallsFragment) : Handler() { override fun handleMessage(msg: Message) { LogUtils.e(CommonTAG, "FN--> handleMessage() --> msg.what ${msg.what}") when (msg.what) { } } } ___________________________________________________________________________ class CallServices.kt ___________________________________________________________________________ var mMessenger: Messenger? = null override fun onBind(p0: Intent?): IBinder? {     LogUtils.e(CommonTAG, "onBind() --> ")     val mMessenger = Messenger(IncomingHandler(this))     return mMessenger.binder } /*get fragment request here*/ internal class IncomingHandler : Handler() {   override fun handleMessage(msg: Message) {     when (msg.what) { SERVICE_REGISTER_BIND -> { logMessage("SERVICE_REGISTER_BIND")         callServices.mMessenger = msg.replyTo         getDataFromActivity(msg)         } SERVICE_UNREGISTER_UNBIND -> { logMessage("SERVICE_UNREGISTER_UNBIND") callServices.mMessenger = null }       else -> super.handleMessage(msg)     }   } } private fun getDataFromActivity(msg: Message) {       val mBundle = msg.obj as Bundle       callServices.usageType = mBundle.getSerializable(BUNDLE_KEY_USAGE_TYPE) as VoiceVideoUsageType       callServices.showedName = mBundle.getString(BUNDLE_KEY_CALL_PERSON_NAME)       callServices.showedAvatar = mBundle.getString(BUNDLE_KEY_CALL_PERSON_AVATAR)       callServices.roomName = mBundle.getString(BUNDLE_KEY_CALL_ROOM_NAME)       callServices.participantId = mBundle.getString(BUNDLE_KEY_CALL_PERSON_ID)       currentCallID = mBundle.getString(BUNDLE_KEY_CALL_ID) } companion object { /**      * Command to the service to register a client, receiving callbacks      * from the service. The Message's replyTo field must be a Messenger of      * the client where callbacks should be sent.      */     const val SERVICE_REGISTER_BIND = 1     /**      * Command to the service to unregister a client, ot stop receiving callbacks      * from the service. The Message's replyTo field must be a Messenger of      * the client as previously given with MSG_REGISTER_CLIENT.      */     const val SERVICE_UNREGISTER_UNBIND = 2 /*start service*/ fun startService(context: Context, intent: Intent) {       try {         if (!isMyServiceRunning(context, CallServices::class.java)) {           context.startService(intent)         }       } catch (e: IllegalStateException) {         LogUtils.e(logTag, "Cannot start background service: " + e.message, e)         if (hasOreo()) {           // INFO: 2019-12-18   for Oreo           context.startForegroundService(intent)         } else {           throw IllegalStateException("Starting CallServices when app in background with OS < 26")         }       }     } // check the service are running or not fun isMyServiceRunning(context: Context?, serviceClass: Class<*>): Boolean { val manager = context!!.getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager? for (service in manager!!.getRunningServices(Int.MAX_VALUE)) { if (serviceClass.name == service.service.className) { return true } } return false } } ___________________________________________________________________________ Start service ___________________________________________________________________________ startService(context, notificationIntent.apply { setClass(context, CallServices::class.java) }) ___________________________________________________________________________
via Blogger https://ift.tt/2RRnQ1J














