상세 컨텐츠

본문 제목

[안드로이드]포그라운드 서비스(Foreground Service) 죽지않는 서비스& 스레드(Thread)

안드로이드

by aries574 2020. 6. 17. 17:09

본문


2020/12/25 - [안드로이드] - [안드로이드]Notification 간단한 알림 띄우기

2020/12/28 - [안드로이드] - [안드로이드]Notification 알림창에 액션기능 추가하기

2020/12/29 - [안드로이드] - [안드로이드] Notification 알림창에 댓글(Reply) 기능 추가

2020/12/30 - [안드로이드] - [안드로이드] Notification 알림창에 ProgressBar 기능 추가

2020/12/31 - [안드로이드] - [안드로이드] Notification 커스텀 알림창 쉽게 적용해보기


안드로이드 화면 밖에서(백그라운드)에서 실행을 시키고싶은 경우가 있습니다. 뒤로가기를 해도 죽지않고 

반복적으로 알아서 계속 돌리는 서비스. 사용자가 서비스 취소를 하지 않을때까지 계속 실행.

이럴때 사용할 수 있는게 있습니다. "포그라운드 서비스(Foreground Service)"입니다.

말로만 들으면 이해가 안되겠지만, 우리는 자주 사용하고 있습니다.  시계어플입니다.

타이머를 실행시키면 상태바에 실행중이라고 하면서 보여줍니다.

사용자가 서비스 이용중이라는 걸 알수 있는게 "포그라운드 서비스(Foreground Service)"입니다.

직접 만들어 보면 이해가 될 것입니다. 그럼 따라해 봅시다.

1. Service 생성

New -> Service -> Service -> MyService.java

 

 

2. 화면에 버튼2개 생성( 서비스 시작, 서비스 취소)

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">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="120dp"
        android:orientation="horizontal">

        <Button
            android:id="@+id/startBtn"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="서비스 시작"/>

        <Button
            android:id="@+id/stopBtn"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="서비스 취소"/>
    </LinearLayout>
</LinearLayout>

 

3. 기능구현 java 소스작성( 서비스 시작, 서비스 취소 기능 구현)

MainActivity.java

 


import androidx.appcompat.app.AppCompatActivity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity {

        Intent serviceIntent;
        
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);

            //서비스 시작
            Button startBtnBtn = findViewById(R.id.startBtn);
            startBtnBtn.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    startService();
                    Toast.makeText(getApplicationContext(), "서비스 시작", Toast.LENGTH_SHORT).show();
                }
            });

            //서비스 취소
            Button stopBtnBtn = findViewById(R.id.stopBtn);
            stopBtnBtn.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    Toast.makeText(getApplicationContext(), "서비스 중지", Toast.LENGTH_SHORT).show();
                    stopService();
                }
            });
        }


    /**
     * 알림서비스 실행
     */
    public void startService()
    {
        serviceIntent = new Intent(this, MyService.class);
        startService(serviceIntent);
    }

    /**
     * 알림서비스 중지
     */
    public void stopService()
    {
        serviceIntent = new Intent(this, MyService.class);
        stopService(serviceIntent);
    }

 

 

4. 서비스 구현

서비스안에 반복작업을 할 수있게 스레드(thread)를 구현했습니다. 사용자의 입맛에 맞게 바꾸시면 됩니다.

MyService.java

public class MyService extends Service {

    BackgroundTask task;

    int value = 0;

    public MyService() {
    }

    @Override
    public IBinder onBind(Intent intent) {
// TODO: Return the communication channel to the service.
        throw new UnsupportedOperationException("Not yet implemented");
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {

//반복작업
        task = new BackgroundTask();
        task.execute();

        initializeNotification(); //포그라운드 생성
        return START_NOT_STICKY;
    }

    /**
     * 포그라운드 서비스
     */
    public void initializeNotification()
    {
        NotificationCompat.Builder builder = new NotificationCompat.Builder(this, "1");
        builder.setSmallIcon(R.mipmap.ic_launcher);
        NotificationCompat.BigTextStyle style = new NotificationCompat.BigTextStyle();
        style.bigText("설정을 보려면 누르세요.");
        style.setBigContentTitle(null);
        style.setSummaryText("서비스 동작중");
        builder.setContentText(null);
        builder.setContentTitle(null);
        builder.setOngoing(true);
        builder.setStyle(style);
        builder.setWhen(0);
        builder.setShowWhen(false);

        Intent notificationIntent = new Intent(this, MainActivity.class);
        PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0);
        builder.setContentIntent(pendingIntent);
        NotificationManager manager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            manager.createNotificationChannel(new NotificationChannel("1", "포그라운드 서비스", NotificationManager.IMPORTANCE_NONE));
        }
        Notification notification = builder.build();
        startForeground(1, notification);
    }

    class BackgroundTask extends AsyncTask<Integer, String, Integer> {

        String result = "";

        @RequiresApi(api = Build.VERSION_CODES.CUPCAKE)
        @Override
        protected Integer doInBackground(Integer... values) {



            while(isCancelled() == false){

                try{
                    println(value + "번째 실해중");
                    Thread.sleep(1000);
                    value++;
                }catch (InterruptedException ex){}
            }
            return value;
        }

        //상태확인
        @Override
        protected void onProgressUpdate(String... String) {
            println("onProgressUpdate()업데이트");
        }

        @Override
        protected void onPostExecute(Integer integer) {
            println("onPostExecute()");
            value = 0;
        }

        @Override
        protected void onCancelled() {
            value = 0; //정지로 초기화
        }
    }

    /**
     * 서비스 종료
     */
    @Override
    public void onDestroy() {
        super.onDestroy();
        Log.d("MyService", "onDestory");

        task.cancel(true);
    }


    public void println(String message){
        Log.d("MyService", message);
    }
}

 

5. 권한등록(manifests -> AndroidManifest.xml)

<uses-permission android:name="android.permission.FOREGROUND_SERVICE"/> <!-- 서비스 권한등록-->

 

6. 실제화면

 

 

2020/12/25 - [안드로이드] - [안드로이드]Notification 간단한 알림 띄우기

2020/12/28 - [안드로이드] - [안드로이드]Notification 알림창에 액션기능 추가하기

2020/12/29 - [안드로이드] - [안드로이드] Notification 알림창에 댓글(Reply) 기능 추가

2020/12/30 - [안드로이드] - [안드로이드] Notification 알림창에 ProgressBar 기능 추가

2020/12/31 - [안드로이드] - [안드로이드] Notification 커스텀 알림창 쉽게 적용해보기

 

반응형

관련글 더보기

댓글 영역