http://th30z.netsons.org/2008/08/123/
doxygen 변환 툴 Programming 2010.08.29 14:26
1. doxygen 다운로드 후 설치

2. 아래와 같이 설정

3. Run 탭에서 Run Doxygen 버튼 투른후 Show HTML 클릭하면 페이지로 이동한다.

If you are running Ubuntu, it is strongly suggested to use a package manager like aptitude or synaptic to download and install packages, instead of doing so manually via this website.

You should be able to use any of the listed mirrors by adding a line to your /etc/apt/sources.list like this:

deb http://cz.archive.ubuntu.com/ubuntu intrepid main 
synaptic 에서 hotkey-setup package 설치

t’s that special time of year again! I have just finished upgrading my trusty ThinkPad T61 to the latest version of Ubuntu Linux — 10.04 Lucid Lynx. This edition of the operating system no longer employs the udev method of emulating scrolling. With the following instructions, one will be able to scroll with the middle button both vertically and horizontally:

Step 1. Create a new file

sudo vi /usr/lib/X11/xorg.conf.d/20-thinkpad.conf

Step 2. Insert the following

Section "InputClass"
Identifier "Trackpoint Wheel Emulation"
MatchProduct "TPPS/2 IBM TrackPoint|DualPoint Stick|Synaptics Inc. Composite TouchPad / TrackPoint"
MatchDevicePath "/dev/input/event*"
Option "EmulateWheel" "true"
Option "EmulateWheelButton" "2"
Option "Emulate3Buttons" "false"
Option "XAxisMapping" "6 7"
Option "YAxisMapping" "4 5"
EndSection

Step 3. Save file, restart computer, and enjoy!

Please comment and let me know whether this solution worked for you, or if you have alternative methods.

By the way, I’m not able to get the fingerprint reader working. Has anyone had any luck with it? Any tips to share?

  1    2    3    4    5    6   -   1    2     3   4     5     6      7   (주민등록번호)
  2    3    4    5    6    7       8    9     2    3     4     5          (승수)
 n1  n2   n3  n4  n5  n6      n7  n8   n9  n10  n11  n12

각 자릿수에 지정된 승수를 더한 값을 N 이라고 하면,

N = n1 + n2 + n3 + ... +n12

N을 11로 나눈 나머지를 11에서 뺀 수가 주민등록번호 마지막 자릿수와 일치하면
정상적인 주민등록번호이다.

11 - (N%11) = 마지막 자릿수

N의 값이 11로 나누어 떨어지거나 나머지가 1이라면 위 식의 값을 10 또는 11이 된다.
마지막 자릿수는 1자리이기 때문에 이런 경우에는 비교할때 같이 않은 것으로
처리되기 때문에 위 식을 다시 한번 10으로 나누어 그 나머지를 취하여
마지막 자릿수와 비교해야한다. 

(11 - (N%11)) % 10  = 마지막 자릿수
- Focus

View.dispatchKeyEvent() : focus를 붙잡아서 처리할수 있다.

UI 이벤트 발생
-> Activity(dispatch~로 시작되는 method 호출)
-> View(호출)
-> Activity(on~로 시작되는 method 호출)

Android에서는 기본적으로 Focus 처리를 합리적으로 처리되게끔
되어 있으나, Focus 처리를 바꾸고 싶다면, 아래 XML속성으로 쉽게
변경할수 있다.
(nextFocusLeft, nextFocusRight, nextFocusUp, nextFocusDown)
ex)
<LinearLayout android:orientation="vertical" ... >
<Button android:id="@+id/top" android:nextFocusUp="@+id/bottom" ... />
<Button android:id="@+id/bottom" android:nextFocusDown="@+id/top" ... />
</LinearLayout>

View.requestFocus() ( = setFocus() ) 강제 포커스

<Intent>
대상이 명확할때는 intent filter가 필요없다(Explicit intent)
대상이 명확하지 않을때는 intent filter가 필요함(Implicit intent)

<Notification>
- Toast
- Status bar notification(맨위에 Title bar)
주로 Service(화면에 보이지 않는)에서 사용됨.

