170501 안드로이드 스터디 정리
01 May 2017
- play book url
- 안드로이드 초기역사
- 달빅 VM
- 안드로이드 소프트웨어 스택
- 안드로이드 컴포넌트
- 애플리케이션 생애주기
- 리소스
- 핵심 안드로이드 리소스
- 이미지 리소스
- 모서리가 둥근 직사각형
- raw 리소스
- asset
- 시스템 DB 파일
- 헬퍼클래스에 정의된 URI
- 주소록 DB 읽기
- 레코드 삽입
- 레코드 갱신/삭제
- 인텐트 기초
- 기본 인텐트
- 간단한 메뉴
- 클래스 이름으로 인텐트 호출
- 인텐트 카테고리
- 실행가능한 앱 모두 열거
- 어떤앱을 실행할지 묻기
- 어떤홈을 실행할지 묻기
- TextView 자동링크
- AutoCompleteTextView
- Button
- ImageButton
- ToggleButton
- CheckBox
- RadioButton
- ImageView
- DatePicker, TimePicker
- 스타일과 테마
- 뷰에서 스타일 사용
- 레이아웃 관리자
- LinearLayout
- 메뉴
- 컨텍스트 메뉴
- 다이얼로그
- 토스트
- 탭-액션바
- 탭-액션바에 메뉴를 위치시키려면
- 리스트-액션바
- 표준-액션바
- 검색-액션바
[toc]
play book url
https://play.google.com/store/books/details?id=_8ajAgAAQBAJ
안드로이드 초기역사
- 2005 : 구글이 안드로이드 인수
- 2007 : v.1.0 (early look sdk) 발표
- 2009.4 : v1.5
- 소프트웨어 키보드
- 미디어 레코딩
- 위젯
- 2009.6 : v1.6
- 2009.7 : v2.0
- tts
- v2.3
- wifi 핫스팟
- sd card 앱설치 지원
- OpenGL ES 2.0 지원
- NFC 지원
- v3.0
- 듀얼코어 지원
- 프래그먼트 소개
- v4.0
- Roboto 폰트 추가
- Wifi Direct 제공
- P2P 서비스를 위함
달빅 VM
- jvm 구현체 –(최적화)–> 달빅vm
- .class 파일 –(달빅vm)–> .dex 파일
안드로이드 소프트웨어 스택
Application |
---|
Java SDK 리소스, 위치, UI, 컨텐트프로바이더, 패키지매니저 |
달빅VM |
native 라이브러리 OpenGL, WebKit, FreeType, SSL, libc, SQLite, Media(패킷비디오기반, www.packetvideo.com, OpenCore), SurfaceManager … |
리눅스 커널 디바이스 드라이버, 리소스관리, 전력관리 … |
안드로이드 컴포넌트
- intent
private static void _StartGoogle(Activity activity) { var intent = new Intent(Intent.ACTION_VIEW); intent.setData(Uri.Parse("http://google.com")); activity.startActivity(intent); }
애플리케이션 생애주기
- 액티비티 시작
- onCreate
- onStart
- onResume
- onPause
- onStop
- onDestroy
- 액티비티 종료
리소스
- 문자열 리소스
- /res/values/strings.xml
<resource> <string name=hello> hello <string name=app_name> hello message
R.string.hello
- /res/values/strings.xml
- 레이아웃 리소스
-
/res/layout/main.xml
<LinearLayout orientation=vertical layout_width=fill_parent layout_height=fill_parent <TextView id=@+id/text1 ... <Button id=@+id/b1 ...
onCreate this.setContentView(R.layout.main); var tv = (TextView)this.findViewById(R.id.text1); tv.setText("...");
-
핵심 안드로이드 리소스
- 문자열
- /res/values/…
- R.string.*
- 이미지
- /res/drawable/…
- *.jpg, *.png, *.gif
- *.9.png
- R.drawable.*
- xml
- /res/xml/…
- *.xml
- R.xml.*
- raw 리소스
- /res/raw/…
- R.raw.*
- 에셋
- /assets/…/…/…/*
- 임의의 깊이가 가능함
- 실제 리소스는 아니고 그냥 일반 파일
- 리소스 ID 생성 안함
- /assets 를 제외한 상대경로로 접근해야 함
이미지 리소스
<Button
id=@+id/button1
background=@drawable/sample_image
var d = activity.getResource().getDrawable(R.drawable.sample_image);
button.setBackgroundDrawable(d);
button.setBackgroundResource(R.drawable.sample_image)
모서리가 둥근 직사각형
-
/res/drawable/my_rounded_rect.xml
<shape <solid color=#ff123456 <stroke width=3dp color=... <corners radius=13dp <padding left=10dp top=10dp right=10dp bottom=10dp
var d = (GradientDrawable)activity.getResources().getDrawable(R.my_rounded_rect);
tv.setBackgroundDrawable(d);
raw 리소스
String _GetStringFromRawFile(activity)
var is = activity.getResource().openRawResource(R.raw.test);
var os = new ByteArrayOutputStream();
...
var str = os.toString();
return str;
asset
String _GetStringFromAssetFile(activity)
var is = activity.getAssets().open("test.txt");
var os = new ByteArrayOutputStream();
...
var str = os.toString();
return str;
시스템 DB 파일
- /data/data/*/databases
- alarms.db
- contracts.db
- downloads.db
- settings.db
- …
헬퍼클래스에 정의된 URI
- MediaStore.Images.Media.INTERNAL_CONTENT_URI
- content://media/internal/images
- MediaStore.Images.Media.EXTERNAL_CONTENT_URI
- content://media/external/images
- ContactsContract.Contacts.CONTENT_URI
- content://com.android.contacts/contacts
주소록 DB 읽기
-
23 번 주소록 읽기
var uri23 = Uri.withAppendedPath(ContactsContract.Contacts.CONTENTS_URI, "23"); var cur = activity.managedQuery(uri23, null, null, null); var idxName = cur.getColumnIndex(Contacts.DISPLAY_NAME_PRIMARY); var name = cur.getString(idxName);
var uri = ContactsContract.Contacts.CONTENTS_URI; var cur = activity.managedQuery(uri23, null, "id=?", new String[] {23}); var idxName = cur.getColumnIndex(Contacts.DISPLAY_NAME_PRIMARY); var name = cur.getString(idxName);
-
모든 주소록 읽기
var uri = ContactsContract.Contacts.CONTENTS_URI; var cur = activity.managedQuery(uri23, null, null, null); var idxName = cur.getColumnIndex(Contacts.DISPLAY_NAME_PRIMARY); for(cur.moveToFirst(); !cur.isAfterLast(); cur.moveNext()) { var name = cur.getString(idxName); }
레코드 삽입
var values = new ContentValues();
values.put("title", "new title");
values.put("note", "new note");
var cr = activity.getContentResolver();
var uri = ContactsContract.Contacts.CONTENTS_URI;
var newUri = cr.insert(uri, values);
레코드 갱신/삭제
cr.update
cr.delete
인텐트 기초
MyActivity
{
onCreate
{
var intent = this.getIntent();
...
}
}
<activity name=.MyActivity
<intent-filter
<action name=com.myapp.intent.action.My
<category name=android.intent.category.DEFAULT
_InvokeMyActivity(activity)
{
var actionName = "com.myapp.intent.action.My"
var intent = new Intent(actionName);
activity.startActivity(intent);
}
기본 인텐트
_InvokeWebBrowser(activity)
{
var intent = new Intent(Intent.ACTION_VIEW);
intent.setData(Uri.Parse("http://google.com"));
activity.startActivity(intent);
}
_InvokeCall(activity)
{
var intent = new Intent(Intent.ACTION_CALL);
intent.setData(Uri.Parse("tel:02-1234-5678"));
activity.startActivity(intent);
}
간단한 메뉴
MyActivity
{
onCreateOptionMenu(menu)
{
var menuIdx = Menu.FIRST;
var item1 = menu.add(menuIdx, menuIdx, menuIdx, "first menu");
menuIdx++;
var item2 = menu.add(menuIdx, menuIdx, menuIdx, "second menu");
}
onOptionMenuSelected(item)
{
if(item.getItemId() == Menu.FIRST)
{
}
else if(item.getItemId() == (Menu.FIRST + 1))
{
}
}
}
클래스 이름으로 인텐트 호출
_InvokeMyActivity(activity)
{
var intent = new Intent(activity, MyActivity.class);
activity.startActivity(intent);
}
인텐트 카테고리
- CATEGORY_DEFAULT
- 묵시적 인텐트로 실행가능하게
- CATEGORY_LAUNCHER
"android.intent.category.LAUNCHER"
- 시작화면을 지정
- CATEGORY_HOME
- 홈스크린에 표시
실행가능한 앱 모두 열거
_EnumAllAppsAndStartMy(activity)
{
var mainIntent = new Intent(Intent.ACTION_MAIN, null);
mainIntent.addCategory(Intent.CATEGORY_LAUNCHER);
var pm = activity.getPackageManager();
var actList = pm.queryIntentActivities(mainIntent, 0);
for (var ri : actList)
{
var packName = ri.activityInfo.packageName;
var clsName = ri.activityInfo.name;
if(clsName.Contains(".My"))
{
var newIntent = new Intent();
newIntent.setClassName(packName, clsName);
activity.startActivity(newIntent);
break;
}
}
}
어떤앱을 실행할지 묻기
_QueryAnyApp(activity)
{
var mainIntent = new Intent(Intent.ACTION_MAIN, null);
mainIntent.addCategory(Intent.CATEGORY_LAUNCHER);
activity.startActivity(mainIntent);
}
어떤홈을 실행할지 묻기
_QueryAnyHome(activity)
{
var mainIntent = new Intent(Intent.ACTION_MAIN, null);
mainIntent.addCategory(Intent.CATEGORY_HOME);
activity.startActivity(mainIntent);
}
TextView 자동링크
tv.setAutoLinkMask(Linkify.ALL);
tv.setText("please visit http://google.com .")
AutoCompleteTextView
<AutoCompleteTextView id=@+id/actv
tv.setAutoLinkMask(Linkify.ALL);
tv.setText("please visit http://google.com .");
var strAdapter = new ArrayAdapter<String>(
this,
android.R.layout.simple_dropdown_item_1line,
new String[] {"en", "ko", "jp", "ch", ...});
tv.setAdapter(strAdapter);
Button
<Button ...
var btn = (Button)thisActivity.findViewById ...
btn.setOnClickListener( new OnClickListener() {
public void onClick(v) {
var i = new Intent(Intent.ACTION_VIEW,
Uri.parse("http://google.com"));
thisActivity.startActivity(i);
}
})
ImageButton
<ImageButton
...
src=@drawable/icon
imgBtn = findById ...
imgBtn.setImageResource(R.drawable.icon);
ToggleButton
<ToggleButton
textOn
textOff
CheckBox
<CheckBox
cb.setOnChecedChangeListener(
new CompoundButton.OnCheckedChangeListener() {
onCheckedChanged(cb, isChecked) {
...
}
}
)
RadioButton
<RadioGroup
orientation=vertical
<RadioButton
text=...
<RadioButton
text=...
<RadioButton
text=...
var myRadioGroup = findById ...
var id = myRadioGroup.getCheckedRadioButtonId();
myRadioGroup.setOnCheckedChangedListener(
...
);
ImageView
<ImageView
id=@+id/img1
src=@drawable/icon
<ImageView
id=@+id/img2
layout_width=125dp
layout_height=25dp
src=#555555
<ImageView
id=@+id/img3
<ImageView
id=@+id/img4
src=@drawable/img4
scaleType=centerInside
maxWidth=35dp
maxHeight=50dp
img3 = ...
img3.setImageResource(R.drawable.img3);
img3.setImageBitmap(
BitmapFactory.decodeResource(
thisActivity.getResourec(),
R.drawable.img3));
img3.setImageDrawable(
Drawable.createFromPath("/mnt/sdcard/img3.png"));
img3.setImageURI(
Uri.parse("file://mnt/sdcard/img3.png"));
DatePicker, TimePicker
<DatePicker
<TimePicker
dp.getMonth();
...
var timeF = new java.util.Formatter();
timeF.format(
"%02d:%02d:%02d",
tp.getCurrentHour(),
tp.getCurrentMinute(),
tp.getCurrentSecond());
var timeStr = timeF.toString();
스타일과 테마
<string name=styled_text><i>이탤릭</i>스타일 <b>볼드</b>스타일</string>
tv.setText(
R.string.styled_text,
TextView.BufferType.SPANNABLE);
et.setText(...);
var spn = (Spannable)et.getText();
spn.setSpan(
new BackgroundColorSpan(Color.RED),
0,
7,
Spanable.SPAN_EXCLUSIVE_EXCLUSIVE);
spn.setSpan(
new StyleSpan(android.graphics.Typeface.BOLD_ITALIC),
0,
7,
Spanable.SPAN_EXCLUSIVE_EXCLUSIVE);
뷰에서 스타일 사용
-
/res/values/…
<resources <style name=error_text <item name=layout_width>fill_parent <item name=layout_height>fill_parent <item name=textColor>#ff0000 <item name=typeface>monospace
-
/res/layout/…
<TextView style=@style/error_text
레이아웃 관리자
- LinearLayout
- TableLayout
- RelativeLayout
- FrameLayout
- GridLayout
LinearLayout
<LinearLayout
<EditText
layout_height=wrap_content
layout_weight=0
<EditText
layout_height=wrap_content
layout_weight=100
<EditText
layout_height=wrap_content
layout_weight=0
- 그외의 속성
- layout_gravity
- gravity
메뉴
MyActivity
onCreateOptionMenu( menu )
{
super ...
menu.add(0, 0, 0, "menu0");
menu.add(1, 1, 1, "menu1");
var menuItem2 = menu.add(2, 2, 2, "menu2");
menuItem2.setIcon(R.drawable.menuItem2);
}
onOptionItemSelected( item )
{
var mid = item.getItemId();
}
컨텍스트 메뉴
MyActivity
onCreate
{
var tv = ...
thisActivity.registerForContextMenu(tv);
}
onCreateContextMenu(menu, v, menuInfo)
{
menu.setHeaderTitle("contextMenu");
menu.add(100, 100, 100, "contextMenuItem100");
}
onContextItemSelected(item)
{
if(item.getItemId() == 100)
{
...
}
}
다이얼로그
AlertDialog.Builder
토스트
Toast.
makeText(thisActivity, "toast message", Toast.LENGTH_LONG).
show();
탭-액션바
MyActivity
onCreate
var ab = thisActivity.getActionBar();
ab.setTitle
ab.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
var t0 = ab.newTab();
t0.setText
t0.setTabListener
ab.addTab(t0);
var t1 = ab.newTab();
t1.setText
t1.setTabListener
ab.addTab(t1);
탭-액션바에 메뉴를 위치시키려면
showAsAction=ifRoom
//showAsAction=ifRoom
//showAsAction=never
//showAsAction=always
리스트-액션바
MyActionBarAdapter
extends ArrayAdapter<String>
implements SinnableAdapter
{
MyActionBarAdapter(ctx)
{
super(
ctx,
android.R.simple_sppiner_item,
new String[] {"one", "two"});
this.setDropDownResource(
android.R.layout.simple_spinner_dropdown_item);
}
getDropdownView(position, convertView, perentView)
{
return super.getDropDownView(
position,
convertView,
parentView);
}
}
MyActivity
onCreate
var ab = thisActivity.getActionBar();
ab.setTitle
ab.setNavigationMode(ActionBar.NAVIGATION_MODE_LIST);
ab.setListNavigationCallbacks(
new MyActionBarAdapter(this),
new ActionBar.OnNavigationListener
{
onNavigationItemSelected(itemPosition, itemId)
{
}
}
);
표준-액션바
MyActivity
onCreate
var ab = thisActivity.getActionBar();
ab.setTitle
ab.setNavigationMode(ActionBar.NAVIGATION_MODE_STANDARD);
var t0 = ab.newTab();
t0.setText
t0.setTabListener
ab.addTab(t0);
var t1 = ab.newTab();
t1.setText
t1.setTabListener
ab.addTab(t1);
검색-액션바
MyActivity
{
onCreateMenu
{
var menuItem = create ...
menuItem.id = id/menu_search ...
var searchView = (SearchView)menuItem.getActionView();
var searchMgr = (SearchManager)thisActivity.getSystemService(
Context.SEARCH_SERVICE);
var cn = new ComponentName(thisActivity, MyActivity.class);
var info = searchMgr.getSearchInfo(cn);
searchView.setSearchInfo(info);
searchView.setIconifiedByDefault(false);
}
onCreate
{
var queryIntent = thisActivity.getIntent();
var queryAction = queryIntent.getAction();
if (queryAction == Intent.ACTION_SEARCH)
{
var queryString = queryIntent.getStringExtra(
SearchManager.QUERY);
}
}
}
- /res/xml/searchable.xml
<searchable
label=...
hint=...
- AndroidManifest.xml
<activity name=.MyActivity
<intent-filter
<action name=android.intent.action.SEARCH
<meta-data
name=android.app.searchable
resource=@xml/searchable