우찬쓰 개발블로그

안드로이드 백그라운드 서비스 만들기 본문

안드로이드/안드로이드 개발

안드로이드 백그라운드 서비스 만들기

이우찬 2019. 4. 1. 18:08
반응형

안드로이드가 오레오, 파이로 넘어가면서 백그라운드 서비스를 다루기가 점점 어려워지고 있다.

 

사실 어려워진다는 얘기도 백그라운드에서 서비스를 돌리면서도 Notification을 띄우지 않는 기술에 대한 꼼수(?)가 어려워 지고 있는거지 Notification이 뜨든 말든 상관없는 초보자들은 더 혼동이 오기 마련이다.

 

그래서 안드로이드 초보자의 기준에서, 안드로이드의 백그라운드 서비스를 공식적인 방법으로 띄우는 방법에 대해 알아보자.

 

여기서 용어를 정의하고 넘어가야 하는데, 앱이 죽든 말든 백그라운드에서 서비스를 죽지않게 하고 싶다면 이것을 포어그라운드 서비스 라고 한다.

 

따라서 이하 포어그라운드 서비스 라고 부르겠다.

 

먼저 서비스를 만들어야 하는데 생각보다 간단하다.

 

서비스를 상속받은 예제 서비스를 만들자

 

class TestService : Service() {

    override fun onCreate() {
        super.onCreate()
        
        // 오레오 부터는 notification channel을 설정해 주어야 함
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            val name = "Test Notification"
            val importance = NotificationManager.IMPORTANCE_DEFAULT
            val notificationChannel = NotificationChannel("YOUR_CHANNEL_ID", name, importance)

            val notificationManager = getSystemService(NOTIFICATION_SERVICE) as NotificationManager
            notificationManager.createNotificationChannel(notificationChannel)
        }
        
        // TODO : 아래 주석 인텐트는 해당 Notification을 눌렀을때 어떤 엑티비티를 띄울 것인지 정의.
        // val notificationIntent = Intent(this, TestActivity::class.java)
        // val pendingIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0)
        val builder = NotificationCompat.Builder(this, "YOUR_CHANNEL_ID")
            .setSmallIcon(R.drawable.test_icon)
            .setContentText("test")
            //.setContentIntent(pendingIntent)
        startForeground(1, builder.build())
    }

    override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
    	// TODO : 서비스 처음 시작시 할 동작 정의.
        return START_REDELIVER_INTENT
    }

    override fun onDestroy() {
	// TODO : 서비스 종료시 할 것들
        super.onDestroy()
    }
}

 

그리고 Activity에서 

 

val intent = Intent(context, TestService::class.java)
startService(intent)

 

를 호출하면 끝이다.

 

생각보다 간단한데, 이렇게 간단한 예제 하나가 정리되어있는게 없다는게 참 아쉽다.

 

 

아마 다들 알겠지만 Google 정책이 바뀌면서 포어그라운드 서비스를 돌리기 위해서는 Notification이 항상 띄워져 있어야 한다.

 

그렇지 않으면 서비스가 돌지 않는다.

 

그리고 서비스를 더이상 돌리고 싶지 않다면

 

val intent = Intent(context, TestService::class.java)
stopService(intent)

를 호출해 주는것도 잊지 않도록 하자.

 

 

더 나아가서, 포어그라운드 서비스와 엑티비티간 통신을 구현해 보자.

 

서비스와 엑티비티간 통신에는 LocalBroadcastManager를 사용한다.

 

먼저 서비스 부분에서 엑티비티로 보내기 위한 부분을 세팅해보자.

 

val localBroadcastManager = LocalBroadcastManager.getInstance(this)
val intent = Intent("intent_action")
intent.putExtra("test", "testString")
localBroadcastManager.sendBroadcast(intent)

 

그 다음 엑티비티에서도 값을 전달받기 위해 다음과 같이 세팅한다.

 

val messageReceiver = object : BroadcastReceiver() {
    override fun onReceive(context: Context, intent: Intent) {
        val test = intent.getStringExtra("test")
        println(test)
    }
}

LocalBroadcastManager.getInstance(this).registerReceiver(messageReceiver, IntentFilter("intent_action"))

 

매우 잘 작동하는 것을 확인할 수 있다.

 

엑티비티에서 서비스로 값을 전달할 때도 이와 같이 작업하면 된다.

반응형
Comments