ContactPicker

프로페셔널 안드로이드2 애플리케이션 개발 5장의 ContactPicker

인텐트를 이용한 액티비티간 데이터 전송 예제

연락처 데이터 베이스에서 각각의 연락처를 표시하는 “contactpicker”와

이를 호출하는 “contactpickerTester” 두 개의 액티비티 클래스로 구성 된다.

“contactpickerTester” 뷰에 “연락처 선택”버튼이 있어 이 버튼을 누루면

“contactpicker” 액티비티로 전환되고 연락처가 표시 된다.

연락처를 선택하면 선택된 연락처의 URI를 리턴하고 “contactpickerTester”에서 받아

표시하는 간단한 인텐트 필터 예제 프로그램.

ContactPicker.java
[java]
package com.paad.contactpicker;

import android.app.Activity;
import android.content.Intent;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.provider.Contacts.People;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ListView;
import android.widget.SimpleCursorAdapter;
import android.widget.AdapterView.OnItemClickListener;

public class ContactPicker extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
setContentView(R.layout.main);

Intent intent = getIntent();
String dataPath =intent.getData().toString();

final Uri data = Uri.parse(dataPath + “people/”);
final Cursor c = managedQuery(data, null, null, null, null);

String[] from = new String[] {People.NAME};
int[] to = new int[] {R.id.itemTextView };

SimpleCursorAdapter adapter = new SimpleCursorAdapter(this,
R.layout.listitemlayout,
c,
from,
to);
ListView lv = (ListView)findViewById(R.id.contactListView);
lv.setAdapter(adapter);

lv.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView parent, View view, int pos,
long id) {
// 선택된 아이템으로 커서 이동
c.moveToPosition(pos);
int rowId = c.getInt(c.getColumnIndexOrThrow(“_id”)); //row ID
Uri outURI = Uri.parse(data.toString() + rowId); // result URI
Intent outData = new Intent();
outData.setData(outURI);
setResult(Activity.RESULT_OK, outData);
finish();
}
});
}
}
[/java]

ContactPickerTester.java
[java]
package com.paad.contactpicker;

import android.app.Activity;
import android.content.Intent;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.provider.Contacts.People;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;

public class ContactPickerTester extends Activity{

public static final int PICK_CONTACT = 1;

@Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
setContentView(R.layout.contactpickertester);

Button button = (Button)findViewById(R.id.pick_contact_button);

button.setOnClickListener( new OnClickListener() {
@Override
public void onClick(View _view) {
Intent intent = new Intent(Intent.ACTION_PICK,
Uri.parse(“content://contacts/”));
startActivityForResult(intent, PICK_CONTACT);
}

});
}

@Override
public void onActivityResult(int reqCode, int resCode, Intent data) {
super.onActivityResult(reqCode, resCode, data);

switch(reqCode) {
case(PICK_CONTACT):{
if(resCode == Activity.RESULT_OK) {
Uri contactDatat = data.getData();
Cursor c = managedQuery(contactDatat, null, null, null, null);
c.moveToFirst();
String name = c.getString(c.getColumnIndexOrThrow(People.NAME));
TextView tv = (TextView)findViewById(R.id.selected_contact_textview);
tv.setText(name);
}
break;
}
}
}

}
[/java]

contactpickertester.xml
[xml]

[/xml]

listitemlayout.xml
[xml]

[/xml]

main.xml
[xml]

[/xml]
contactpicker 엑티비티

select

contactpickerTester 액티비티

selected

contactpicker

To Do List – Ch4

프로페셔널 안드로이드2 애플리케이션 개발 4장의 To Do List

To Do List application에 ContextMenu 와 OptionsMenu 추가

ContextMenu는 할 일 목록 길게 누르는 경우 나오는 메뉴로 “목록 삭제 “기능 추가

OptionsMenu는 메뉴키를 눌렀을 때 하단에 나오는 메뉴로 “추가” 와 “취소” 기능 추가

한단 OptionsMenu는 목록의 구성에 따라 취소가 삭제 또는 나타나지 않을 수 있음.

ToDoList.java
[java]
package com.paad.todolist;

import java.util.ArrayList;
import android.app.Activity;
import android.os.Bundle;
import android.view.ContextMenu;
import android.view.KeyEvent;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnKeyListener;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.EditText;
import android.widget.ListView;

public class ToDoList extends Activity {
private ArrayList todoItems;
private ListView myListView;
private EditText myEditText;
private ArrayAdapter aa;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);

setContentView(R.layout.main);

myListView = (ListView)findViewById(R.id.myListView);
myEditText = (EditText)findViewById(R.id.myEditText);
todoItems = new ArrayList();

int resID = R.layout.todolist_item;
aa = new ArrayAdapter(this, resID /*android.R.layout.simple_list_item_1*/, todoItems);
myListView.setAdapter(aa);

myEditText.setOnKeyListener(new OnKeyListener(){
public boolean onKey(View v, int keyCode, KeyEvent event) {
if(event.getAction() == KeyEvent.ACTION_DOWN)
if(keyCode == KeyEvent.KEYCODE_DPAD_CENTER){
todoItems.add(0, myEditText.getText().toString());
myEditText.setText(“”);
aa.notifyDataSetChanged();
cancelAdd();
return true;
}
return false;
}
});
registerForContextMenu(myListView);
}
static final private int ADD_NEW_TODO = Menu.FIRST;
static final private int REMOVE_TODO = Menu.FIRST + 1;

