[Android] BroadcastReceiver 샘플테스트

나도 최근에 테스트해본 것이지만, 안드로이드에는 브로드캐스트 리시버라는 놈이 있다.
이놈을 간단히 설명하자면, 사용자 또는 주변환경에 의해 단말기의 상태가 변경되어 버릴때 호출되도록 미리 설정을 해 놓으면 그러한 상황이 벌어졌을때에 자동으로 (세상에 자동은 없다. 미리 설정되어 있을뿐...) 호출되는 모 그런놈이란다.

이 브로드캐스트 리시버라는 놈은 두가지 방법으로 설정해줄 수가 있다. 한가지는 XML로 매니페스트 파일에 설정을 하는것이고, 다른 하나는 자바 코드로 클래스상에서 등록해주는 것이다. 두가지 방법에는 큰 차이점이 있었다.

일단 매니페스트에 등록할때의 방법을 살펴보자.

<receiver android:name=".SampleBroadcastReceiver">
      <intent-filter>
              <action android:name="android.net.conn.CONNECTIVITY_CHANGE">
      </intent-filter>
</receiver>
인터넷에 자료가 많지만, 요놈을 매니페스트의 어느 위치에 설정하는지 나와있는 자료는 좀 드물다. 다들 잘 아는걸까 -_-; 그렇다. 나만 잘 모르는것이다. 나같은 분들은 그냥 <application></application> 사이에 다른 액티비티 설정부분과 동일한 위치에 설정을 해주면 된다.
그러면 코드로 등록하는 방법도 알아봐야겠다.

         ... (생략) ...            

    final String CONNECTIVITY_CHANGE = "android.net.conn.CONNECTIVITY_CHANGE";

    private BroadcastReceiver receiver;
 
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        /** 네트워크 상태 표시 */
        IntentFilter filter = new IntentFilter(CONNECTIVITY_CHANGE);
        receiver = new ULNetworkReceiver(this);
        registerReceiver(receiver, filter);

    }
         ... (생략) ...
캐치하고자 하는 단말기의 상태변경항목을 이용해 필터를 생성해주고, 새로운 리시버를 생성한뒤 Activity 클래스의 registerReceiver() 메서드를 이용해서 등록한다. 등록은 이렇게 하고... 그럼 해제해주는 메서드도 있을까? 정답은 있다. 그것도 매우 쉽게 unregisterReceiver(receiver) 라는 메서드로 존재한다.

그런데 매니페스트에 설정하는 방법과 코드로 구현하는 방법에는 약간의 차이점이 있다.
코 드를 통해 프로그래밍적으로 등록된 브로드캐스트 리시버는, 브로드캐스트 리시버에 등록된 애플리케이션 컴포넌트가 실행 중인 경우에만 브로드캐스트 인텐트에 반응한다... 라고 참고된 서적에 나와있다. 매우 중요한 차이점이라 생각된다.

샘플코드를 한번 살펴보자.
매우 간단히 만들어본 코드로서, 구성은 메인액티비티와 브로드캐스트 리시버 클래스 이렇게 두개의 클래스로 존재한다. 구현내용은 메인 액티비티가 화면에 출력되면 브로드캐스트 리시버가 등록되겠지? 물론 난 코드로 구현했으니깐 항상 메인 액티비티가 보여질때만 리시버가 동작을 할거고... 화면상에는 버튼이 하나 있고, 텍스트뷰로 카운터가 있어. 그냥 버튼 누르면 카운트가 1씩 증가되는 아주 심플한 프로그램인데, 뭘 할거냐면...

네트워크 상태를 체크하는 브로드캐스트 리시버를 코드로 등록했다.
애뮬레이터 혹은 단말기로 테스트를 하는데, 애뮬레이터에서는 F8 키를 이용/단말에서는 알아서 네트워크 상태를 변경한다. 이 때에 등록된 리시버가 정상적으로 동작하고, 또 리시버가 동작할때마다 리시버클래스는 메인 액티비티의 onResume() 메서드를 호출한다. 뭐 onResume() 메서드가 하는 일은 버튼을 눌렀을때와 마찬가지로 카운트를 1씩 증가시켜 주는 역할을 한다.

