일반적으로 서비스는 백그라운드(Background)로 동작합니다. 하지만 필요에 따라서는 이 서비스를 포어그라운드(Foreground)로도 실행할 수 있습니다. 포어그라운드라면 서비스가 동작하는 것 자체를 사용자에게 표시해야 하는데 이때는 휴대폰의 상단 상태바를 활용하게 됩니다.
우선 서비스를 포어그라운드로 동작시키려면 해당 권한을 명시해야 합니다. app -> manifests -> AndroidManifest.xml파일에 다음과 같은 태그를 추가해 주세요.
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
그다음 app -> java -> [패키 지명]에서 마우스 오른쪽 버튼을 눌러 New -> Service -> Service를 선택합니다. 화면상의 Class Name은 MyService정도로 하고 Finish를 눌러줍니다.
파일이 생성되면 onBind() 메서드를 아래와 같이 수정합니다.
class MyService : Service() {
override fun onBind(intent: Intent): IBinder {
return Binder()
}
}
그리고 상태바에 알림을 표시할 메서드를 작성합니다. 알림은 채널단위로 동작하기에 사용할 채널 변수(SC)를 설정하고 설정한 채널로 알림이 표시되도록 하는 것입니다.
class MyService : Service() {
val SC = "myService"
fun Notification() {
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
val nc = NotificationChannel(SC, "My Service Channel", NotificationManager.IMPORTANCE_DEFAULT)
val nm = getSystemService(NotificationManager::class.java)
nm.createNotificationChannel(nc)
} else {
Toast.makeText(this, "알림을 실행할 수 없음", Toast.LENGTH_LONG).show()
}
}
override fun onBind(intent: Intent): IBinder {
return Binder()
}
}
위에서 알림 채널을 생성하였으면 onStartCommand()를 오버라이드 하여 Notification() 메서드를 호출해 채널을 만들고, 알림 제목과 아이콘을 지정하여 알림을 생성한 뒤 startForeground() 메서드로 알림을 표시하도록 합니다. 이때 NotificationCompat의 setContentTitle에서는 알림의 제목을, setSmallIcon에서는 알림의 아이콘을 지정하고 있는데 이러한 설정은 생략이 가능합니다.
class MyService : Service() {
val SC = "myService"
fun Notification() {
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
val nc = NotificationChannel(SC, "My Service Channel", NotificationManager.IMPORTANCE_DEFAULT)
val nm = getSystemService(NotificationManager::class.java)
nm.createNotificationChannel(nc)
} else {
Toast.makeText(this, "알림을 실행할 수 없음", Toast.LENGTH_LONG).show()
}
}
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
Notification()
val nc: Notification = NotificationCompat.Builder(this, SC).setContentTitle("myNotify").setSmallIcon(R.mipmap.ic_launcher_round).build()
startForeground(1, nc)
return super.onStartCommand(intent, flags, startId)
}
override fun onBind(intent: Intent): IBinder {
return Binder()
}
}
이번에는 MainActivity.kt에서 서비스를 실행하는 ServiceStart()와 서비스를 중지하는 ServiceStop() 메서드를 작성합니다. 특히 ServiceStart() 메서드에 주목해 주세요. 서비스를 포어그라운드로 동작시키려면 ContextCompat.startForegroundService() 메서드를 사용해야 합니다.
fun ServiceStart(view: View) {
val intent = Intent(this, MyService::class.java)
ContextCompat.startForegroundService(this, intent)
}
fun ServiceStop(view: View) {
val intent = Intent(this, MyService::class.java)
stopService(intent)
}
그런 다음 MainActivity 디자인 화면에서 다음과 같이 버튼 2개를 만들고 각각 ID를 btnServiceStart와 btnServiceStop으로 지정합니다. 그리고 btnServiceStart 버튼의 onClick속성에는 ServiceStart() 메서드를 btnServiceStop 버튼의 onClick속성에는 ServiceStop() 메서드를 지정합니다. 그러면 각 버튼을 클릭할 때마다 해당 메서드를 호출하게 됩니다. 이러한 방법이 가능한 이유는 위에서 ServiceStart()와 ServiceStop() 메서드를 만들 때 매개변수로 View를 지정했기 때문입니다.
앱을 동작시켜 '서비스실행'버튼을 누르면 상태바에 설정한 알림이 표시되는 걸 확인할 수 있습니다.
'Mobile > Kotlin' 카테고리의 다른 글
[Kotlin] HttpURLConnection (2) | 2021.01.12 |
---|---|
[Kotlin] 컨텐트 리졸버(Content Resolver) (0) | 2021.01.11 |
[Kotlin] 서비스(Service) (2) | 2021.01.07 |
[Kotlin] AsyncTask (0) | 2021.01.06 |
[Kotlin] 프로세스(Process)와 스레드(Thread) (0) | 2021.01.05 |