Home » Android -6. 서비스 및 브로드캐스트

Android -6. 서비스 및 브로드캐스트

6.1. Service

  • 화면없이 뒤에서 실행되는 기능. 예를 들어 음악재생 처럼 다른 작업을 하고 있는 도중에도 계속 노래를 재생해야 하는 작업 등 을 말한다.
  • 현재 사용자가 화면(Activity) 을 보고 있지 않아도 백그라운드에서 실행 되는 것이 바로 Service이다.

<AndroidManifest.xml>
[php]
… 생략

<service
android:name="com.ahope.tutorial.activity.step4.ServiceSample"
android:exported="false" > (1)
<intent-filter> (2)
<action android:name="com.ahope.tutorial.activity.step4.ServiceSample" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</service>
… 생략
[/php]

번호 설명
(1) Service의 이름 및 접근 설정 exported가 false면 다른 어플리케이션의 컴포넌트에서 이 액티비티를 런치 하지 못하도록 설정.
(2) Intent Filter 설정. Intent filter란 컴포넌트(Activity, Service, Broadcast receiver, Content provider)가 가지고 있는 Intent에 관한 정보.

<step4/ServiceSampleActivity>
[php]
startService(new Intent("com.ahope.tutorial.activity.step4.ServiceSample")); (1)
… 생략
stopService(new Intent("com.ahope.tutorial.activity.step4.ServiceSample")); (2)
[/php]

번호 설명
(1) Service 실행. Manifest에 지정한 이름을 매칭
(2) Service 중지

<step4/ServiceSample>
[php]
// onStart시 불려지는 메소드
@Override
public int onStartCommand(Intent intent, int flags, int startId) { (1)
Logger.i("in onStartCommand");
// 음악을 재생하기 위한 플레이어 생성
mPlayer = MediaPlayer.create(this, R.raw.rolling);
// 음악 재생
mPlayer.start();
return super.onStartCommand(intent, flags, startId);
}

// onStop시 불려지는 메소드
@Override
public void onDestroy() { (2)
Logger.i("in onDestroy");

// 음악 끔
mPlayer.stop();
super.onDestroy();

}
[/php]

번호 설명
(1) startService를 했을 때 실행 되는 메소드 (예제에서는 음악 플레이를 하고 있다.)
(2) stopService를 했을 때 실행 되는 메소드 (예제에서는 플레이한 음악을 중지하고 있다.)

  • 음악을 재생시키고 어플을 종료해도 음악이 재생되고 있는지 확인해본다.

6.2. Broadcast Receiver

  • 안드로이드 단말기 내부에는 무수히 많은 일들이 벌어지고 있다.
  • 전화가 걸려 올 수도 있고 SMS 메시지를 받을 수도, 배터리가 부족해질 수도 있다.
  • 이러한 단말기 내부의 특정 여러 가지 상황을 잡아낼 수 있는 기능이 Broadcast Receiver이다.
  • 즉, 어떤 특정한 작업이 벌어질 경우 알려주는 기능을 한다.

Source상에서 Broadcast 등록

퍼미션 등록
<AndroidManifest.xml>
[php]
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
[/php]

<step4/BroadcastSampleActivity>
[php]
… 생략
wifiMonitor = new BroadcastSample(this); (1)
wifiMonitor.setOnChangeNetworkStatusListener(SnowChangedListener); (2)
// 리시버 등록
registerReceiver(wifiMonitor,
new IntentFilter(WifiManager.NETWORK_STATE_CHANGED_ACTION)); (3)
registerReceiver(wifiMonitor, new IntentFilter(WifiManager.WIFI_STATE_CHANGED_ACTION)); (4)

@Override
protected void onDestroy()
{
super.onDestroy();
// 리시버 등록 해제
unregisterReceiver(wifiMonitor); (5)
}

