通过使用通知操作停止服务

时间:2019-03-26 15:13:29

标签: android kotlin service

我正在尝试构建一个简单的应用程序。此应用程序启动后将立即启动服务,该服务将执行较长的操作(在本示例中,我仅使用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)

0 个答案:

没有答案