Pro Android with Kotlin
Download 5.42 Mb. Pdf ko'rish
|
@de android telegram Pro Android with Kotlin Developing Modern Mobile
33
CHAPTER 4: Services The second case is given if the service we want to start is part of another app and thus is an external service. You then have to add an intent filter inside the service declaration. Here’s an example: android:enabled="true" android:exported="true"> In this example, is the name of app’s package, and instead of START_SERVICE, you can write a different identifier if you like. Now, inside the service client, you can write the following to start and stop the external service, where inside the intent constructor you have to write the same string as in the intent filter declaration of the service: val intent = Intent(" .START_SERVICE") intent.setPackage(" ") startService(intent) // ... do something ... stopService(intent) The setPackage() statement is important here (of course you have to substitute the service’s package name); otherwise, a security restriction applies, and you get an error message. Binding to Services Starting a service is one part of the story. The other part is using them while they are running. This is what the binding of services is used for. To create a service that can be bound to or from the same app, write something like this: /** * Class used for binding locally, i.e. in the same App. */ class MyBinder(val servc:MyService) : Binder() { fun getService():MyService { return servc } } Note Since intents allow general-purpose extra attributes by using one of the various putExtra() methods, we can also pass data to the service. 34 CHAPTER 4: Services class MyService : Service() { // Binder given to clients private val binder: IBinder = MyBinder(this) // Random number generator private val generator: Random = Random() override fun onBind(intent: Intent):IBinder { return binder } /** method for clients */ fun getRandomNumber():Int { return generator.nextInt(100) } } To bind to this service internally, from the same app, inside the service using the client, write the following: val servcConn = object : ServiceConnection { override fun onServiceDisconnected(compName: ComponentName?) { Log.e("LOG","onServiceDisconnected: " + compName) } override fun onServiceConnected(compName: ComponentName?, binder: IBinder?) { Log.e("LOG","onServiceConnected: " + compName) val servc = (binder as MyBinder).getService() Log.i("LOG", "Next random number from service: " + servc.getRandomNumber()) } override fun onBindingDied(compName:ComponentName) { Log.e("LOG","onBindingDied: " + compName) } } val intent = Intent(this, MyService::class.java) val flags = BIND_AUTO_CREATE bindService(intent, servcConn, flags) Here, the object: ServiceConnection {...} construct is the Kotlin way of implementing an interface by creating an object of an anonymous inner class, like new ServiceConnection() {...} in Java. The construct is called an object expression in Kotlin. The this inside the intent constructor in this case refers to a Context object. You can use it like this inside an activity. If you have the Context in a variable instead, use that variable’s name here. Of course, instead of the logging, you should do more meaningful things. Especially inside the onSeviceConnected() method you can save the binder or service in a variable for further use. Just make sure, having said all that, that you appropriately react to a died binding or a killed service connection. You could, for example, try to bind the service again, tell the user, or both. |
Ma'lumotlar bazasi mualliflik huquqi bilan himoyalangan ©fayllar.org 2024
ma'muriyatiga murojaat qiling
ma'muriyatiga murojaat qiling