1. Get a reference to the NotificationManager.
String ns = Context.NOTIFICATION_SERVICE;
NotificationManager mNotificationManager =(NotificationManager)getSystemService(ns);

2.  Instantiate the Notification.
int icon = R.drawable.notification_icon;      // icon
CharSequence tickerText = "Hello";           // text
long when = System.currentTimeMillis();   // msg 발생 시간
Notification notification = new Notification(icon, tickerText, when);
notification.flags |= notification.FLAG_AUTO_CANCEL; <= 확인하면 위에
아이콘이 자동으로 사라짐!!!!

3. Define the Notification's expanded message and Intent.(이벤츠를 펼칠때)
Context context = getApplicationContext();
CharSequence contentTitle = "My notification";
CharSequence contentText = "Hello World!";
Intent notificationIntent = new Intent(this, MyClass.class);
PendingIntent contentIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0);
notification.setLatestEventInfo(context, contentTitle, contentText, contentIntent);

4 Pass the Notification to the NotificationManager.
private static final int HELLO_ID = 1;
mNotificationManager.notify(HELLO_ID, notification);

- Dialog notification

<AdapterView>

배열을 resource로 만들기.
contact의 데이터를 접근하려면 permission이 필요하다.
AndroidManifest.xml에서 uses-permission(android.permission.READ_CONTACTS)
을 추가한다.


Adapter는 데이터만이 아닌 +@(항목에 사용될 View)도 설정이 가능하다.
- ArrayAdapter : 배열 객체
ex)
Spinner s1 = (Spinner)findViewById(R.id.spinner1);
ArrayAdapter<?> adapter = ArrayAdapter.createFromResource(
this, R.array.colors, android.R.layout.simple_spinner_item);
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
s1.setAdapter(adapter);
final String[] arr = getResources().getStringArray(R.array.colors); 
s1.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> parent, View view,
int position, long id) {
Toast.makeText(SpinnerTest.this, arr[position] + " 선택됨",
Toast.LENGTH_SHORT).show();
}
@Override
public void onNothingSelected(AdapterView<?> parent) {
}
});

resource data를 code level에서 접근하기
final String[] arr = getResources().getStringArray(R.array.colors);  

- SimpleCursorAdapter : database 데이터(Content Provider)
ex)
String[] PROJECTION = new String[] { People._ID, People.NAME };
Spinner s2 = (Spinner) findViewById(R.id.Spinner02);
Cursor cur = managedQuery(People.CONTENT_URI, PROJECTION, null, null, null);
SimpleCursorAdapter adapter2 = new SimpleCursorAdapter(this,
android.R.layout.simple_spinner_item, cur,
new String[] { People.NAME }, new int[] { android.R.id.text1 });
adapter2.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
s2.setAdapter(adapter2);

Contect Provider에 접근할때 URI로써 접근한다.
Avtivity.managedQuery() 통해서 가져옴.(Cursor 리턴)
항목선택에대한 처리는 AdapterView에서 처리한다.

<Data Storage>
각 응용프로그램의 데이터는 공유되지 않는다.
(단. Content provider를 통해서 접근 가능하다.)

- Preferences

 어플리케이션 데이터를 간단하게 저장(XML로저장된 파일)
DDMS-File Exporer-data-data-package 이름-shared_prefs 에 파일 존재함.

ex)
@Override protected void onPause() {
super.onPause();
// SharedPreferences setting =getPreferences(MODE_PRIVATE);
SharedPreferences setting = getSharedPreferences("mysetting", MODE_PRIVATE);
Editor editor = setting.edit();
editor.putString("mytext", edit.getText().toString());
editor.commit();
}

@Override protected void onResume() {
super.onResume();
// SharedPreferences setting =getPreferences(MODE_PRIVATE);
SharedPreferences setting = getSharedPreferences("mysetting", MODE_PRIVATE);
edit.setText(setting.getString("mytext", ""));
}

