Gomdori

[Android] Background Service(Thread) 백그라운드 서비스 유지하기(+Notification) 본문

코딩(Coding)

[Android] Background Service(Thread) 백그라운드 서비스 유지하기(+Notification)

Ghomdori 2020. 2. 4. 22:48

안녕하세요.

오늘은 Android Background Service 만들기입니다.

Background Service란?

앱을 종료하여도 내부적으로 돌아가는 프로세스를 의미합니다.

즉, 예를 들어 사용자의 위치 정보 등을 갖고 올 때 사용됩니다.

바로 본론으로 들어가도록 하겠습니다.

 

Manifests.xml

<manifests>

<application>

	<activtiy></activity
    <service android:name="MyService"
            android:enabled="true"
            android:exported="true">

</manifests>

 

MainActivity.java

public class test extends AppCompatActivity{
   
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate( savedInstanceState );
        setContentView( R.layout.activity_main );
        
        // 앱 실행시 Background Service 실행
        Intent serviceintent = new Intent( test.this, MyService.class );
        startService( serviceintent );
        
    }
}

 

ServiceThread -- Thread가 실행되는 부분입니다.

public class ServiceThread extends Thread {
    Handler handler;
    boolean isRun = true;

    public ServiceThread(Handler handler) {
        this.handler = handler;
    }
    public void stopForever() {
        synchronized (this) {
            this.isRun = false;
        }
    }
    public void run() {
        //반복적으로 수행할 작업을 한다.
        while (isRun) {
            handler.sendEmptyMessage( 0 );//쓰레드에 있는 핸들러에게 메세지를 보냄
            try {
                Thread.sleep( 1000 ); //10초씩 쉰다.
            } catch (Exception e) {
            }
        }
    }
}

Thread.sleep(1000) = 1000당 1초입니다.

 

추가 과금없는 저렴한 무제한트래픽 웹호스팅 추천(WebHosting)

안녕하세요. 오늘은 추가과금없이 저렴하게 무제한 트래픽을 이용할 수 있는 웹호스팅을 추천하려고 합니다. 보통 잘 알려진 카페24(cafe24) / 가비아 등 웹호스팅업체를 사용하는데요. 카페 24 같�

shihis123.tistory.com

 

MyService</p

public class MyService extends Service {
    NotificationManager Notifi_M;
    ServiceThread thread;

    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Notifi_M = (NotificationManager) getSystemService( Context.NOTIFICATION_SERVICE );
        myServiceHandler handler = new myServiceHandler();
        thread = new ServiceThread( handler );
        thread.stopForever();
        return START_STICKY;
    }

    //서비스가 종료될 때 할 작업
    public void onDestroy() {
        myServiceHandler handler = new myServiceHandler();
        thread = new ServiceThread( handler );
        thread.start();
    }

    public void start() {
        myServiceHandler handler = new myServiceHandler();
        thread = new ServiceThread( handler );
        thread.start();
    }

    public void stop() {
        myServiceHandler handler = new myServiceHandler();
        thread = new ServiceThread( handler );
        thread.stopForever();
    }

    public class myServiceHandler extends Handler {
        @Override
        public void handleMessage(android.os.Message msg) {
            NotificationManager notificationManager = (NotificationManager) getSystemService( Context.NOTIFICATION_SERVICE );
            Intent intent = new Intent( test.this, MainActivity.class );
            intent.addFlags( Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_SINGLE_TOP );
            PendingIntent pendingIntent = PendingIntent.getActivity( MyService.this, 0, intent, PendingIntent.FLAG_ONE_SHOT );
            Uri soundUri = RingtoneManager.getDefaultUri( RingtoneManager.TYPE_NOTIFICATION );

            if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
                @SuppressLint("WrongConstant")
                NotificationChannel notificationChannel = new NotificationChannel( "my_notification", "n_channel", NotificationManager.IMPORTANCE_MAX );
                notificationChannel.setDescription( "description" );
                notificationChannel.setName( "Channel Name" );
                assert notificationManager != null;
                notificationManager.createNotificationChannel( notificationChannel );
            }
            NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder( MyService.this )
                    .setSmallIcon( R.drawable.appicon )
                    .setLargeIcon( BitmapFactory.decodeResource( getResources(), R.drawable.appicon ) )
                    .setContentTitle( "Title" )
                    .setContentText( "ContentText" )
                    .setAutoCancel( true )
                    .setSound( soundUri )
                    .setContentIntent( pendingIntent )
                    .setDefaults( Notification.DEFAULT_ALL )
                    .setOnlyAlertOnce( true )
                    .setChannelId( "my_notification" )
                    .setColor( Color.parseColor( "#ffffff" ) );
            //.setProgress(100,50,false);
            assert notificationManager != null;
            int m = (int) ((new Date().getTime() / 1000L) % Integer.MAX_VALUE);
            Calendar cal = Calendar.getInstance();
            int hour = cal.get( Calendar.HOUR_OF_DAY );
            if (hour == 18) {
                notificationManager.notify( m, notificationBuilder.build() );
                thread.stopForever();
            } else if (hour == 22) {
                notificationManager.notify( m, notificationBuilder.build() );
                thread.stopForever();
            }
        }
    }
}

제가 만든 Background Service는 Calendar를 이용하여, 위에 Thread.sleep(1000)이지만,

 

 

실제로는 Thread.sleep(3000000)으로 하여, 30분 단위로 백그라운드 서비스를 통하여 Calendar를 이요한 현재 시간이 18시 또는 22시 일 경우 notifiaction push 를 주는 예제를 해보았습니다.

thread.stopForerver()을 사용한 이유는, 처음에 MainActivity 앱 실행시 18시 또는 22시일 경우 Notification Push 알림이 계속 울려서 해다 앱이 실행 중일 시 한번만 울리도록 하였으며,

MyService의 onDestroy() 메소드를 보시면, 서비스가 종료되더라도, 다시 Service를 실행하여, 백그라운드 작업이 진행되도록 하였습니다. 후......

Thread 뭔가 힘드네유..

이거때문에 3시간 날렸네.. 화가나네요...ㅠㅠ

좀더 분발해야 할 것 같습니다.

읽어주셔서 정말 감사합니다~!!

모르시는 거 있으시면 제가 아는 범위 안에서 답변해드리도록 하겠습니다!

Comments