더 간단히 말하자면, 브로드캐스트 리시버가 동작할때 화면상의 어떠한 액션을 줄수 있는지 테스트한 결과물이다.
너무 간만에 직접 내용을 적었더니 손가락이 아프다. 이상 끝.

0002


MainActivity.java

package com.vartist;

import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.IntentFilter;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;

import com.vartist.receiver.ULNetworkReceiver;

public class MainActivity extends Activity {

 final String CONNECTIVITY_CHANGE = "android.net.conn.CONNECTIVITY_CHANGE";
 
 private TextView myTextView;
 private Button myUpdateButton;
 private int count = 0;
 private BroadcastReceiver receiver;
 
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        /** 레이아웃 가져오기 */
        this.myTextView = (TextView) findViewById(R.id.myId);
        this.myUpdateButton = (Button) findViewById(R.id.updateButton);
      
        /** 네트워크 상태 표시 */
        IntentFilter filter = new IntentFilter(CONNECTIVITY_CHANGE);
        receiver = new ULNetworkReceiver(this);
        registerReceiver(receiver, filter);
      
        /** 테스트 클릭이벤트 */
        this.myUpdateButton.setOnClickListener(new OnClickListener(){

   @Override
   public void onClick(View arg0) {
    onResume();
   }
        
        });
    }

 @Override
 public void onResume() {
  super.onResume();
 
  this.myTextView.setText("테스트 어플리케이션... / count : " + this.count++);
 }

 @Override
 protected void onDestroy(){
  super.onDestroy();
  unregisterReceiver(receiver);
  Log.e("info >>> ", "unregisterReceiver()...");
 }
}
ULNetworkReceiver.java

package com.vartist.receiver;

import com.vartist.MainActivity;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.util.Log;
import android.widget.Toast;

public class ULNetworkReceiver extends BroadcastReceiver {
 
 private Activity activity;
 
 public ULNetworkReceiver() {
  super();
 }

 public ULNetworkReceiver(Activity activity) {
  this.activity = activity;
 }
 
 @Override
 public void onReceive(Context context, Intent intent) {
 
  String action = intent.getAction();
 
  // 네트웍에 변경이 일어났을때 발생하는 부분
  if (action.equals(ConnectivityManager.CONNECTIVITY_ACTION)) {
   try {
    ConnectivityManager connectivityManager =
           (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
    NetworkInfo activeNetInfo = connectivityManager.getActiveNetworkInfo();
    NetworkInfo _wifi_network =
            connectivityManager.getNetworkInfo(ConnectivityManager.TYPE_WIFI);

    if(_wifi_network != null) {
   
     /** 3G, WIFI 둘 중 하나라도 있을 경우 */
     if(_wifi_network != null && activeNetInfo != null){
      Toast.makeText(context, "상태1 : " + activeNetInfo.getTypeName(), Toast.LENGTH_SHORT).show();
     }
     /** 3G, WIFI 둘 다 없을 경우 */
     else{
      Toast.makeText(context, "상태2 : 3G/WIFI 불가능", Toast.LENGTH_SHORT).show();
     }
    
     /** 테스트용 */
     if(this.activity instanceof MainActivity) {
      ((MainActivity)this.activity).onResume();     
     }
    }
   } catch (Exception e) {
    Log.i("ULNetworkReceiver", e.getMessage());
   }  
  }
 }
}
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
      package="com.vartist"
      android:versionCode="1"
      android:versionName="1.0">
    <application android:icon="@drawable/icon" android:label="@string/app_name">
        <activity android:name=".MainActivity"
                  android:label="@string/app_name">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

<!--
  <receiver android:name=".receiver.ULNetworkReceiver"
                             android:enabled="true" android:priority="0">
         <intent-filter>
                <action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
         </intent-filter>
  </receiver>
 -->
 
    </application>
    <uses-sdk android:minSdkVersion="7" />
 <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
 <uses-permission android:name="android.permission.INTERNET" />
</manifest>