본문 바로가기
안드로이드/Service

안드로이드 IPC

by 김어찐 2022. 6. 16.
728x90

Activity에서 실행 중인 서비스를 제어하거나 데이터를 사용하는 등의 작업이 필요할 때 사용하는 개념이다.
현재 실행중인 서비스에 접속하고 서비스가 가지고 있는 메서드를 호출 할 수 있는 개념이다.
이 때, 데이터를 반환 받아 사용할 수 있다.

 

package com.example.ipc

import android.app.ActivityManager
import android.content.ComponentName
import android.content.Context
import android.content.Intent
import android.content.ServiceConnection
import android.os.Build
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.os.IBinder
import kotlinx.android.synthetic.main.activity_main.*

class MainActivity : AppCompatActivity() {
    // 접속한 서비스 객체
    var ipcService:TestService? = null

    // 서비스 접속을 관리하는 객체
    val connection = object : ServiceConnection{
        // 서비스가 접속이 성공했을 때
        // 두 번째 : 서비스의 onBind 메서드가 반환하는 객체를 받는다
        override fun onServiceConnected(name: ComponentName?, service: IBinder?) {
            val binder = service as TestService.LocalBiner
            ipcService = binder.getService()
        }

        // 서비스 접속을 해제했을때
        override fun onServiceDisconnected(name: ComponentName?) {
            ipcService = null
            TODO("Not yet implemented")
        }
    }
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        // 서비스가 가동중이 아니라면 서비스를 가동한다
        val chk = isSerivceRunning("com.example.ipc.TestService")

        val serviceIntent = Intent(this,TestService::class.java)

        if (chk == false) {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                startForegroundService((serviceIntent))
            } else {
                startService(serviceIntent)
            }
        }

        // 서비스에 접속한다.
        bindService(serviceIntent,connection,Context.BIND_AUTO_CREATE)

        button.setOnClickListener {
            var value = ipcService?.getNumber()
            textView.text = "value : $value"
        }

    }

    override fun onDestroy() {
        super.onDestroy()

        // 접속한 서비스에 접속을 해제한다.
        unbindService(connection)
    }

    // 비스 실행 여부를 검사하는 메서드
    fun isSerivceRunning(name: String): Boolean {
        val manager = getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager
        // 현재 실행중인 서비스들을 가져온다.
        val serviceList = manager.getRunningServices(Int.MAX_VALUE)

        for (serviceInfo in serviceList) {
            if (serviceInfo.service.className == name) {
                return true
            }
        }
        return false
    }
}

 

 

 

package com.example.ipc

import android.app.NotificationChannel
import android.app.NotificationManager
import android.app.Service
import android.content.Context
import android.content.Intent
import android.graphics.Color
import android.os.Binder
import android.os.Build
import android.os.IBinder
import android.os.SystemClock
import android.util.Log
import androidx.core.app.NotificationCompat
import kotlin.concurrent.thread

class TestService : Service() {

    var value = 0;
    var isRunning = false;
    var binder = LocalBiner()

    //외부에서 서비스에 접속하면 호출되는 메서드
    override fun onBind(intent: Intent): IBinder {
        return binder
    }

    override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {

        // 안드로이드 8.0 이상부터
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            val manager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
            val channel = NotificationChannel("service","service", NotificationManager.IMPORTANCE_HIGH)
            channel.enableLights(true)
            channel.lightColor = Color.RED
            channel.enableVibration(true)
            manager.createNotificationChannel(channel)

            val builder = NotificationCompat.Builder(this,"service")
            builder.setSmallIcon(android.R.drawable.ic_menu_camera)
            builder.setContentTitle("서비스 가동")
            builder.setContentText("서비스가 가동 중입니다")
            val notification = builder.build()

            // 알림 메세지룰 Foreground 서비스를 위해 표시한다
            startForeground(10,notification)

        }

        isRunning = true

        thread {
            while (isRunning) {
                SystemClock.sleep(500)
                Log.d("test","value : $value")
                value++
            }
        }
        return super.onStartCommand(intent, flags, startId)
    }

    override fun onDestroy() {
        super.onDestroy()
        isRunning = false
    }

    fun getNumber() : Int{
        return value
    }

    // 접속하는 Activity에서 서비스를 추출하기 위해 사용하는 객체
    inner class LocalBiner : Binder() {
        fun getService() : TestService{
            return this@TestService
        }
    }
}
728x90

'안드로이드 > Service' 카테고리의 다른 글

안드로이드 Service  (0) 2022.06.16
안드로이드 시스템 메시지  (0) 2022.06.16
안드로이드 Broad Cast Receiver  (0) 2022.06.16