728x90

Android 에서 Service 를 만드는 방법입니다.

Service 는 어플리케이션 동작에 상관없이 무언가를 수행하고자 할때 사용됩니다.

 

1. 서비스 만들기

KService 클래스 파일을 하나만듭니다. (이름은 아무거나)

아래 처럼 해당 서비스에는 Service (Android.App.Service) 를 상속 받도록합니다.

Exported 속성은 false 로 하게 되면 실행되는 어플리케이션에 종속되게되어

어플리케이션이 닫히면 서비스도 중단됩니다.

Exported 속성을 true 로 하게 되면 어플리케이션과는 무관하게 서비스가 독립적으로 구동됩니다.

당연히 어플리케이션이 닫혀도 계속 동작하게 됩니다.

Name 은 서비스의 고유 이름입니다. 전역서비스인 경우 이 이름으로 접근하여 핸들링할 수 있습니다.

    [Service(Exported = true, Name = "kr.kjun.KService")]
    public class KService : Service
    {

        /// <summary>
        /// 서비스 객체와 화면간의 데이터를 주고 받고자 할 때 사용되는 메서드로
        /// 데이터를 전달할 필요가 없으면 return null 로 둡니다.
        /// </summary>
        /// <param name="intent"></param>
        /// <returns></returns>
        public override IBinder OnBind(Intent intent)
        {
            return null;
        }

        public override StartCommandResult OnStartCommand(Android.Content.Intent intent, StartCommandFlags flags, int startId)
        {

            // 여기에 수행할 액션을 처리합니다.

             return StartCommandResult.Sticky;
        }

        /// <summary>
        /// 서비스에서 가장 먼저 호출됩니다.(최초에 한번만)
        /// </summary>
        public override void OnCreate()
        {
            base.OnCreate();
        }

        /// <summary>
        /// 서비스가 종료될 때 실행됩니다.
        /// </summary>
        public override void OnDestroy()
        {
            base.OnDestroy();
        }

    }

실제 서비스에서 처리할 로직의 코드가 들어갈 부분은 OnStartCommand 메서드 부분입니다.

return 의 종류가 총 5개가 있는데 가장많이 사용되는 것은 세자기로

Sticky
Service가 강제 종료되었을 경우 시스템이 다시 Service를 재시작 시켜 주지만 intent 값을 null로 초기화 시켜서 재시작 합니다. 
Service 실행시 StartService(Intent service) 메서드를 호출 하는데 OnStartCommand(Intent intent, int flags, int startId) 메서드에 intent로 value를 넘겨 줄 수 있습니다.
기존에 intent에 value값이 설정이 되있다고 하더라도 Service 재시작시 intent 값이 null로 초기화 되서 재시작 됩니다.

NotSticky
이 Flag를 리턴해 주시면, 강제로 종료 된 Service가 재시작 하지 않습니다. 시스템에 의해 강제 종료되어도 괸찮은 작업을 진행 할 때 사용해 주시면 됩니다.

RedeliverIntent
Service가 종료 되었을 경우 시스템이 다시 Service를 재시작 시켜 주지만 intent 값을 그대로 유지 시켜 줍니다. StartService() 메서드 호출시 Intent value값을 사용한 경우라면 해당 Flag를 사용해서 리턴값을 설정해 주면 됩니다.

참고 : https://developer.xamarin.com/api/type/Android.App.StartCommandResult/

저같은 경우는 타이머를 동작 시켜 특정 작업을 주기적으로 DB 에 담는 처리를 하였습니다.

 

2. 서비스 등록하기

서비스를 아무리 잘만들었어도 등록되지 않으면 구동되지 않고 에러가 납니다.

아래 처럼 AndroidManifest.xml 파일에 서비스를 등록해 주어야합니다.

Service 이름은 위에서 지정한 Name 이름을 넣습니다.

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:versionCode="11" android:versionName="2.0" package="kr.kjun.pushcoin" android:installLocation="auto">
 <uses-sdk android:minSdkVersion="19" android:targetSdkVersion="23" />
  ........
  ........
 <application android:allowBackup="true" android:label="@string/app_name" android:icon="@drawable/icon">
  <service android:name="kr.kjun.KService" android:exported="true"></service>
  ........
  ........
 </application>
</manifest>

 

3. 서비스 구동하기

이제 서비스 구동 준비는 되었고 원하는 시기에 서비스가 동작하도록 코딩을 해야합니다.

옐호 어플리케이션 시작시에 동작시킨다면

MainActivity.cs 에서 OnCreate 메서드에 아래 처럼 코딩하면 서비스가 시작됩니다.

KService kService = new Intent(this, typeof(KService));

StartService(kService);

 

4. 서비스 구동여부 확인하는 방법

아래 코드는 해당 서비스가 동작하고 있는지 여부를 리턴해 줍니다.

이를 확인하여 서비스 중복 실행을 방지합니다.

위에서 정의한 Name 항목으로 서비스를 찾을수 있습니다.

        /// <summary>
        /// 현재 서비스가 실행중인지 확인합니다.
        /// </summary>
        /// <param name="context"></param>
        /// <param name="serviceName">찾을 서비스 명입니다.</param>
        /// <returns></returns>
        public static bool IsServiceRunningCheck(Context context, string serviceName)
        {
            ActivityManager manager = (ActivityManager)context.GetSystemService(Activity.ActivityService);

            ActivityManager.RunningServiceInfo service 
                                        = manager.GetRunningServices(int.MaxValue).Where(c => c.Service.ClassName.Equals(serviceName)).FirstOrDefault();

            if(service != null) return true;

            return false;
        }

728x90
Posted by kjun.kr
,