我正在尝试构建一个简单的应用程序。此应用程序启动后将立即启动服务,该服务将执行较长的操作(在本示例中,我仅使用Thread.sleep(1000)
模拟该操作)。
但是,我还需要能够从前台通知(操作)中取消该服务。
我尝试了一些诸如jobserviceintent之类的方法(我认为这不是正确的方法,因为我需要在工作时取消当前线程)。我最终使用了常规服务。
Android清单
<service android:name=".KotlinService"
android:permission="android.permission.BIND_JOB_SERVICE"
android:enabled="true"
android:exported="true"/>
<receiver android:name=".KotlinReceiver">
<intent-filter>
<action android:name="com.example.myapplication.STOP_SERVICE_ACTION" />
</intent-filter>
</receiver>
KotlinService
class KotlinService : Service() {
var isWorking = false
lateinit var receiever : KotlinReceiver
val FOREGROUND_NOTIFICATION = 1
val CHANNEL_ID = "CHANNEL_ID"
companion object {
const val TAG = "KotlinService"
const val ACTION_BACKGROUND = "ACTION_BACKGROUND"
private const val SERVICE_ID : Int = 1000
}
override fun onBind(intent: Intent?): IBinder? {
return null
}
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
var intentFilter = IntentFilter(KotlinReceiver.STOP_SERVICE_ACTION)
receiever = KotlinReceiver()
registerReceiver(receiever,intentFilter)
when(intent!!.action)
{
ACTION_BACKGROUND->
{
startForeground(FOREGROUND_NOTIFICATION,showNotification())
Log.d(TAG,"onHandleWork")
var startTime = System.currentTimeMillis()
isWorking = true
while(isWorking)
{
var currentTime = System.currentTimeMillis()-startTime
Log.d(TAG,"current elapsed $currentTime")
Thread.sleep(1000)
}
}
}
return Service.START_STICKY
}
private fun showNotification(): Notification {
//Build your notification
val mBuilder = NotificationCompat.Builder(this, CHANNEL_ID)
.setSmallIcon(R.drawable.ic_launcher_foreground)
.setContentTitle("Testing service in background")
.setContentText("See actions below")
.setPriority(NotificationCompat.PRIORITY_LOW)
// Create Channel for Android O. DON'T FORGET
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
val notificationManager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
val channel = NotificationChannel(CHANNEL_ID,
"test",
NotificationManager.IMPORTANCE_LOW)
notificationManager.createNotificationChannel(channel)
}
//notification stop action
var stopIntent = Intent()
stopIntent.action = KotlinReceiver.STOP_SERVICE_ACTION
var stopPendingIntent = PendingIntent.getBroadcast(this,1234,stopIntent,PendingIntent.FLAG_UPDATE_CURRENT)
var action : NotificationCompat.Action = NotificationCompat.Action.Builder(0, "Stop",stopPendingIntent).build();
mBuilder.addAction(action)
return mBuilder.build()
}
override fun onDestroy() {
isWorking = false
unregisterReceiver(receiever)
super.onDestroy()
}
}
Kotlin接收器
class KotlinReceiver : BroadcastReceiver() {
companion object {
const val TAG = "KotlinReceiver"
const val STOP_SERVICE_ACTION = "com.example.myapplication.STOP_SERVICE_ACTION"
}
override fun onReceive(context: Context?, intent: Intent?) {
var action = intent!!.action
when(action)
{
STOP_SERVICE_ACTION->
{
Log.d(TAG,"onReceive STOP_SERVICE_ACTION")
var stopIntent = Intent(context!!,KotlinService::class.java)
context!!.stopService(stopIntent)
}
}
}
}
这是我启动服务的方式:
var intent = Intent(this,KotlinService::class.java)
intent.action = KotlinService.ACTION_BACKGROUND
startService(intent)