Android 프로그래밍 2

본문 바로가기
사이트 내 전체검색


Android 프로그래밍 2
Android 프로그래밍 2

4. Foreground Service 만들기 (3)

페이지 정보

작성자 관리자 댓글 0건 조회 2,582회 작성일 21-03-23 20:04

본문

4. Foreground Service 만들기 (3)

이전 실습은 단순한 Service에 대해 코드를 작성해봤습니다.


Service는 백그라운드에서 작업하는 코드들을 위해서 존재하는 컴퍼넌트입니다. 

여기서 작성한 코드도 Timer를 Service에서 하기 때문에 액티비티를 홈키를 눌러서 종료시켜도 TImer가 동작을 합니다. 


그러면 이번에는 Foreground Service를 작성해보겠습니다.



1. 프로젝트 생성


프로젝트명 : ServiceTest3



2. 퍼미션 추가


manifest.xml에 permission 코드를 추가해줍니다.


<uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>



3. Service 생성


File -> New -> Service 를 선택하여 Service를 생성합니다.


Service 클래스 명 : FirstService


class FirstService : Service() {


    private val channelId = "channelId test"


    @Override

    override fun onCreate() {

        startNotification()

    }


    // foreground 시작하는 함수.

    private fun startNotification() {

        channelRegister()

        // PendingIntent 입니다.

        val contentIntent = PendingIntent.getActivity(this, 0, Intent(this, MainActivity::class.java), 0)

        // Foreground Service의 layout입니다.

        val view = RemoteViews(packageName, R.layout.service_first)

        // notification 셋팅

        val notification = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {

            Notification.Builder(this, channelId)

                .setSmallIcon(R.drawable.ic_launcher_foreground)  // 아이콘 셋팅

                .setCustomContentView(view)       // 레이아웃 셋팅

                .setContentIntent(contentIntent)  // pendingIntent 클릭시 화면 전환을 위해

                .build()

        } else {

            //TODO("VERSION.SDK_INT < O")

            Notification.Builder(this)

                .setSmallIcon(R.drawable.ic_launcher_foreground)  // 아이콘 셋팅

                .setContent(view)                 // 레이아웃 셋팅

                .setContentIntent(contentIntent)  // pendingIntent 클릭시 화면 전환을 위해

                .build()

        }

        // Foreground 시작하는 코드

        startForeground(1, notification)

    }


    // 채널을 등록하는 함수.

    private fun channelRegister(){

        val channelName = "service channel name"

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {

            val channel = NotificationChannel(

                channelId, channelName,

                NotificationManager.IMPORTANCE_DEFAULT

            )

            val manager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager

            manager.createNotificationChannel(channel)

        }

    }


    override fun onBind(intent: Intent): IBinder {

        //TODO("Return the communication channel to the service.")

        throw UnsupportedOperationException("Not yet")

    }


    private var timer = Timer("TimerTest", false).schedule(2000, 3000) {

        doSomethingTimer()

    }


    // Timer에서 실행되는 함수.

    private fun doSomethingTimer(){

        Handler(Looper.getMainLooper()).post{

            Toast.makeText(applicationContext, "test", Toast.LENGTH_SHORT).show()

        }

    }


    override fun onDestroy() {

        super.onDestroy()

        timer.cancel()

    }


    // 처음 시작되면 호출되는 함수.

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

        callEvent(intent)

        return START_NOT_STICKY

    }


    // 이벤트를 호출(구현하고 싶은 코드를 구현하면 됩니다.)

    private fun callEvent(intent: Intent?){

        Log.d("My_TAG", "callEvent()")

        timer.scheduledExecutionTime()

    }


    companion object {

        fun startService(context: Context) {

            val startIntent = Intent(context, FirstService::class.java)

            context.startService(startIntent)

        }

        fun stopService(context: Context) {

            val stopIntent = Intent(context, FirstService::class.java)

            context.stopService(stopIntent)

        }

    }

}


추가된 코드는 API26(Oreo) 이상에서 foreground에서 service를 시작하기 위해서 채널을 등록해야 돼서. 채널을 등록하는 코드입니다.

그리고 notification을 API26(Oreo) 이상과 미만 버전에서 구별하여 startForeground로 띄웁니다.



service_first 레이아웃 : service_first.xml


<?xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

    android:orientation="vertical"

    android:layout_width="match_parent"

    android:layout_height="match_parent"

    android:gravity="center">

    <TextView

        android:layout_width="wrap_content"

        android:layout_height="wrap_content"

        android:gravity="center"

        android:text="Service Test"

        android:textSize="25sp"/>

</LinearLayout>



4. 서비스 시작


MainActivity.kt


class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {

        super.onCreate(savedInstanceState)

        setContentView(R.layout.activity_main)

    }


    override fun onResume() {

        super.onResume()

        var start_service_btn = findViewById(R.id.start_service_btn) as Button

        var stop_service_btn = findViewById(R.id.stop_service_btn) as Button

        // 서비스 시작 버튼을 눌렀을 때 이벤트 함수.

        start_service_btn.setOnClickListener {

            // 서비스를 시작하는 코드

            FirstService.startService(this)

        }

        // 서비스 종료 버튼을 눌렀을 때 이벤트 함수.

        stop_service_btn.setOnClickListener {

            // 서비스를 종료하는 코드

            FirstService.stopService(this)

        }

    }

}


activity_main.xml


<?xml version="1.0" encoding="utf-8"?>

<LinearLayout

    xmlns:android="http://schemas.android.com/apk/res/android"

    xmlns:app="http://schemas.android.com/apk/res-auto"

    xmlns:tools="http://schemas.android.com/tools"

    android:layout_width="match_parent"

    android:layout_height="match_parent"

    android:orientation="vertical"

    tools:context=".MainActivity">


    <Button

        android:id="@+id/start_service_btn"

        android:text="Start Service"

        android:layout_width="fill_parent"

        android:layout_height="wrap_content" />


    <Button

        android:id="@+id/stop_service_btn"

        android:text="Stop Service"

        android:layout_width="fill_parent"

        android:layout_height="wrap_content" />


</LinearLayout>



5. 실행


서비스 시작을 누르면 똑같은 프로세스가 시작됩니다. 

다만,  위에 Notification에 Service가 띄워져있습니다.



댓글목록

등록된 댓글이 없습니다.


개인정보취급방침 서비스이용약관 모바일 버전으로 보기 상단으로

TEL. 063-469-4551 FAX. 063-469-4560 전북 군산시 대학로 558
군산대학교 컴퓨터정보공학과

Copyright © www.leelab.co.kr. All rights reserved.