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









