Chapter 5: Intents, Broadcast Receivers, Adapters, and the Internet
1. Introducing Intents 114
Intents 란?
a message-passing mechanism that lets you declare your intention that an action be performed, usually with a particular piece of data
메시지를 전달하는 방법 : 특정 데이터를 사용해서 Action이 발생하게 하려는 의도를 선언하는 것.
Intents 사용 방법
explicitly - 명시적으로 클래스를 사용해서 새로운 Activity 실행
implicitly - 데이터를 사용할 Action을 요청
broadcast messages - Event-driven application, System Event 전달
1.1. Using Intents to Launch Activities 114
startActivity : 새로운 Activity 실행
startActivityForResult : 실행된 Activity로 부터 데이터 받음
Explicity Starting New Activities
Activity 실행
- Intent intent = new Intent (MyActivity.this, MyOtherActivity.class);
- startActivity (intent);
Activity 종료
- finish()
'Back' 버튼으로 이전 Activity로 이동
Implicit Intents and Late Runtime Binding
Implicity Intents - 요청한 Action에 대해 익명의 어플리케이션이 동작
action : 수행할 action 지명
data (option) : action이 사용할 데이터 지정
예) 어플리케이션에서 전화 걸기
- if (somethingWeird & itDontLookGood) {
- Intent intent = new (Intent.ACTION_DIAL, Uri.parse("tel:555-2368"));
- startActivity (intent);
- }
Introducing Linkify
Linkify - RegEx pattern matching (정규 표현식)을 통해 TextView 클래스의 하이퍼링크를 생성하는 helper class
특정한 정규 표현식을 만족하는 텍스트는 하이퍼링크로 변환되며, 관련된 startActivity(new Intent (Intent.ACTION_VIEW, uri)) 를 실행한다.
The Native Link Types
사용법 : Linkify.addLinks
content types : Linkify. (WEB_URLS, EMAIL_ADDRESSES, PHONE_NUMBERS, ALL)
예)web과 e-mail 주소에 대한 하이퍼링크 설정
- TextView textView = (TextView) findViewById (R.id.myTextView);
- Linkify.addLinks (textView, Linkify.WEB_URLS|Linkify.EMAIL_ADDRESSES);
예) 전화 번호와 e-mail 주소에 대한 하이퍼링크 설정
- <TextView
- android:layout_width="fill_parent"
- android:layout_height="fill_parent"
- android:text="@string/linkify_me"
- android:autoLink="phone|email"
- />
Creating Custom Link Strings
정규 표현식을 정의해서 자신만의 linkify 스트링을 정의할 수 있음
예) earthquake data에 대한 하이퍼링크 설정 (quake로 시작하고 바로 뒤에 숫자가 옮)
- int flags = Pattern.CASE_INSENSITIVE;
- Pattern p = Pattern.complie("\\bquake[0-9]*\\b", flags);
- Linkify.addLinks (myTextView, p, "content://com.paad.earthquake/earthquakes/");
TransformFilter와 MatchFilter도 사용할 수 있음
Using the Match Filter
정규 표현식에 대한 조건을 추가
MatchFilter에 acceptMath 메소드 구현
예) 느낌표 이후에 부합하는 것은 거부
- class MyMatchFilter implements MatchFilter {
public boolean acceptMatch(CharSequence s, int start, int end) {
return (start == 0 || s.charAt(start-1) != ‘!’);
}
}
Using the Transform Filter
link 텍스트와 목표 URI의 형태를 일치시키지 않게끔 변화를 주는 것
TransformFilter에 transformUrl 메소드 구현
예) 소문자 URI로 변경
- class MyTransformFilter implements TransformFilter {
public String transformUrl(Matcher match, String url) {
return url.toLowerCase();
}
}
Returning Results from Activities
Launching Sub-Activities
startActivityForResult : Activity 정의, request code 전달
request code : 결과를 반환한 sub-Activity를 구분하는 값
예) skeleton code - explicitly
- private static final int SHOW_SUBACTIVITY = 1;
Intent intent = new Intent(this, MyOtherActivity.class);
startActivityForResult(intent, SHOW_SUBACTIVITY);
예) skeleton code - implicitly
- private static final int PICK_CONTACT_SUBACTIVITY = 2;
Uri uri = Uri.parse(“content://contacts/people”);
Intent intent = new Intent(Intent.ACTION_PICK, uri);
startActivityForResult(intent, PICK_CONTACT_SUBACTIVITY);
Returning Results
finish 를 호출하기 전에 setResult 를 호출
setResult : 결과 코드 - sub-Activity 수행 결과 (Activity.RESULT_OK 또는 Activity.RESULT_CANCELED)
결과 - sub-Activity로 부터의 반환값
예) OK 버튼과 Cancel 버튼
- Button okButton = (Button) findViewById(R.id.ok_button);
okButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
Uri data = Uri.parse(“content://horses/” + selected_horse_id);
Intent result = new Intent(null, data);
result.putExtra(IS_INPUT_CORRECT, inputCorrect);
result.putExtra(SELECTED_PISTOL, selectedPistol); - setResult(RESULT_OK, result);
finish();
}
});
Button cancelButton = (Button) findViewById(R.id.cancel_button);
cancelButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
setResult(RESULT_CANCELED, null);
finish();
}
});
Handling Sub-Activity Results
sub-Activity가 종료될 때 부모 Activity의 onActivityResult 이벤트 핸들러가 실행됨.
onActivityResult의 파라메터
The Request Code : sub-Activity를 실행할 때 사용한 코드
A Result Code : sub-Activity에 의해 결정된 결과 코드, sub-Activity가 비정상 종료하거나 결과 코드를 명시하지 않으면,
Activity.RESULT_CANCELED 로 결정
Data : 반환되는 데이터를 가지고 있는 Intent. 보통 URI가 들어간다.
예) 예제 코드
- private static final int SHOW_SUB_ACTIVITY_ONE = 1;
private static final int SHOW_SUB_ACTIVITY_TWO = 2;
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
switch(requestCode) {
case (SHOW_SUB_ACTIVITY_ONE) : {
if (resultCode == Activity.RESULT_OK) {
Uri horse = data.getData(); - boolean inputCorrect = data.getBooleanExtra(IS_INPUT_CORRECT, false);
String selectedPistol = data.getStringExtra(SELECTED_PISTOL);
}
break;
}
case (SHOW_SUB_ACTIVITY_TWO) : {
if (resultCode == Activity.RESULT_OK) {
// TODO: Handle OK click.
}
break;
}
}
}
Native Android Actions
ACTION_ANSWER, ACTION_CALL, ACTION_DELETE, ACTION_DIAL, ACTION_EDIT, ACTION_INSERT, ACTION_PICK, ACTION_SEARCH, ACTION_SENDTO, ACTION_SEND, ACTION_VIEW, ACTION_WEB_SEARCH
1.2. Using Intent Filters to Service Implicit Intents 121
Intent Filters : Intent를 어떤 어플리케이션이 처리할 지 결정하는데 사용
컴포넌트의 manifest 노드에서 intent-filter 태그 사용
action : android:name , action의 이름, 고유해야 함
category : android:category , action이 수행되는 환경 정의
ALTERNATIVE : 기본 action에 대한 대체자 (기본 action : 보기, alternative : 편집, 삭제 등)
SELECTED_ALTERNATIVE : Alternative와 유사, 여러 action 나열
BROWSABLE : 브라우저 안에서 가능한 action
DEFAULT : 기본 action
GADGET : 다른 activity 안에 embedded 되어 동작
HOME : 디바이스가 시작할 때 동작하는 첫번째 activity
LAUNCHER : application launcher에 나타남
data : 컴포넌트가 다루는 데이터 지정
android:host - 유효한 host name (예, com.google)
android:mimetype - 컴포넌트가 다루는 데이터 형태 지정 (예, <type android:value="vnd.android.cursor.dir/*"/>
android:path - URI의 유효한 경로 (예, /transport/boats/)
android:port - host에 대한 유효한 포트
android:scheme - 특정 schemem (예, content, http)
- <activity android:name=”.EarthquakeDamageViewer”
android:label=”View Damage”>
<intent-filter>
<action
android:name=”com.paad.earthquake.intent.action.SHOW_DAMAGE”>
</action>
<category android:name=”android.intent.category.DEFAULT”/>
<category
android:name=”android.intent.category.ALTERNATIVE_SELECTED”
/>
<data android:mimeType=”vnd.earthquake.cursor.item/*”/>
</intent-filter>
</activity>
How Android Resolves Intent Filters
Intent resolution : 어떤 Activity가 실행될 지 결정하는 과정
- 모든 Intent Filters의 리스트를 만듦
- action이나 category를 만족하지 못하는 Intent Filters 제거
- Intent의 데이터 URI와 Intent Filter의 data 태그 비교
- 위 과정으로 하나 이상의 component가 선택되면, Intent Fileter 노드에 추가될 수 있는 추가 태그로 우선 순위 결정
Native Android 어플리케이션과 third-party 어플리케이션 사이에 Intent resolution 과정의 동일하다.
Responding to Intent Filter Matches
Implicit Intent로 어플리케이션이 시작되면 getIntent, getAction, getData 메소드를 이용해서 Intent와 Action, Data를 설정한다.
- @Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
setContentView(R.layout.main);
Intent intent = getIntent();
}
- String action = intent.getAction();
Uri data = intent.getData();
Passing on Responsibility
startNextMatchingActivity 메소드를 이용해서 action handling을 차선 어플리케이션으로 넘길 수 있다.
- Intent intent = getIntent();
if (isAfterMidnight)
startNextMatchingActivity(intent);
Select a Contact Example
contact data에 대한 PICK_ACTION을 서비스하는 sub-Activity 생성
contact database에 있는 contacts를 보여줌
사용자가 하나를 선택하면, 자신을 부른 Activity에 해당 URI를 전달하고 종료
1.3. Using Intent Filters for Plug-ins and Extensibility 130
Intent Filters를 사용해서 실행중에 메뉴를 동적으로 변화시키는 것
프로젝트를 수정하거나 재컴파일하지 않고, 새로운 기능 추가 가능
Supplying Anonymous Actions to Applications
manifest 노드에 intent-filter 태그를 사용해서 다른 Activity에 의해 action이 수행 가능하게 지정
-
<activity android:name=”.NostromoController”>
<intent-filter android:label=”Nuke From Orbit”>
<action android:name=”com.pad.nostromo.NUKE_FROM_ORBIT”/>
<data android:mimeType=”vnd.moonbase.cursor.item/*”/>
<category android:name=”android.intent.category.ALTERNATIVE”/>
<category
android:name=”android.intent.category.SELECTED_ALTERNATIVE”
/>
</intent-filter>
</activity>
Incorporating Anonymous Actions in Your Activity's Menu
onCreateOptionsMenu 나 onCreateContextMenu 핸들러에서 처리
menu-action을 처리하기 위한 Intent 생성 방법
- Intent intent = new Intent();
intent.setData(MyProvider.CONTENT_URI);
intent.addCategory(Intent.CATEGORY_ALTERNATIVE);
Intent를 addIntentOptions로 전달해서 동적으로 메뉴 생성 가능
- // Populate the menu
menu.addIntentOptions(menuGroup,
menuItemId,
menuItemOrder,
caller,
specificIntents,
intent,
flags,
outSpecificItems);
1.4. Using Intents to Broadcast Events
Intents를 통해 구조적인 메시지를 프로세스 사이에 전달할 수 있음
sendBroadcast : components 사이에 메시지를 방송하는 방법
Broadcast Intents : 시스템 리스너, 어플리케이션 이벤트, 어플리케이션 간의 이벤트 기반 프로그래밍에 사용
예 : 수신 콜, 배터리 충전 량, 네트워크 연결 등
Broadcasting Events with Intents
Intent 구성 후 sendBroadcast 메소드를 이용하여 발송
action, data, category 정의
action : 이벤트를 구별하는 이름, 고유한 문자열 지정, Java package 형태 추천
- public static final String NEW_LIFEFORM_DETECTED =
“com.paad.action.NEW_LIFEFORM”; - Intent intent = new Intent(NEW_LIFEFORM_DETECTED);
intent.putExtra(“lifeformName”, lifeformType);
intent.putExtra(“longitude”, currentLongitude);
intent.putExtra(“latitude”, currentLatitude);
sendBroadcast(intent);
Listening for Broadcasts with Broadcast Receivers
Broadcaster Receiver를 사용하려면 등록 (코드 또는 manifest) 이 필요
등록할 때 청취할 Intent Filter 지정
BroadcastReceiver 클래스를 extends해서 onReceive 이벤트 핸들러 구현
onReceive 핸들러는 5초안에 종료되야 함 -> Application Unresponsive 다이얼로그
- public class LifeformDetectedBroadcastReceiver extends BroadcastReceiver {
public static final String BURN =
“com.paad.alien.action.BURN_IT_WITH_FIRE”;
@Override
public void onReceive(Context context, Intent intent) {
// Get the lifeform details from the intent.
Uri data = intent.getData();
String type = intent.getStringExtra(“type”);
double lat = intent.getDoubleExtra(“latitude”, 0);
double lng = intent.getDoubleExtra(“longitude”, 0);
Location loc = new Location(“gps”);
loc.setLatitude(lat);
loc.setLongitude(lng);
if (type.equals(“alien”)) {
Intent startIntent = new Intent(BURN, data);
startIntent.putExtra(“latitude”, lat);
startIntent.putExtra(“longitude”, lng);
context.startActivity(startIntent);
}
}
}
Registering Broadcast Receivers in Your Application Manifest
- <receiver android:name=”.LifeformDetectedBroadcastReceiver”>
<intent-filter>
<action android:name=”com.paad.action.NEW_LIFEFORM”/>
</intent-filter>
</receiver>
Registering Broadcast Receivers in Code
register Broadcast Receiver
- // Create and register the broadcast receiver.
IntentFilter filter = new IntentFilter(NEW_LIFEFORM_DETECTED);
LifeformDetectedBroadcastReceiver r = new LifeformDetectedBroadcastReceiver();
registerReceiver(r, filter);
unregister Broadcast Receiver
- unregisterReceiver(r);
Native Android Broadcast Actions
ACTION_BOOT_COMPLETED, ACTION_CAMERA_BUTTON, ACTION_DATE_CHANGED, ACTION_TIME_CHANGED, ACTION_GTALK_SERVICE_CONNECTED, ACTION_GTALK_SERVICE_DISCONNECTED, ACTION_MEDIA_BUTTON, ACTION_MEDIA_EJECT, ACTION_MEDIA_MOUNTED, ACTION_MEDIA_UNMOUNTED, ACTION_SCREEN_OFF, ACTION_SCREEN_ON, ACTION_TIMEZONE_CHANGED
자세한 것은 http://developer.android.com/reference/android/content/Intent.html 참조
2. Introducing Adapters
Adapter란? 데이터를 view에 바인딩하는 class.
아무 view나 adapter로 바인딩할수 있는 것은 아니고, adapter에 의해 바인딩되는 view(adapter view라고 함)는 AdapterView라는 abstract class를 extend 해야 한다.
2.1. Introducing Some Android-Supplied Adapters
Android가 기본적으로 제공하는 adapter(native adapter라고 함) 중 가장 유용한 2가지 adapter
- ArrayAdapter = 디폴트로 각 오브젝트의 toString 값을 layout내의 TextView와 바인딩.
- SimpleCursorAdapter = Content Provider query를 통해 리턴된 cursor와 View를 바인딩. 자세한 것은 6장에서 ...
2.2. Using Adapters for Data Binding
- ArrayList<String> myStringArray = new ArrayList<String>();
ArrayAdapter<String> myAdapterInstance;
int layoutID = android.R.layout.simple_list_item_1;
myAdapterInstance = new ArrayAdapter<String>(this, layoutID,myStringArray);
myListView.setAdapter(myAdapterInstance);
(1) ArrayAdapter 커스터마이징 실습 - To-Do List, 4장에서 실습한 ToDoList 프로젝트가 있어야 한다.
- ToDoItem 클래스를 만든다. (2개의 getter - getTask(), getCreated(), override toString() 메소드)
- ToDoList activity 클래스를 고친다. (ArrayAdapter<String>을 ArrayAdapter<ToDoItem>으로)
- 실행시켜 본다.
- todolist_item.xml을 고친다. (2개의 TextView를 좌우로 배치)
- ToDoItemAdapter 클래스를 만든다. (extends ArrayAdapter<ToDoItem>, override getView 메소드)
-
ToDoList activity 클래스를 고친다. (ArrayAdapter를 ToDoItemAdapter로 바꾼다.)
(2) SimpleCursorAdapter 사례
- 일단 ContactPicker 예제를 보세요. ContactPicker.java
- Content Provider와 Cursor에 대한 설명 및 SimpleCursorAdapter에 대한 더 많은 사례는 6장에서 ...
3. Using Internet Resources
Android에는 web browser가 이미 있는데, 굳이 왜 internet resource를 다른 어플리케이션에서 접근해야할까?
- Bandwidth를 덜 쓰려고,
- 모바일 인터넷은 잘 끊기니까 Caching해서 쓰려고,
- LBS나 카메라 등 Android에서 제공하는 기능을 결합하려고.
3.1. Connecting to an Internet Resource
Internet resource 접근하기 전에 우선 AdroidManifest.xml 파일에다가 하기 내용을 추가
- <uses-permission android:name=”android.permission.INTERNET”/>
Internet 데이터 스트림을 여는 일반적인 패턴은 ..
- String myFeed = getString(R.string.my_feed);
try {
URL url = new URL(myFeed);
URLConnection connection = url.openConnection();
HttpURLConnection httpConnection = (HttpURLConnection)connection;
int responseCode = httpConnection.getResponseCode();
if (responseCode == HttpURLConnection.HTTP_OK) {
InputStream in = httpConnection.getInputStream(); -
// 여기에 input stream 을 프로세싱하는 코드를 넣는다.
}
- }
- catch (MalformedURLException e) { }
catch (IOException e) { }
- Earthquake 어플리케이션을 보세요.
- 9장, 10장에서 자세히 ...
3.2. Leveraging Internet Resources
- WebView widget - 브라우저를 activity 안에 넣을수 있다. 매우 high-level에서 제어
- GData API - 서버 프로세스와 직접 통신. 매우 low-level에서 제어
- javax - XML 데이터를 parsing하여 활용하는 방법. middle-level에서 제어. Earthquake 어플리케이션이 바로 이 방법
4. Introducing Dialogs 143
Dialogs 란?
Doalog box(대화상자)는 사용자에게 질의 및 대답을 하게 하고, 선택, 동작의 확인, 경고와 오류메시지를 읽게하는데 사용되는 기본적인 UI 이다.
Dialog 구현 방법
Dialog 클래스계열을 사용 - 범용적인 대화상자로 사용되는 AlertDialog등 Dialog를 확장하여 특정용도로 특화시킨 Dialog들을 사용
Dialog-Themed Activities - 일반적인 Activity에 Dialog Theme을 적용하여, 대화상자(떠다니는 윈도우)로 표시할 수 있다.
Toast - Toast는 modaless 메시지 상자로, Broadcast Receiver와 백그라운드 서비스 등에서 사용자에게 이벤트를 통지하기 위해 사용된다. 8장 참조.
4.1. Introducing the Dialog Class 144
-
Doalog 클래스는 단순한 대화상자를 구현한다. 일반적인 대화상자의 기능구현을 위해서는 AlertDialog를 사용할 수 있다.
-
DatePickerDialog, TimePickerDialog, ProgressDialog 등의 대화상자가 미리 제공된다.
-
Dialog를 상속하는 경우 OnCreateDialog와 OnPrepareDialog를 오버라이드 하여 필요한 기능을 구현한다.
4.2. Using Activities as Dialogs 147
Dialog는 가볍게 화면에 표시하는 기능을 제공한다. 하지만, Activity를 Dialog처럼 사용할 수도 있다. Activity 정의시 android:style/Theme.Dialog로 스타일을 적용해주면된다.
5. Creating an Earthquake Viewer 148
예제 참조
6. Summary
Intent - 어플리케이션에 대한 메시징 시스템
Broadcast Intent
sub-Activity
Adapter
Dialog
History
Last edited on 03/26/2009 00:09 by 네피림
Comments (0)