Broadcast Receiver


보내는 쪽은 하나이고 받는 쪽은 다수인 개념으로 Broadcast라는 용어를 통상 쓴다.

BroadcastReceiver클래스를 재정하여 사용 한다.

  • void onReceive (Context context, Intent intent)

메인 스레드에서 동작하기 때문에 간결하게 작성하고 신속하게 리턴해야한다.

시스템에서 응용프로그램으로 방송하는 것이 일반적이지만 응용 프로그램도 특별한 변화를 유발시켰다거나 특이한 변화를 발견했다면
다른 응용 프로그램에게 방송을 보낼 수 있다.
그래서 방송은 응용 프로그램끼리 통신하는 공식적인 수단으로 활용된다. 응용 프로그램이 방송할 때는 다음 메서드를 호출한다.

  • void sendBroadcast (Intent intent [, String receiverPermission])
  • void sendOrderdBroadcast (Intent intent, String receiverPermission)

일반 방송은 비동기적으로 동작하여 호출시 즉시 리턴한다. 수신자가 방송을 수신했는지의 여부는 관여하지 않으며 누가 먼저 방송을 받을지 알 수 없다. 비동기적이며 비순서적이므로 효율이 좋다.

BroadCast 발생과 수신

임의로 응용프로그램에서 BR을 발생시키는 코드이다.

public class DetectFree extends Activity {
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.detectfree);
	}

	public void mOnClick(View v) {
		Intent intent = new Intent();
		intent.setAction("andexam.ver6.FREEWIFI");
		sendBroadcast(intent);
	}
}

수신하는 코드는 다음과 같다.

public class FreeBR extends BroadcastReceiver {
	public void onReceive(Context context, Intent intent) {
		Intent intent2 = new Intent(context, 
				andexam.ver6.c28_network.AsyncDownHtml.class);
		intent2.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
		context.startActivity(intent2);
	}
}

매니패시트

<receiver android:name=".c29_br.FreeBR">
    <intent-filter>
        <action android:name="andexam.ver6.FREEWIFI" />
    </intent-filter>
</receiver>

BR이 수신되면 html을 다운받는 새로운 Activity를 실행하는 코드를 작성해 두었다.

동적 BR 등록

매니페스트에 등록하지 않고 코드상에서도 할 수 있다.
즉 필요할 때만 등록하고 해지 시킬 수 있다.

  • Intent registerReceiver (BroadcastReceiver receiver, IntentFilter filter)
  • void unregisterReceiver (BroadcastReceiver receiver)

등록 메서드로 BR 객체와 인텐트 필터를 직접 전달한다.

  • onResume() 등록
  • onPause() 해제

코드는 아래와 같다.

public class OnSaveZone extends Activity {
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.onsavezone);
	}
	
	public void onResume() {
		super.onResume();
		IntentFilter filter = new IntentFilter();
		filter.addAction("andexam.ver6.SAVEZONE");
		registerReceiver(mSaveZoneBR, filter);
	}
	
	public void onPause() {
		super.onPause();
		unregisterReceiver(mSaveZoneBR);
	}

	BroadcastReceiver mSaveZoneBR = new BroadcastReceiver() {
		public void onReceive(Context context, Intent intent) {
			Toast.makeText(context, "아싸! 공짜다.", 
					Toast.LENGTH_LONG).show();
		}
	};
}

배터리 감시용 코드

public class WatchBattery extends Activity {
	TextView mStatus;

	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.watchbattery);

		mStatus = (TextView)findViewById(R.id.status);
	}
	
	public void onResume() {
		super.onResume();
		IntentFilter filter = new IntentFilter();
		filter.addAction(Intent.ACTION_BATTERY_CHANGED);
		filter.addAction(Intent.ACTION_BATTERY_LOW);
		filter.addAction(Intent.ACTION_BATTERY_OKAY);
		filter.addAction(Intent.ACTION_POWER_CONNECTED);
		filter.addAction(Intent.ACTION_POWER_DISCONNECTED);
		registerReceiver(mBRBattery, filter);
	}	

	public void onPause() {
		super.onPause();        
		unregisterReceiver(mBRBattery);
	}

	BroadcastReceiver mBRBattery = new BroadcastReceiver() {
		int Count = 0;
		public void onReceive(Context context, Intent intent) {
			String action = intent.getAction();
			Count++;
			if (action.equals(Intent.ACTION_BATTERY_CHANGED)) {
				onBatteryChanged(intent);
			}
			if (action.equals(Intent.ACTION_BATTERY_LOW)) {
				Toast.makeText(context, "배터리 위험 수준", Toast.LENGTH_LONG).show();
			}
			if (action.equals(Intent.ACTION_BATTERY_OKAY)) {
				Toast.makeText(context, "배터리 양호", Toast.LENGTH_LONG).show();
			}
			if (action.equals(Intent.ACTION_POWER_CONNECTED)) {
				Toast.makeText(context, "전원 연결됨", Toast.LENGTH_LONG).show();
			}
			if (action.equals(Intent.ACTION_POWER_DISCONNECTED)) {
				Toast.makeText(context, "전원 분리됨", Toast.LENGTH_LONG).show();
			}
		}

		public void onBatteryChanged(Intent intent) {
			int plug, status, scale, level, ratio;
			String sPlug = "";
			String sStatus = "";

			if (intent.getBooleanExtra(BatteryManager.EXTRA_PRESENT, false) == false){
				mStatus.setText("배터리 없음");
				return;
			}

			plug = intent.getIntExtra(BatteryManager.EXTRA_PLUGGED, 0);
			status = intent.getIntExtra(BatteryManager.EXTRA_STATUS, 
					BatteryManager.BATTERY_STATUS_UNKNOWN);
			scale = intent.getIntExtra(BatteryManager.EXTRA_SCALE, 100);
			level = intent.getIntExtra(BatteryManager.EXTRA_LEVEL, 0);
			ratio = level * 100 / scale;

			switch (plug) {
			case BatteryManager.BATTERY_PLUGGED_AC:
				sPlug = "AC";
				break;
			case BatteryManager.BATTERY_PLUGGED_USB:
				sPlug = "USB";
				break;
			default:
				sPlug = "Battery";
				break;
			}

			switch (status) {
			case BatteryManager.BATTERY_STATUS_CHARGING:
				sStatus = "충전중";
				break;
			case BatteryManager.BATTERY_STATUS_NOT_CHARGING:
				sStatus = "충전중 아님";
				break;
			case BatteryManager.BATTERY_STATUS_DISCHARGING:
				sStatus = "방전중";
				break;
			case BatteryManager.BATTERY_STATUS_FULL:
				sStatus = "만충전";
				break;
			default:
			case BatteryManager.BATTERY_STATUS_UNKNOWN:
				sStatus = "알 수가 없어";
				break;
			}

			String str = String.format("수신 회수:%d\n연결: %s\n상태:%s\n레벨:%d%%", 
					Count, sPlug, sStatus, ratio);
			mStatus.setText(str);
		}
	};
}


'Computer Science > Android Application' 카테고리의 다른 글

NDK 사용  (0) 2017.08.20
Preference  (0) 2017.08.20
Service  (0) 2017.08.16
Activity  (0) 2017.08.16
쓰레드 (Thread)  (0) 2017.08.04

+ Recent posts