Pro Android with Kotlin


Download 5.42 Mb.
Pdf ko'rish
bet43/223
Sana04.11.2023
Hajmi5.42 Mb.
#1746807
1   ...   39   40   41   42   43   44   45   46   ...   223
Bog'liq
@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:name=".MyService"
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.



Download 5.42 Mb.

Do'stlaringiz bilan baham:
1   ...   39   40   41   42   43   44   45   46   ...   223




Ma'lumotlar bazasi mualliflik huquqi bilan himoyalangan ©fayllar.org 2024
ma'muriyatiga murojaat qiling