getPreferences() : 같은 응용프로그램내에서 다른 Activiry 접근 불가능.
getSharedPreferences() : 내응용프로그램내의 다른 Avtivity 들 간의 데이터 접근.

MODE_PRIVATE : 나혼자 사용하겠음. (-rw-rw---) 소유자:그룹:기타
MODE_WORLD_READABLE : 공유할수는 있지만 파일의 위치를 알아야하므로 비추

edit() 과 commit() 사이에 저장한다.

settings값들을 저장하기에 적합하다.

- Files
ex)
FileOutputStream out = null;
FileInputStream in = null;

try {
if (v == btnWrite) {
try {
out = openFileOutput("mydata.txt", MODE_PRIVATE);
out.write(text.getText().toString().getBytes());
}
catch (IOException e) {
e.printStackTrace();
}
}
else if (v == btnRead) {
try {
in = openFileInput("mydata.txt");
text.setText("");
final int length = 256;
byte[] buf = new byte[length];
int n;
String str;
while ((n = in.read(buf, 0, length)) != -1) {
str = new String(buf, 0, n);
text.append(str);
}
}
catch (IOException e) {
e.printStackTrace();
}
}
}
finally {
try {
if (out != null)
out.close();
if (in != null)
in.close();
}
catch (IOException e) {
e.printStackTrace();
}
}

openFileOutput() openFileInput() , 이름에는 Path sperator는 추가될수 없다.
(즉 "/sdcard/mytext.txt" 로 파일을 열수 없다.) 
아래와 같이 FileOutputStream constructor로서 path를 포함하여 파일을 열수 있다.
ex)
out = new FileOutputStream("/sdcard/mydata.txt");
in = new FileInputStream("/sdcard/mydata.txt");
(Java에서는 permission 개념이 없으므로 위의 Java class로 파일을 오픈하면,
 권한이 rw로 되어 있다.)

- Databases

SQLite3 명령어 : 따로 공부 필요함.
.schema : 테이블의 상태를 알수 있음.
.databases : 모든 테이블 보여줌
...

데이터베이스를 사용하고 싶다면.
1. SQLiteOpenHelper을 subclass 해서 몇가지 Method를 재정의한다.
ex)
private static class MyDatabaseHelper extends SQLiteOpenHelper {

@Override
public void onCreate(SQLiteDatabase db) {
// TODO Auto-generated method stub
//DB 생성시
}

@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
// TODO Auto-generated method stub
//DB 업데이트시 수정 작업을 도와줌
}
// 초기생성자의 매개변수는 사용자 임의로 변경가능하다.
public MyDatabaseHelper(Context context, String name,
CursorFactory factory, int version) {
super(context, name, factory, version);
// TODO Auto-generated constructor stub
}
}

SQLiteDatabase mDb = mDbHelper.getWritableDatabase(); // 실제 데이터베이스 생성

데이터 추가
ex)
ContentValues initialValues = new ContentValues();
initialValues.put(KEY_TITLE, title);
initialValues.put(KEY_BODY, body);
mDb.insert(DATABASE_TABLE, null, initialValues);

데이터 삭제
ex)
mDb.delete(DATABASE_TABLE, KEY_ROWID + "=" + rowId, null) > 0;  
 
데이터 가져오기
ex)
mDb.query(DATABASE_TABLE, new String[] 
{KEY_ROWID, KEY_TITLE, KEY_BODY}, null, null, null, null, null);

데이터 업데이트
ex)
ContentValues args = new ContentValues();
args.put(KEY_TITLE, title);
args.put(KEY_BODY, body);
mDb.update(DATABASE_TABLE, args, KEY_ROWID + "=" + rowId, null) > 0;

Notepad Tutorial 참조.


- Content Providers

데이터 공유 할수 있는 공식적인(표준적) 방법이다.

두가지 방법
1. 기존의 Content provider를 추가한다.
2. 새로운 Content provider를 생성한다.

Content provider는 단순한 테이블로 구성되어 있다.(공식적으로 id는 _ID로 되어 있다.)
Cursor를 통해서 record를 이동하여 참조할수 있다.

