Presentation is loading. Please wait.

Presentation is loading. Please wait.

안드로이드 프로그래밍 서비스와 방송 수신자 장 원 영 실습파일 : http://goo.gl/Nans04.

Similar presentations


Presentation on theme: "안드로이드 프로그래밍 서비스와 방송 수신자 장 원 영 실습파일 : http://goo.gl/Nans04."— Presentation transcript:

1 안드로이드 프로그래밍 서비스와 방송 수신자 장 원 영 실습파일 :

2 목차 서비스 서비스 기초 IntentService 클래스 연결 타입의 서비스 방송 수신자란? 애플리케이션이 방송하기
중요한 방송

3 이 장의 주요 개념 2가지 관점을 토대로 이해 서비스 -- 클라이언트 방송수신자 -- 방송송신자

4 서비스 특징 액티비티, 방송 수신자, 콘텐츠 제공자와 함께 주요 컴포넌트 사용자 인터페이스를 가지지 않음
메니페스트 선언 사용자 인터페이스를 가지지 않음 서비스를 호출한 메인 스레드 안에서 실행됨 큰 작업의 경우 별도의 스레드 생성 가능 백그라운드 작업, 프로세스간 통신 배경 음악 재생 폰의 사용량을 계산 업데이트 검사

5 서비스 종류 시작 타입 서비스 연결 타입 서비스 startService() stopService()
백그라운드에서 무한정 실행 가능 / 일방 (UDP ?) 연결 타입 서비스 bindService() unbindService() 연결되어 있는 동안만 실행 / 상호작용 (TCP ?)