@Override
public void onCreateContextMenu(ContextMenu menu,
View v,
ContextMenu.ContextMenuInfo menuInfo) {
super.onCreateContextMenu(menu, v, menuInfo);
menu.setHeaderTitle(“할 일 아이템 선택”);
menu.add(0, REMOVE_TODO, Menu.NONE, R.string.remove);
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
super.onCreateOptionsMenu(menu);
// 새 메뉴 아이템을 만들어 추가
MenuItem itemAdd = menu.add(0, ADD_NEW_TODO, Menu.NONE,
R.string.add_new);
MenuItem itemRem = menu.add(0, REMOVE_TODO, Menu.NONE,
R.string.remove);
// 아이콘 할당
itemAdd.setIcon(R.drawable.add);
itemRem.setIcon(R.drawable.del);
// 단축키 할당
itemAdd.setShortcut(‘0’, ‘a’);
itemRem.setShortcut(‘1’, ‘r’);
return true;
}

private boolean addingNew = false;

@Override
public boolean onPrepareOptionsMenu(Menu menu) {
super.onPrepareOptionsMenu(menu);

int idx = myListView.getSelectedItemPosition();
String removeTitle = getString(addingNew ?
R.string.cancel : R.string.remove);
MenuItem removeItem = menu.findItem(REMOVE_TODO);
removeItem.setTitle(removeTitle);
removeItem.setVisible(addingNew || idx > -1);
return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
super.onOptionsItemSelected(item);

int index = myListView.getSelectedItemPosition();

switch(item.getItemId()){
case(REMOVE_TODO): {
if(addingNew) {
cancelAdd();
}else {
removeItem(index);
}
return true;
}
case(ADD_NEW_TODO): {
addNewItem();
return true;
}
}
return false;
}

@Override
public boolean onContextItemSelected(MenuItem item) {
super.onContextItemSelected(item);

switch(item.getItemId()) {
case(REMOVE_TODO): {
AdapterView.AdapterContextMenuInfo menuInfo;
menuInfo = (AdapterView.AdapterContextMenuInfo)item.getMenuInfo();
int index = menuInfo.position;

removeItem(index);
return true;
}
}
return false;
}

private void addNewItem() {
addingNew = true;
myEditText.setVisibility(View.VISIBLE);
myEditText.requestFocus();
}

private void cancelAdd() {
addingNew = false;
myEditText.setVisibility(View.GONE);
}
private void removeItem(int index) {
todoItems.remove(index);
aa.notifyDataSetChanged();
}
}

[/java]

todo_list

todolist

Compass – Ch4

프로페셔널 안드로이드2 애플리케이션 개발 4장의 Compass (나침판)

실제 센서에서 값을 가지고 오지 않고 고정된 값을 사용하여 뷰만 그려준다.

src/com/paad/compass/CompassView.java
[java]
package com.paad.compass;