Database의 접근은 URI를 통해서 접근한다.(문자열. "content://"로 시작됨.)
(즉 DB정보를 몰라도 하나의 주소형태로 접근가능하다)

Android에서 기본적으로 제공하는 URI
android.provider.Contacts.Phones.CONTENT_URI
android.provider.Contacts.Photos.CONTENT_URI
android.provider.CallLog.Calls.CONTENT_URI
...

질의 방법에는 두가지가 있는데,ContentResolver.query(), Activity.managedQuery() 
Activity는 Cursor(resource)를 life cycle에 의해서 리소스 할당 해제가 자동으로 
관리되므로 Activity.managedQuery()를 주로 사용한다.
Activity.startManagingCursor(Cursor c);

실제 마지막 데이터에 접근하려면 id값이 추가로 필요한다.
ContentUris.withAppendedId(), Uri.withAppendedPath() 통해서 추가하여 URI로
사용된다.
public static Uri withAppendedId(Uri contentUri, long id)
public static Uri withAppendedPath(Uri baseUri, String pathSegment)

ex)
Uri myPerson = ContentUris.withAppendedId(People.CONTENT_URI, 23);
// id가 23인 people에 접근하는 URI
Cursor cur = managedQuery(myPerson, null, null, null, null);
// cur는 단 특정 id(23)을 지정하였으므로 하나의 내용만 가지고 있다.


ex) content 접근 예제(주의 permission 필요함 android.permission.READ_CONTACTS)
String[] projection = new String[] { People._ID, People.NAME, People.NUMBER };
// Get the base URI for the People table in the Contacts content
// provider.
Uri contacts = People.CONTENT_URI;
// Make the query.(오름차순)
Cursor managedCursor = managedQuery(contacts, projection, null,
null, People.NAME + " ASC");
getColumnData(managedCursor);

...


private void getColumnData(Cursor cur){
if (cur.moveToFirst()) {  // cursor의 맨앞으로
String name;
String phoneNumber;
int nameColumn = cur.getColumnIndex(People.NAME);
int phoneColumn = cur.getColumnIndex(People.NUMBER);
do {
// Get the field values
name = cur.getString(nameColumn);
phoneNumber = cur.getString(phoneColumn);
// Do something with the values.
Log.d("test", "name="+name+", phone="+phoneNumber);
...
} while (cur.moveToNext());
}
}

Cursor는 가져온 데이터를 출력용으로 사용하고,
Data수정은 ContentResolver() 통해서 수정가능하다.

ex) data 수정
ContentValues values = new ContentValues(); // DB에 추가할때 사용됨.
// Add Abraham Lincoln to contacts and make him a favorite.
values.put(People.NAME, "Punbear");
// 1 = the new contact is added to favorites
// 0 = the new contact is not added to favorites
values.put(People.STARRED, 1);  // 즐겨찾기 추가
Uri uri = getContentResolver().insert(People.CONTENT_URI, values);
// 리턴되는 uri는 추가된 데이터의 URI

ex) data 추가(위의 코드와 연결됨)
Uri phoneUri = null;
Uri emailUri = null;
phoneUri = Uri.withAppendedPath(uri, People.Phones.CONTENT_DIRECTORY);
values.clear();
values.put(People.Phones.TYPE, People.Phones.TYPE_MOBILE);
values.put(People.Phones.NUMBER, "01047150000");
getContentResolver().insert(phoneUri, values);
// Now add an email address in the same way.
emailUri = Uri.withAppendedPath(uri, People.ContactMethods.CONTENT_DIRECTORY);
values.clear();
// ContactMethods.KIND is used to distinguish different kinds of
// contact methods, such as email, IM, etc.
values.put(People.ContactMethods.KIND, Contacts.KIND_EMAIL);
values.put(People.ContactMethods.DATA, "punbear@gmail.com");
values.put(People.ContactMethods.TYPE, People.ContactMethods.TYPE_HOME);
getContentResolver().insert(emailUri, values);

Provider 종류 아래 URL 참조

Contacts : 연락처(1.6 버전 이하)
ContactsContract : 연락처(2.0 버전 이상)
MediaStore : 미디어관련
...