BroadcastSample.OnChangeNetworkStatusListener SnowChangedListener =
new BroadcastSample.OnChangeNetworkStatusListener() { (6)
@Override
public void OnChanged(int status) (7)
{
switch(status) (8)
{
case BroadcastSample.WIFI_STATE_DISABLED:
Logger.i( "[WifiMonitor] WIFI_STATE_DISABLED");
break;
… 생략
[/php]

번호 설명
(1) BroadcastReceiver를 상속 받아 만들어진 객체 생성
(2) 네트워크가 상태가 변경될 때마다 호출 되는 리스너 등록
(3) 리시버를 등록. Intent fileter로 네트워크 상태 변화 액션 등록
(4) 리시버를 등록. Intent fileter로 와이파이 상태 변화 액션 등록
(5) Activity가 끝날 때 등록했던 리시버를 해제
(6) 네트워크 변화 리스너 생성
(7) 네트워크가 변화 될 때 실행되는 메소드
(8) 각 변화에 따른 switch문. (ex. 사용하지 않으면 WIFI_DISABLED가 표시된다.)

<step4/BroadcastSample>
[php]
… 생략
// 생성자
public BroadcastSample(Context context) {
Logger.i("context : " + context);
// wifi 및 네트워크와 관련된 작업을 할 수 있는 객체 가져오기
m_WifiManager = (WifiManager)context.getSystemService(Context.WIFI_SERVICE); (1)
m_ConnManager =
(ConnectivityManager)context.getSystemService(Context.CONNECTIVITY_SERVICE); (2)
}

public void setOnChangeNetworkStatusListener(OnChangeNetworkStatusListener listener) { (3)
m_OnChangeNetworkStatusListener = listener;
}
// 정보는 받는 메소드
@Override
public void onReceive(Context context, Intent intent) (4)
{
if (m_OnChangeNetworkStatusListener == null)
{
return;
}
// 어떤 액션이 발생했는지 가져온다
String strAction = intent.getAction(); (5)
// 액션이 wifi 상태 변화일 경우
if (strAction.equals(WifiManager.WIFI_STATE_CHANGED_ACTION)) (6)
{
switch(m_WifiManager.getWifiState()) (7)
{
case WifiManager.WIFI_STATE_DISABLED:
m_OnChangeNetworkStatusListener.OnChanged(WIFI_STATE_DISABLED);
Logger.i("WIFI_STATE_DISABLED");
break;
… 생략
[/php]

번호 설명
(1) Wifi 관련 작업을 위한 객체 생성
(2) 네트워크 관련 작업을 위한 객체 생성
(3) 네트워크 변화에 대한 리스너
(4) 실제 정보를 받는 메소드
(5) 받은 intent의 액션을 가져온다.
(6) 받은 액션이 Wifi 상태 변화 일 경우의 분기문
(7) Wifi의 상태 변화에 대한 분기문(사용중, 미사용 등)

AndroidManifest.xml에서 Broadcast 등록

퍼미션 등록
<AndroidManifest.xml>
[php]
<uses-permission android:name="android.permission.READ_PHONE_STATE" />

<AndroidManifest.xml>
<receiver android:name=".activity.step4.BroadcastSample2" > (1)
<intent-filter>
<action android:name="android.intent.action.PHONE_STATE" /> (2)
</intent-filter>
</receiver>
[/php]

번호 설명
(1) BroadcastReceiver 이름 설정
(2) Intent filter 설정, action으로 휴대폰의 변화에 대한 감지(전화가 왔는지, 끊겼는지 등)

< step4/BroadcastSample2 >
[php]
@Override
public void onReceive(Context context, Intent intent) { (1)
this.context = context;
Logger.i("in Broad sample 2");
try {
TelephonyManager tmgr = (TelephonyManager) context
.getSystemService(Context.TELEPHONY_SERVICE); (2)

// Create Listner
MyPhoneStateListener PhoneListener = new MyPhoneStateListener(); (3)
} catch (Exception e) {
// Log.e("Phone Receive Error", " " + e);
}

}

// 폰 상태 변화 리스너
private class MyPhoneStateListener extends PhoneStateListener { (4)
public void onCallStateChanged(int state, String incomingNumber) { (5)

Logger.i(state + " incoming no:" + incomingNumber);
// 전화가 걸려왔을 때
if (state == 1) { (6)
String msg = "New Phone Call Event. Incomming Number : "
+ incomingNumber;
ToastUtil.show(context, msg);

}
}
}
[/php]

번호 설명
(1) 정보를 받는 메소드
(2) 전화와 관련된 작업을 위한 객체 생성
(3) 휴대폰의 상태 변화와 관련된 리스너 생성
(4) 휴대폰 상태 변화 리스너
(5) 휴대폰 상태 변화시 호출 되는 메소드 인자로 상태 값과 걸려온 번호를 가져온다.
(6) 전화가 걸려왔을 때(state == 1)의 처리. 토스트 메시지로 걸려온 번호를 띄어준다.

SendBroadcast

<AndroidManifest.xml>
[php]
<receiver android:name=".activity.step4.BroadcastSample3" />

<step4/BroadcastSample3>
@Override
public void onReceive(Context context, Intent intent) {
this.context = context;
Logger.i("in Broad sample 3");

Bundle bundle = intent.getExtras();
String str = StrUtil.isNullCheck(bundle.getString("data"));

if(!str.equals("")) {
ToastUtil.show(context, str + "을 수신했습니다."); (1)
}

}
[/php]

번호 설명
(1) 받은 intent의 데이터를 가져와 토스트 메시지를 띄어준다.

< step4/BroadcastSampleActivity3 >
[php]
Intent intent = new Intent(BroadcastSampleActivity3.this, BroadcastSample3.class); (1)
intent.putExtra("data", "dummy"); (2)
// broadcast 호출
sendBroadcast(intent); (3)
[/php]

번호 설명
(1) Intent 생성. BraodcastSample3를 호출
(2) 보낼 데이터 설정
(3) Broadcast로 만들어진 경우 startActivity가 아닌 sendBroadcast를 사용