import android.content.Context;
import android.content.res.Resources;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.view.View;
public class CompassView extends View{
public CompassView(Context context) {
super(context);
initCompassView();
}
public CompassView(Context context, AttributeSet attrs) {
super(context, attrs);
initCompassView();
}
public CompassView(Context context,
AttributeSet ats,
int defaultStyle) {
super(context, ats, defaultStyle);
initCompassView();
}
private Paint markerPaint;
private Paint textPaint;
private Paint circlePaint;
private String northString;
private String eastString;
private String southString;
private String westString;
private int textHeight;

protected void initCompassView() {
setFocusable(true);

Resources r = this.getResources();
circlePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
circlePaint.setColor(r.getColor(R.color.background_color));
circlePaint.setStrokeWidth(1);
circlePaint.setStyle(Paint.Style.FILL_AND_STROKE);

northString = r.getString(R.string.cardinal_north);
eastString = r.getString(R.string.cardinal_east);
southString = r.getString(R.string.cardinal_south);
westString = r.getString(R.string.cardinal_west);

textPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
textPaint.setColor(r.getColor(R.color.text_color));

textHeight = (int)textPaint.measureText(“yY”);

markerPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
markerPaint.setColor(r.getColor(R.color.marker_color));
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec){
int measuredWidth = measure(widthMeasureSpec);
int measuredHeigh = measure(heightMeasureSpec);
int d = Math.min(measuredWidth, measuredHeigh);
setMeasuredDimension(d,d); // 뷰의 크기를 높이와 폭 중 작은 값으로 설정
}
private int measure(int measureSpec) {
int result = 0;
int specMode = MeasureSpec.getMode(measureSpec);
int specSize = MeasureSpec.getSize(measureSpec);

if(specMode == MeasureSpec.UNSPECIFIED) {
result = 200; // 경계가 지정되지 않은 경우 200
}else {
result = specSize; // 영역 전부를 사용
}
return result;
}
private float bearing;
public void setBearing(float _bearing) {
bearing = _bearing;
}
public float getBearing() {
return bearing;
}
@Override
protected void onDraw(Canvas canvas){
int px = getMeasuredWidth() / 2;
int py = getMeasuredHeight() / 2;
int radius = Math.min(px, py);

canvas.drawCircle(px, py, radius, circlePaint);
canvas.save();
canvas.rotate(-bearing, px, py);

int textWidth = (int)textPaint.measureText(“W”);
int cardinalX = px – textWidth/2;
int cardinalY = py – radius+textHeight;

for (int i = 0; i< 24; i++) {
canvas.drawLine(px, py-radius, px, py-radius+10, markerPaint);
canvas.save();
canvas.translate(0, textHeight);
if(i%6 == 0) {
String dirString = "";
switch(i) {
case(0) : {
dirString = northString;
int arrowY = 2*textHeight;
canvas.drawLine(px, arrowY, px-5, 3*textHeight,markerPaint);
canvas.drawLine(px, arrowY, px+5, 3*textHeight, markerPaint);
break;
}
case(6) : dirString = eastString; break;
case(12) : dirString = southString; break;
case(18) : dirString = westString; break;
}
canvas.drawText(dirString, cardinalX, cardinalY, textPaint);
}
else if(i%3 == 0) {
String angle = String.valueOf(i*15);
float angleTextWidth = textPaint.measureText(angle);
int angleTextX = (int)(px-angleTextWidth/2);
int angleTextY = py-radius+textHeight;
canvas.drawText(angle, angleTextX, angleTextY, textPaint);
}
canvas.restore();
canvas.rotate(15, px, py);
}
canvas.restore();
}
}

[/java]

src/com/paad/compass/Compass.java
[java]
package com.paad.compass;

import android.app.Activity;
import android.os.Bundle;

public class Compass extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);

setContentView(R.layout.main);
CompassView cv = (CompassView)this.findViewById(R.id.compassView);
cv.setBearing(45);
/*
CompassView cv = new CompassView(this);
setContentView(cv);
cv.setBearing(45);
*/

}
}
[/java]

res/layout/main.xml
[xml]

[/xml]

res/values/color.xml
[xml]

#F555
#AFFF
#AFFF

[/xml]

res/values/strings.xml
[xml]

Compass
N
E
W
S

[/xml]

compass

compass

TodoList -Ch4

프로페셔널 안드로이드2 애플리케이션 개발 4장의 ToDoList

ListView는 ArrayAdapter를 사용하여 ListView내의 TextView resouce ID 값을 설정한다.

2장에서는 resourceID를 android.R.layout.simple_list_item_1를 사용하였다.

4장에서는 새로운 TextVIew를 만들어 android.R.layout.simple_list_item_1 대신

R.layout.todolist_item를 사용한다.

[java]

final ArrayAdapter<String> aa;

int resID = R.layout.todolist_item;