1.6까지는 web과 1개만 sync 되었었는데 2.0(API Level 5) 로 와서는 3개까지 지원됨.
실제로 전화기 관련 app 개발시 ContactsContract 를 통해서 작업해야함. Contact 는 참고!!

- NDK란??
NDK : Java에서 C code를 결합하는거 ?
NDK를 사용하는 주요이유는 기존에 사용하는 c코드 및 리눅스 레벨에서 사용되는 코드를
그대로 사용하기 위해서, OpenGL, Android 게임 프로그래밍등등..
JNI(C code Interfaces)

- Binder
- Service 
- AIDL(Android Interface Definition Language) (Java 문법 아님) 기법. 아래 URL 참조

Font는 res가 아닌 assets 폴더 안에다가 넣는다(자동화 되지 않음)
ex) Fontset
Typeface typeface = Typeface.createFromAsset(getContext(), getAssets(), "gulim.ttf");
setTypeface(typeface);

- 이클립스 단축키
F4 : class Hierarchy를 볼수 있음.

Toast 사용자 임의 수정 가능함.(아래 파일 참조)
file:///C:/android/android-sdk-windows/docs/guide/topics/ui/notifiers/toasts.html
Toast 바로 표시하기!(??) 어떻게 할까요??

에뮬레이터에서 F6 : 트랙볼

다국어 관련 파일들 존재
C:\android\android-sdk-windows\platforms\android-7\data\res
mcc : Mobile Climate Control  ???
mnc : Media Nusantara Citra   ???
위의 둘다 지원함.
res 에 values/Language 추가(이때 기존의 values/strings.xml 파일과 이름이 동일해야함
로케일 변경하면 자동적으로 다국어 변환됨.

- anonymouse inner class(안드로이드에서 빈번하게 사용됨)
builder.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
}
});

<Thread>
Looper : 메시지 루프를 구동함
Handler : 메시지 큐에 메시지를 넣음. 메시지 큐에서 메시지를 꺼냄
Bundle class : key-value형태로 데이터를 관리하는 클래스
ex)
Message msg = thread.mHandler.obtainMessage(); (미리 만들어논 메시지가 
있다면사용되지 않는 object 리턴[최적화])
Bundle b = new Bundle();
b.putInt("total", total);
msg.setData(b);     // msg.getData().getInt("total");(가져오기)
thread.mHandler.sendMessage(msg);

Handler는 생성되는 위치에따라서 Parent의 thread와 결합하여 동작되게 된다.
(메시지큐 동일하게 사용함)


<Menu>
1. Option menu(Web browser의 옵션)
- Icon menu
- Expanded menu

  Menu버튼을 click했을때(Activity.onCreateOptionsMenu()) 자동호출
  메뉴가 최초에 open 될때 호출됨.
  source-override Implement methods... 에서 코드 자동추가 가능함.

  menu추가 방법
  code : Menu.add() 
ex)       
menu.add(groupId, itemId, order, title)
menu.add(0, Menu.FIRST+1, 0, "Menu1");
menu.add(0, Menu.FIRST+2, 0, "Menu2");
(Menu.FIRST 는 Menu class에서 권장하는 초기 itemId 상수임.)

