Android 启动service(Kotlin)
一、使用startForegroundService()或startService()启用service
**Activity
//启动service
val intent: Intent = Intent(ServiceActivity@this,MyService::class.java)
//Build.VERSION_CODES.O = 26
// Android8以后,不允许后台启动Service
if(Build.VERSION.SDK_INT >= 26){
startForegroundService(intent)
}else{
startService(intent)
}
**Service
package com.example.buju.service
import android.app.NotificationChannel
import android.app.NotificationManager
import android.app.Service
import android.content.Context
import android.content.Intent
import android.graphics.BitmapFactory
import android.os.Build
import android.os.IBinder
import android.util.Log
import androidx.core.app.NotificationCompat
class MyService:Service() {
override fun onCreate() {
super.onCreate()
Log.e("MyService","onCreate")
initNotification()
}
// 初始化通知(安卓8.0之后必须实现)
private fun initNotification() {
val channelName = "channelName"
val channelId = "channelId"
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.O){
// 发送通知,把service置于前台
val notificationManager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
// 从Android 8.0开始,需要注册通知通道
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
val channel = NotificationChannel(channelId, channelName, NotificationManager.IMPORTANCE_HIGH)
notificationManager.createNotificationChannel(channel)
}
// 页面跳转
val intent = Intent(applicationContext,ServiceActivity::class.java)
val pendingIntent = PendingIntent.getActivity(this, 0, intent,
PendingIntent.FLAG_UPDATE_CURRENT)
// 创建通知并配置相应属性
val notification = NotificationCompat.Builder(this, channelId)
.setSmallIcon(android.R.drawable.star_off)//小图标一定需要设置,否则会报错(如果不设置它启动服务前台化不会报错,但是你会发现这个通知不会启动),如果是普通通知,不设置必然报错
.setLargeIcon(BitmapFactory.decodeResource(getResources(), android.R.drawable.star_on))
.setContentTitle("通知标题")// 标题
.setContentText("通知内容")// 内容
.setPriority(NotificationCompat.PRIORITY_DEFAULT)
.setContentIntent(pendingIntent)// 设置跳转
.setWhen(System.currentTimeMillis())
.setAutoCancel(false)
.setOngoing(true)
.build()
// 注意第一个参数不能为0
startForeground(1, notification)
}
}
override fun onBind(intent: Intent?): IBinder? {
Log.e("MyService","onBind")
return null
}
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
Log.e("MyService","onStartCommand")
return super.onStartCommand(intent, flags, startId)
}
override fun onUnbind(intent: Intent?): Boolean {
Log.e("MyService","onUnbind")
return super.onUnbind(intent)
}
override fun onDestroy() {
super.onDestroy()
Log.e("MyService","onDestroy")
//停止的时候销毁前台服务。
stopForeground(true);
}
}
注意该方法不会调用onBind()和onUnbind()
二、绑定启用service
**Activity
package com.example.buju
import android.content.ComponentName
import android.content.Context
import android.content.Intent
import android.content.ServiceConnection
import android.os.Bundle
import android.os.IBinder
import android.util.Log
import android.view.View
import android.widget.Button
import androidx.appcompat.app.AppCompatActivity
import com.example.buju.service.MyService
class ServiceActivity:AppCompatActivity() {
private var myBinder:MyService.MyBinder? = null
lateinit var startBtn:Button
lateinit var stopBtn:Button
lateinit var getBtn:Button
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_service)
initControls()
}
/**
* 控件初始化
* */
private fun initControls(){
startBtn = findViewById(R.id.startBtn)
startBtn.setOnClickListener(btnClick)
stopBtn = findViewById(R.id.stopBtn)
stopBtn.setOnClickListener(btnClick)
getBtn = findViewById(R.id.getBtn)
getBtn.setOnClickListener(btnClick)
}
/**
* service 连接
* */
private val connection = object:ServiceConnection{
//Activity与Service连接成功时回调该方法
override fun onServiceConnected(name: ComponentName?, service: IBinder?) {
Log.e("MyService","---------Service 成功连接----------")
myBinder = service as MyService.MyBinder
}
// Activity与Service断开连接时回调该方法
override fun onServiceDisconnected(name: ComponentName?) {
Log.e("MyService","---------Service 断开连接----------")
}
}
/**
* 点击事件
* */
val btnClick:(View)->Unit = {
when(it.id) {
R.id.startBtn -> {
// 绑定service
val intent: Intent = Intent(ServiceActivity@this,MyService::class.java)
bindService(intent,connection,Context.BIND_AUTO_CREATE)
}
R.id.stopBtn ->{
// 解除绑定
unbindService(connection)
}
R.id.getBtn ->{
// 获取service传递过来的数据
Log.e("MyService","getCount=${myBinder?.getCount()}")
}
else ->{
}
}
}
override fun finish() {
super.finish()
overridePendingTransition(R.anim.slide_no,R.anim.slide_out_from_bottom)
}
override fun onDestroy() {
super.onDestroy()
// 解除绑定
unbindService(connection)
}
}
**Service
package com.example.buju.service
import android.app.NotificationChannel
import android.app.NotificationManager
import android.app.Service
import android.content.Context
import android.content.Intent
import android.graphics.BitmapFactory
import android.os.Binder
import android.os.Build
import android.os.IBinder
import android.util.Log
import androidx.core.app.NotificationCompat
class MyService:Service() {
/**
* 用于传递参数
* */
private var count:Int = 0
private var myBinder:MyBinder = MyBinder()
inner class MyBinder: Binder(){
fun getCount():Int?{
return count
}
}
override fun onCreate() {
super.onCreate()
Log.e("MyService","onCreate")
Thread(Runnable {
Thread.sleep(1000)
count=100
}).start()
initNotification()
}
// 初始化通知(安卓8.0之后必须实现)
private fun initNotification() {
val channelName = "channelName"
val channelId = "channelId"
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.O){
// 发送通知,把service置于前台
val notificationManager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
// 从Android 8.0开始,需要注册通知通道
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
val channel = NotificationChannel(channelId, channelName, NotificationManager.IMPORTANCE_HIGH)
notificationManager.createNotificationChannel(channel)
}
val notification = NotificationCompat.Builder(this, channelId)
.setSmallIcon(android.R.drawable.star_off)//小图标一定需要设置,否则会报错(如果不设置它启动服务前台化不会报错,但是你会发现这个通知不会启动),如果是普通通知,不设置必然报错
.setLargeIcon(BitmapFactory.decodeResource(getResources(), android.R.drawable.star_on))
.setContentTitle("通知标题")// 标题
.setContentText("通知内容")// 内容
.setWhen(System.currentTimeMillis())
.setAutoCancel(false)
.setOngoing(true)
.build()
// 注意第一个参数不能为0
startForeground(1, notification)
}
}
override fun onBind(intent: Intent?): IBinder? {
Log.e("MyService","onBind")
return myBinder
}
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
Log.e("MyService","onStartCommand")
return super.onStartCommand(intent, flags, startId)
}
override fun onUnbind(intent: Intent?): Boolean {
Log.e("MyService","onUnbind")
return super.onUnbind(intent)
}
override fun onDestroy() {
super.onDestroy()
Log.e("MyService","onDestroy")
//停止的时候销毁前台服务。
stopForeground(true);
}
}