aa = new ArrayAdapter<String>(this, resID /*android.R.layout.simple_list_item_1*/, todoItems);

myListView.setAdapter(aa);

[/java]

R.layout.todolist_item 리소스는 xml를 사용하여 다음과 같이 추가해 준다.

todolist_item.xml

[xml]

<?xml version=”1.0″ encoding=”utf-8″?>

<com.paad.todolist.TodoListItemView

xmlns:android=”http://schemas.android.com/apk/res/android&#8221;

android:layout_width=”fill_parent”

android:layout_height=”fill_parent”

android:padding=”10dp”

android:scrollbars=”vertical”

android:textColor=”@color/notepad_text”

android:fadingEdge=”vertical”

/>

[/xml]

그리고 com.paad.todolist.TodoListItemView 클래스를 추가 한다.  TodoListItemView 클래스는 TextView로 부터 확장(extends) 되었으며  onDraw함수에서 새로 TextView를 그린다.

TodoListItemView.java

[java]
package com.paad.todolist;

import android.content.Context;
import android.content.res.Resources;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.widget.TextView;

public class TodoListItemView extends TextView {

private Paint marginPaint;
private Paint linePaint;
private int paperColor;
private float margin;

public TodoListItemView(Context context, AttributeSet ats, int ds) {
super(context);
init();
}

public TodoListItemView(Context context) {
super(context);
init();
}

public TodoListItemView(Context context, AttributeSet attrs) {
super(context);
init();
}

private void init() {
// 리소스 테이블의 레퍼런스를 언어온다.
Resources myResources = getResources();

// onDraw 메서드에서 사용할 페인트 브러시들을 만든다.
marginPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
marginPaint.setColor(myResources.getColor(R.color.notepad_margin));
linePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
linePaint.setColor(myResources.getColor(R.color.notepad_lines));

// 종이의 배경 색상과 여백 폭을 얻어온다.
paperColor = myResources.getColor(R.color.notepad_paper);
margin = myResources.getDimension(R.dimen.notepad_margin);
}

@Override
public void onDraw(Canvas canvas){
// 종이의 배경 생상으로 칠한다.
canvas.drawColor(paperColor);

// 쾌선을 그린다.
canvas.drawLine(0,0,0, getMeasuredHeight(), linePaint);
canvas.drawLine(0, getMeasuredHeight(),
getMeasuredWidth(), getMeasuredHeight(),
linePaint);

// 여백을 그린다.
canvas.drawLine(margin, 0, margin, getMeasuredHeight(), marginPaint);

// 텍스트를 여백 맞은편으로 이동시킨다.
canvas.save();
canvas.translate(margin,0);

// TextView를 이용해 테스트를 렌더링한다.
super.onDraw(canvas);
canvas.restore();
}
}

[/java]

다음은 실행 화면이다. ListView 내의 TextView 내용이 변경된 것을 볼 수 있다.

todo_4

todo_list_ch4

ToDoList

프로페셔널 안드로이드2 애플리케이션 개발 2장의 ToDoList

EditText에 문자열 입력하고 키패드의 가운데 버튼을 누르면 ListView에 추가 된다.

todo_list

todo_list.zip

main.xml

[xml]

[/xml]

ToDoList.java
[java]
package com.paad.todolist;

import java.util.ArrayList;
import android.app.Activity;
import android.os.Bundle;
import android.view.KeyEvent;
import android.view.View;
import android.view.View.OnKeyListener;
import android.widget.ArrayAdapter;
import android.widget.EditText;
import android.widget.ListView;

public class ToDoList extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);

ListView myListView = (ListView)findViewById(R.id.myListView);
final EditText myEditText = (EditText)findViewById(R.id.myEditText);

final ArrayList todoItems = new ArrayList();

final ArrayAdapter aa;
aa = new ArrayAdapter(this, android.R.layout.simple_list_item_1, todoItems);
myListView.setAdapter(aa);

myEditText.setOnKeyListener(new OnKeyListener(){
public boolean onKey(View v, int keyCode, KeyEvent event) {
if(event.getAction() == KeyEvent.ACTION_DOWN)
if(keyCode == KeyEvent.KEYCODE_DPAD_CENTER){
todoItems.add(0, myEditText.getText().toString());
aa.notifyDataSetChanged();
myEditText.setText(“”);
return true;
}
return false;
}
});
}
}
[/java]