- Menu.add()는 MenuItem객체를 리턴하므로 MenuItem의 객체를 바로 수정가능하다.
ex)
 menu.add(0, MENU1, 0,"Menu1").setIcon(R.drawable.icon); (아이콘추가)
 menu.add(0, MENU1, 0, Menu1").setIcon(android.R.drawable.ic_btn_speak_now));
(android에 내장된 icon 객체를 바로사용할수 있음)
            
C:\android\android-sdk-windows\platforms\android-7\data\res\
drawable-mdpi 위치에서 확인가능함.

menu 수가 6개 이상일때는 화면을 많이 가려 불편할수 있으므로 5개까지 표시한후
More 버튼이 마지막에 표시되며, 나머지 6번째 이상부터 표시된다. 이때 아이콘은 표시되지 않는다.

MenuItem을 click했을때(Activity.onOptionsItemSelected()) 호출됨.

ex)
public boolean onOptionsItemSelected(MenuItem item) {
switch(item.getItemId())
{
case MENU1:
Toast.makeText(this, "MENU1 Selected", Toast.LENGTH_SHORT).show();
return true;
case MENU2:
...

  menu항목을 상황에 따라 바꾸고 싶을때.(Toggle button(ex.power on/off))
  메뉴가 열릴때마자 Activity.onPrepareOptionsMenu()자동으로 호출됨.

  ex)
public boolean onPrepareOptionsMenu(Menu menu) {
MenuItem item = menu.findItem(MENU2);
if (mPowerState)
{
item.setTitle("Power On");
}
else
{
item.setTitle("Power Off");
}

* onOptionsItemSelected()에서 선택했을때 바로 text를 바꿀수도 있지만.
  일반적으로는 선택후 다음에 메뉴가 보여질때(onPrepareOptionsMenu()) 에서
  text를 변경함.


 - XML -
menu.xml 파일을 생성한후 코드에서 아래와 같이 추가한다.
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.options_menu, menu);
return super.onCreateOptionsMenu(menu);
}

XML 에서 resource 참조 방법(Layout)

ex) for XML
android resource : @android:drawable/ic_dialog_email 
   (android.R.drawable 에있는 기본 아이콘중하나)
user resource : @string/menu2 


2. Context menu(mouse long click)
- long clicked시 Activity.onCreateContextMenu()가 호출된다.
  (누르는 위치에따라 동작이 다르며, Avtivity.registerForContextMenu()를 해주어야 동작이됨.)
   각 component들은 id값을 가지고 있어야한다.
   ContextMenu에서 setIcon은 적용되지 않는다.
   
3. Submenu
- 다른 메뉴들과 같이 사용된다. 하위계층.
  Parent의 callback function onOptionsItemSelected()/ onContextItemSelected()에서 
  같이 처리됨. Parent의 menuID와 중복되면 안된다.

ex)
SubMenu subMenu = menu.addSubMenu("MENU3");
subMenu.add(0, SUBMENU1, 0, "SUB Menu1");
subMenu.add(0, SUBMENU2, 0, "SUB Menu2");
subMenu.add(0, SUBMENU3, 0, "SUB Menu3");



<Dialog>

- AlertDialog (Ok,Cancel 같이 항목들중 한가지 선택가능하도록)
AlertDialog는 back 버튼 동작되지 않는다.
(AlertDialog.Builder.setCancelable(true) 하면 가능함)
ex)
protected Dialog onCreateDialog(int id) {
switch(id)
{
case DIALOG1:
{
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setMessage("Are you sure you want to exit?");
builder.setCancelable(false);
builder.setPositiveButton("Yes",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
   DialogTest.this.finish();
}
});
builder.setNegativeButton("No",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog,int id) {
dialog.cancel();
}
});
AlertDialog alert = builder.create();
return alert;
}
    case DIALOG2:
    {
      final CharSequence[] items = { "Red", "Green", "Blue" };
            AlertDialog.Builder builder = new AlertDialog.Builder(this);
    builder.setTitle("Pick a color");
    builder.setItems(items, new DialogInterface.OnClickListener() {
      public void onClick(DialogInterface dialog, int item) {
Toast.makeText(getApplicationContext(), items[item],
Toast.LENGTH_SHORT).show();
     }
    });
    AlertDialog alert = builder.create();
    return alert;
     }
     case DIALOG3:
    {
             final CharSequence[] items = { "Red", "Green", "Blue" };
     AlertDialog.Builder builder = new AlertDialog.Builder(this);
     builder.setTitle("Pick a color");
     builder.setSingleChoiceItems(items, -1,
     new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int item) {
Toast.makeText(getApplicationContext(), items[item],              Toast.LENGTH_SHORT).show();
}
});
AlertDialog alert = builder.create();
return alert
    }

 setPositiveButton : 긍정의미의 버튼
 setNeutralButton : 중립의미의 버튼
 setNegativeButton : 부정의미의 버튼
 (위의 3버튼들을 사용자 임의로 설정할수 있다.)