6 서비스 기초 서비스 준비 서비스 생성 public class MusicService extends Service {
public void onStartCommand(Intent intent, int flags, int startid) { // 시작타입의 서비스 // 클라이언트가 startService() 메서드 호출해서 서비스가 시작되면.. } public IBinder onBind(Intent intent) { // 연결타입의 서비스 // 클라이언트가 binService() 메서드 호출해서 연결을 시도하면.. public void onCreate() { // 서비스 초기화 작업 public void onDestroy() { 서비스 기초 서비스 준비

7 src/MusicService.java public class MusicService extends Service {
private static final String TAG = "MusicService"; MediaPlayer player; @Override public IBinder onBind(Intent intent) { return null; } public void onCreate() { Log.d(TAG, "onCreate()"); player = MediaPlayer.create(this, R.raw.old_pop); player.setLooping(false); // Set looping public void onDestroy() { Toast.makeText(this, "Music Service가 중지되었습니다.", Toast.LENGTH_LONG).show(); Log.d(TAG, "onDestroy()"); player.stop(); public int onStartCommand(Intent intent, int flags, int startId) { Log.d(TAG, "onStartCommand()"); Toast.makeText(this, "Music Service가 시작되었습니다.", Toast.LENGTH_LONG).show(); player.start(); return super.onStartCommand(intent, flags, startId); 시작 타입의 서비스의 경우 extends Service extends IntentService

8 src/MusicServiceTest.java public class MusicServiceTest extends Activity implements OnClickListener { private static final String TAG = "MusicServiceTest"; Button start, stop; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); start = (Button) findViewById(R.id.start); stop = (Button) findViewById(R.id.stop); start.setOnClickListener(this); stop.setOnClickListener(this); } public void onClick(View src) { switch (src.getId()) { case R.id.start: Log.d(TAG, "onClick() start "); startService(new Intent(this, MusicService.class)); break; case R.id.stop: Log.d(TAG, "onClick() stop"); stopService(new Intent(this, MusicService.class));

9 AndroidManifest.xml <?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android=" package="com.example" android:versionCode="1" android:versionName="1.0"> <application <activity android:name=".MusicServiceTest" <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <service android:enabled="true" android:name=".MusicService" /> </application> <uses-sdk android:minSdkVersion="16" /> </manifest>

10 서비스 생애주기

11 IntentService 클래스 특징 시작 요청이 들어오면 작업 스레드를 별도 생성 작업 스레드는 1개만 생성됨
다중 작업 불가능 콜백 메서드 구현할 필요 없음 onHandleIntent() 메서드만 구현하면 끝

12 src/MyIntentService.java public class MyIntentService extends IntentService { public MyIntentService() { super("MyIntentService"); } @Override protected void onHandleIntent(Intent intent) { long endTime = System.currentTimeMillis() + 5 * 1000; Log.i("SERVICE", "onHandleIntent() "); while (System.currentTimeMillis() < endTime) { synchronized (this) { try { wait(endTime - System.currentTimeMillis()); } catch (Exception e) {

13 src/IntentServiceTest.java public class IntentServiceTest extends Activity { Intent i; /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); Button start = (Button) findViewById(R.id.start); start.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { i = new Intent(IntentServiceTest.this, MyIntentService.class); startService(i); } }); Button stop = (Button) findViewById(R.id.stop); stop.setOnClickListener(new View.OnClickListener() { stopService(i);

14 연결 타입의 서비스 연결 타입의 서비스 인터페이스 생성 서비스와 클라이언트 간의 연결 매개 Binder 클래스 확장하기
Service 클래스 내부에서 정의하고 클라이언트에서 생성하여 연결함 Binder 클래스 확장하기 Messenger 클래스 사용하기 AIDL 사용하기 인터페이스를 정의하는 .aidl 파일 생성

15 연결 타입의 서비스 연결 타입의 서비스 인터페이스 생성 서비스와 클라이언트 간의 연결 매개 (클래스 내부에서 생성)
Binder 클래스 확장하기 class LocalService extends Service - class LocalBinder extends Binder getSerivce() 구현 - 서비스에서 해야할 메서드 선언구현 (서비스가 해야할 일을 정의) 클라이언트에서 bindService() 호출 LocalService.class를 이용한 Intent + ServiceConnection 인터페이스 객체 LocalService 객체를 통해 메서드 호출 public void onServiceConnected() 메서드에서 LocalService 객체 생성

16 src/LocalService.java public class LocalService extends Service {
// 클라이언트에게 반환되는 바인더 private final IBinder mBinder = new LocalBinder(); // 난수 발생기 private final Random mGenerator = new Random(); // 클라이언트 바인더를 위한 클래스 public class LocalBinder extends Binder { LocalService getService() { return LocalService.this; } @Override public IBinder onBind(Intent intent) { return mBinder; // 클라이언트를 위한 메소드 public int getRandomNumber() { return mGenerator.nextInt(100);

17 src/BoundServiceTest.java public class BoundServiceTest extends Activity { LocalService mService; boolean mBound = false; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); } protected void onStart() { super.onStart(); Intent intent = new Intent(this, LocalService.class); bindService(intent, mConnection, Context.BIND_AUTO_CREATE); protected void onStop() { super.onStop(); if (mBound) { unbindService(mConnection); mBound = false; // 버튼이 클릭되면 호출된다. public void onButtonClick(View v) { int num = mService.getRandomNumber(); Toast.makeText(this, "number: " + num, Toast.LENGTH_SHORT).show(); private ServiceConnection mConnection = new ServiceConnection() { public void onServiceConnected(ComponentName className, IBinder service) { LocalBinder binder = (LocalBinder) service; mService = binder.getService(); mBound = true; public void onServiceDisconnected(ComponentName arg0) { };

18 연결 타입의 서비스 연결 타입의 서비스 인터페이스 생성 서비스와 클라이언트 간의 연결 매개 (클래스 내부에서 생성)
Messenger 클래스 사용하기 class MessengerService extends Serivce - class IncomingHandler extends Handler public void handleMessage(Message) 구현 (서비스가 해야할 일을 정의) - new Messenger(new IncomingHandler()).getBinder()로 연결 클라이언트에서 bindService() 호출 - MessengerService.class를 이용한 Intent + ServiceConnection 인터페이스 객체 - Messenger 객체.send(매개변수) 메서드 호출을 통해 서비스 이용 매개변수 : handleMessage(Message)의 Message 값 Message 값 : Message.obtain() 메서드로 가져옴 public void onServiceConnected() 메서드에서 new Messenger(service) 객체 생성

19 res/layout/main.xml <?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android=" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" > <TextView android:layout_height="wrap_content" /> <Button android:layout_height="wrap_content" android:layout_width="fill_parent" android:text="서비스에 메시지 보내기" android:onClick="sayHello"></Button> </LinearLayout>

20 src/MessengerService.java public class MessengerService extends Service { static final int MSG_SAY_HELLO = 1; class IncomingHandler extends Handler { @Override public void handleMessage(Message msg) { switch (msg.what) { case MSG_SAY_HELLO: Toast.makeText(getApplicationContext(), "hello!", Toast.LENGTH_SHORT).show(); break; default: super.handleMessage(msg); } final Messenger mMessenger = new Messenger(new IncomingHandler()); public IBinder onBind(Intent intent) { Toast.makeText(getApplicationContext(), "binding", Toast.LENGTH_SHORT).show(); return mMessenger.getBinder();

21 src/BoundServiceTest.java public class MessengerServiceTest extends Activity { /// 서비스와 통신하는데 사용되는 메신저 객체 Messenger mService = null; // 바운드 여부를 표시한다. boolean mBound; // 서비스의 인터페이스와 상호작용하는 클래스 private ServiceConnection mConnection = new ServiceConnection() { public void onServiceConnected(ComponentName className, IBinder service) { mService = new Messenger(service); mBound = true; } public void onServiceDisconnected(ComponentName className) { mService = null; mBound = false; }; // 버튼이 눌려지면 실행된다. public void sayHello(View v) { if (!mBound) return; Message msg = Message.obtain(null, MessengerService.MSG_SAY_HELLO, 0, 0); try { mService.send(msg); } catch (RemoteException e) { e.printStackTrace(); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); protected void onStart() { super.onStart(); bindService(new Intent(this, MessengerService.class), mConnection, Context.BIND_AUTO_CREATE); protected void onStop() { super.onStop(); if (mBound) { unbindService(mConnection);

22 방송 수신자란? 방송 안드로이드 장치가 애플리케이션에게 통지 방송 내용 수신측 네트워크 연결 여부 SD 카드 삽입 여부
Intent 매개변수를 통해 전달 수신측 인텐트 필터를 통해 어떤 방송을 수신할지 지정 Manifest.xml 에서 지정 소스코드에서 지정

23 src/BroadcastReceiverTest.java public class BroadcastReceiverTest extends Activity { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); }

24 src/MyBroadcastReceiver.java public class MyBroadcastReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { // TODO Auto-generated method stub Bundle bundle = intent.getExtras(); SmsMessage[] msgs = null; String str = ""; if (bundle != null) { Object[] pdus = (Object[]) bundle.get("pdus"); msgs = new SmsMessage[pdus.length]; for (int i=0; i<msgs.length; i++) { msgs[i] = SmsMessage.createFromPdu((byte[])pdus[i]); str += "SMS from " + msgs[i].getOriginatingAddress(); str += " :"; str += msgs[i].getMessageBody().toString(); str += "\n"; } Toast.makeText(context, str, Toast.LENGTH_SHORT).show();

25 AndroidManifest.xml <?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android=" package="kr.co.infinity.BroadcastReceiverTest" android:versionCode="1" android:versionName="1.0"> <application <activity android:name=".BroadcastReceiverTest" <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <receiver android:enabled="true" android:name=".MyBroadcastReceiver"> <action android:name="android.provider.Telephony.SMS_RECEIVED" /> </receiver> </application> <uses-sdk android:minSdkVersion="16" /> <uses-permission android:name="android.permission.RECEIVE_SMS" /> </manifest>

26 방송 수신자란? 방송 수신자의 동적 생성 Context.registerReceiver() 등록
Context.unregisterReceiver() 해제 onResume() 에서 등록 / onPause() 에서 해제 액티비티가 화면에 보이는 동안에만 방송 수신이 가능

27 src/DynamicBRTest.java public class DynamicBRTest extends Activity {
BroadcastReceiver receiver = new BroadcastReceiver() { // 내부 무명 클래스 @Override public void onReceive(Context context, Intent intent) { // TODO Auto-generated method stub Toast.makeText(context, "SMS가 수신되었습니다.", Toast.LENGTH_LONG).show(); } }; public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); public void onResume() { super.onResume(); IntentFilter filter = new IntentFilter(); filter.addAction("android.provider.Telephony.SMS_RECEIVED"); registerReceiver(receiver, filter); public void onPause() { super.onPause(); unregisterReceiver(receiver);

28 애플리케이션이 방송하기 방송하기 메서드 방송의 분류 sendBroadcast(Intent intent)
sendBroadcast(Intent intent, String receiverPermmision) sendOrderedBroadcast(Intent intent, String receiverPermmision) 방송의 분류 일반 방송 수신자의 순서 없음 이전 수신자의 결과를 이용할 수 없음 정렬된 방송 수신자의 순서는 android:priority 로 설정. 이전 수신자의 결과를 이용할 수 있음 방송할 액션 지정된 권한을 가진 수신자에게만 방송을 보내고 싶을 때

29 애플리케이션이 방송하기 하나의 앱에서 다른 앱으로 방송하기 수신 ‘앱’ 방송 ‘앱'

30 src/MainActivity.java public class MainActivity extends Activity {
@Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); } public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.activity_main, menu); return true;

31 src/MyBroadcastReceiver.java public class MyBroadcastReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { // TODO Auto-generated method stub Uri uri = Uri.parse(" Intent intent1 = new Intent(Intent.ACTION_VIEW, uri); intent1.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); context.startActivity(intent1); }

32 src/MyBroadcastReceiver.java <manifest xmlns:android=" package="kr.co.company.mybroadcastreceiver"> <application > <activity android:name=".MainActivity" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <receiver android:name=".MyBroadcastReceiver" > <action android:name="kr.co.company.START_WEB" /> </receiver> </application> </manifest>

33 src/MyBroadcastSender.java public class MyBroadcastSender extends Activity { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); Button click = (Button) findViewById(R.id.click); click.setOnClickListener(new Button.OnClickListener() { public void onClick(View v) { Intent intent = new Intent(); intent.setAction("kr.co.company.START_WEB"); sendBroadcast(intent); } });

34 중요한 방송 안드로이드 시스템의 주요 방송 메시지

35 src/BatterSDCardTes.java public class BatterySDCardTest extends Activity { TextView textfield; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); textfield = (TextView) findViewById(R.id.textfield); } 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_POWER_DISCONNECTED); filter.addAction(Intent.ACTION_POWER_CONNECTED); filter.addAction(Intent.ACTION_MEDIA_MOUNTED); filter.addAction(Intent.ACTION_MEDIA_REMOVED); registerReceiver(receiver, filter);

36 src/BatterSDCardTes.java @Override public void onPause() {
super.onPause(); unregisterReceiver(receiver); } BroadcastReceiver receiver = new BroadcastReceiver() { public void onReceive(Context context, Intent intent) { String action = intent.getAction(); Toast.makeText(context, action, Toast.LENGTH_LONG).show(); textfield.setText(action); if (action.equals(Intent.ACTION_BATTERY_CHANGED)) { int maxvalue = intent.getIntExtra(BatteryManager.EXTRA_SCALE, 0); int value = intent.getIntExtra(BatteryManager.EXTRA_LEVEL, 0); int level = value * 100 / maxvalue; textfield.setText(action + "\n현재 배터리 레벨=" + level); } else if (action.equals(Intent.ACTION_BATTERY_LOW)) { textfield.setText(action + "\n배터리 부족"); } else if (action.equals(Intent.ACTION_MEDIA_MOUNTED)) { textfield.setText(action + "\nSD카드 장착"); textfield.setText(action + "\nSD카드 장착 해제"); };

37 중요한 방송 AVD 실습 Telnet localhost 5554 help power capacity 70 기본은 50으로 설정

38 감사합니다


Download ppt "안드로이드 프로그래밍 서비스와 방송 수신자 장 원 영 실습파일 : http://goo.gl/Nans04."

Similar presentations


Ads by Google