- ProgressDialog(진행사항표시)
setProgressStyle(ProgressDialog.STYLE_HORIZONTAL) 일반적인 퍼센트 표시
setProgressStyle(ProgressDialog.STYLE_SPINNER) 끝나는 시점을 예측하기 힘들때 사용됨.

- DatePickerDialog(날짜)
- TimePickerDialog(시간)

- CustomDialog(user create)


Activity.showDialog(int) 로 Dialog가 보여진다.
showDialog() 호출시 최초 Dialog가 생성될때 
Activity.onCreateDialog(int) 가 자동으로 호출된다.
onCreateDialog()에서 생성된 Dialog 객체를 return 해준다.

Activity.onPrepareDialog(int, Dialog) Dialog가 display 되기전에 호출된다.

Dialog 종료하기 
1. Dialog.dismiss(), Activity.dismissDialog(int) (화면에 보여지지만 않음)
2. Activity.removeDialog(int) 완전히 삭제 소멸


<Handling UI Events>
- Event listener : 일반적인 button clicked 같은 이벤트 listener
- Event handler : 클래스를 확장하여 기능을 변경함.
                        (트랙볼같은경우는 handler에서 처리해야 자세한 정보를얻을수있다.)

ll.setFocusable(true) : focus상태에서만 key를 입력을 받는다.
ll.setFocusableInTouchMode(true);   : 터치모드에서도 key 입력을 받는다.

onKey()에서 return true는 onKey()에서 처리가 완료되었으므로 더이상
parent()로 이벤트 전달하지 않는다.

onTouch()에서 return true/false 차이점.
최초의 터치 이벤트를 처리안했다고 하면(return false) 그 이후에 마우스 이동시
이벤트가 발생이안된다.즉 Android에서는 처음 Touch 이벤트 처리가 안되면, 
그다음은 의미가 없다고 생각함. return false 를 하면 후속 이벤트 발생안됨.


1. system, data, sdcard(응용프로그램 개발이면 위의 3개 폴더에서 주로 작업함)

unique linux user ID(security)

Android component
(Activity, Service, Broadcast Receiver, Content provider)

Activity = Single Thread

Broadcast Receiver
1. System이 발생
2. Application이 발생(Send,Receiver 둘다 작성)

event 발생시 NotificationManager(폰 맨위의 타이틀바)에 표현가능.

Toast : 간단히 메세지 출력하기

BroadcastReceiver subclass(이벤트 발생시 한줄 출력하는 코드)
public void onReceive(Context context, Intent intent) {
Toast.makeText(context, "SMS received!", Toast.LENGTH_SHORT).show();
}

Eclipse ShortKey
Ctrl+Shift+f : 코드 정리
Ctrl+m : 화면 최대화(code)
Ctrl+Shift+o : import 자동 해결
F2 : 파일이름변경

shift+F2(특정클래스이름에서) : 도움말 열림.

실행시 제대로 동작이 안될시 : permission 관련 문제일 경우가 많음.

ContentProvider데이터는 ContentResolver class로 접근 가능하다.

android:id="@+id/Button01  "+" 는 id를 추가한다라는 의미임.
(만약에 +가 없다면 기존의 존재하는 id값을 사용함)

Intent의 종류
- Explicit intent(대상 명확함) : 하나의 응용 프로그램 내부에서 
자신의 Activity/Service/Receiver를 구동할때 사용.
- Implicit intent(대상 명확하지않음) :

디버그 메세지 출력 Log.d("test", "OnCreate called");
DDMS에서 LogCat 텝에서 확인가능함(filter를 사용하면 원하는 디버깅 메세지 쉽게 확인가능)

Home : Activity 종료되지않음.
Back : Activity 종료됨.

색상설정
code : 0xAARRGGBB
layout : #AARRGGBB

dip(dp) : density-independent pixel
          (Pixel이 다른 기기에서도 동일한 padding 값을 유지함)