Android (2/3) Kook, Joongjin (tipsiness@gmail.com) Operating Systems Lab. Soongsil University 2009.07. 07 141
AlertDialog AlertDialog 실행결과 142
ProgressDialog ProgressDialog ProgressBar 를함께표현한 dialog ProgressDialog 객체생성후 title, message, progressstyle 등을지정하여 dialog 생성 http://developer.android.com/reference/android/app/pro gressdialog.html Progress Style int STYLE_HORIZONTAL Creates a ProgressDialog with a horizontal progress bar. int STYLE_SPINNER Creates a ProgressDialog with a ciruclar, spinning progr ess bar. 143
ProgressDialog ProgressDialog Methods int int getmax() getprogress() int getsecondaryprogress() og ess() void void boolean void void incrementprogressby(int diff) incrementsecondaryprogressby(int diff) isindeterminate() onstart() Called when the dialog is starting. setindeterminate(boolean indeterminate) void setindeterminatedrawable(drawable d) void void void setmax(int max) setmessage(charsequence message) setprogress(int value) void setprogressdrawable(drawable d) void void setprogressstyle(int style) setsecondaryprogress(int secondaryprogress) static ProgressDialog show(context context, CharSequence title, CharSequence message) 144
ProgressDialog ProgressDialog Exam1 mprogdlg = new ProgressDialog(this); mprogdlg.seticon(r.drawable.icon); mprogdlg.settitle(r.string.progress_title); mprogdlg.setprogressstyle(progressdialog.style_horizontal); mprogdlg.setmax(100); mprogdlg.setbutton(gettext(r.string.hide), new DialogInterface.OnClickListener() { }); public void onclick(dialoginterface dialog, int which) {} mprogdlg.setbutton2(gettext(r.string.cancel), new DialogInterface.OnClickListener() { public void onclick(dialoginterface dialog, int whichbutton) {} }); mprogdlg.show(); 145
ProgressDialog ProgressDialog 실행결과 146
ProgressDialog ProgressDialog Exam2 mproghandler = new Handler() { public void handlemessage(message msg) { super.handlemessage(msg); if (mprogress >= 100) { mprogdlg.dismiss(); } else { }; } } mprogress++; mprogdlg.incrementprogressby(1); mproghandler.sendemptymessagedelayed(0, 100); mproghandler.post(null); 147
ProgressDialog ProgressDialog 실행결과 148
ProgressDialog ProgressDialog Exam3 mprogdlg = new ProgressDialog(this); mprogdlg.seticon(r.drawable.icon); mprogdlg.settitle(r.string.progress_title); mprogdlg.setprogressstyle(progressdialog.style_spinner); mprogdlg.setmax(100); mprogdlg.setbutton(gettext(r.string.hide), new DialogInterface.OnClickListener() { }); public void onclick(dialoginterface dialog, int which) {} mprogdlg.setbutton2(gettext(r.string.cancel), new DialogInterface.OnClickListener() { public void onclick(dialoginterface dialog, int whichbutton) {} }); mprogdlg.show(); 149
ProgressDialog ProgressDialog 실행결과 150
Toast Toast Methods void int int View static Toast static Toast void void void void cancel() getduration() getgravity() getview() maketext(context context, int resid, int duration) maketext(context context, CharSequence text, int duration) setduration(int duration) setgravity(int gravity, int xoffset, int yoffset) setmargin(float horizontalmargin, float verticalmargin) settext(int resid) void settext(charsequence s) void void setview(view view) show() 151
Toast Toast Exam Context context = this; int duration = Toast.LENGTH_SHORT; Toast toast = Toast.makeText(context, R.string.hello, duration); toast.show(); int LENGTH_LONG Show the view or text notification for a long period of time. int LENGTH_SHORT Show the view or text notification for a short period of time. 152
Toast Toast 실행결과 153
Button Buttons Button 일반적인버튼의동작수행 ImageButton 이미지를올릴수있는버튼 ToggleButton on/off 상태표시 RadioButton 여러옵션들중한개선택 CheckBox 여러옵션들중여러개선택 Spinner 여러옵션들을리스트형식으로보여주고선택 154
Button 기본 button 의동작 public class MyActivity extends Activity { protected void oncreate(bundle icicle) { super.oncreate(icicle); setcontentview(r.layout.content_layout_id); final Button button = (Button) findviewbyid(r.id.button_id); } } button.setonclicklistener(new View.OnClickListener() { }); public void onclick(view v) { // Perform action on click } 155
Button Button 생성및클릭이벤트처리 public void oncreate(bundle savedinstancestate) { super.oncreate(savedinstancestate); setcontentview(r.layout.buttons); mbtn_common = (Button)findViewById(R.id.btn_common); mbtn_common.settext(r.string.button_title); mbtn_common.settextcolor(0xffffff00); mbtn_common.setpadding(2, 2, 2, 2); mbtn_common.setfocusable(true); } mbtn_common.setonclicklistener(new View.OnClickListener() { public void onclick(view v) { Dialog d = new Dialog(ButtonExam.this); d.settitle("button Clicked"); d.show(); } }); 156
Button 버튼결과 157
ImageButton ImageButton public void oncreate(bundle savedinstancestate) { super.oncreate(savedinstancestate); setcontentview(r.layout.buttons); } mbtn_image = (ImageButton)findViewById(R.id.btn_image); mbtn_image.setimageresource(r.drawable.img_button_1); mbtn_image.setpadding(5, 5, 5, 5); mbtn_image.setfocusable(true); 158
ImageButton ImageButton - xml <ImageButton android:id="@+id/btn_image" android:layout_width="fill_parent" android:layout_height="fill_parent" android:text="@string/button_title" > </ImageButton> 159
ImageButton ImageButton 결과 160
CheckBox CheckBox mbtn_check1 = (CheckBox)findViewById(R.id.plain_cb); mbtn_check2 = (CheckBox)findViewById(R.id.serif_cb); mbtn_check3 = (CheckBox)findViewById(R.id.bold_cb); mbtn_check4 = (CheckBox)findViewById(R.id.italic_cb); mbtn_check1.settext(r.string.check1); mbtn_check2.settext(r.string.check2); h k2) mbtn_check3.settext(r.string.check3); mbtn_check4.settext(r.string.check4); mbtn_check1.setchecked(false); mbtn_check2.setchecked(true); 161
CheckBox CheckBox - xml <CheckBox android:id="@+id/plain_cb" android:text="plain" android:layout_width="wrap_content" android:layout_height="wrap_content /> <CheckBox android:id="@+id/serif_cb" android:text="serif" android:layout_width="wrap_content" android:layout_height="wrap_content" android:typeface="serif /> <CheckBox android:id="@+id/bold_cb" android:text="bold" t android:layout_width="wrap_content" android:layout_height="wrap_content" android:textstyle="bold /> <CheckBox android:id ="@+id/italic_cb" android:text="italic" android:layout_width="wrap_content" android:layout_height= height="wrap_content" android:textstyle="italic /> 162
CheckBox CheckBox 결과 163
RadioButton RadioButton mbtn_radio1 = (RadioButton)findViewById(R.id.radio2); mbtn_radio2 = (RadioButton)findViewById(R.id.radio3); mbtn_radio3 = (RadioButton)findViewById(R.id.radio4); mbtn_radio1.settext(r.string.radio1); mbtn_radio2.settext(r.string.radio2); mbtn_radio3.settext(r.string.radio3); tt t(r t i 3) 164
RadioButton RadioButton - xml <RadioGroup android:id="@+id/radio1" android:layout_width="wrap_content" android:layout_height="wrap_content" xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" > <RadioButton android:id="@+id/radio2" id/ di android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="plain" android:checked="false" android:layout_gravity="left" android:layout_weight="0" > </RadioButton> </RadioGroup> 165
RadioButton RadioButton 결과 166
Spinner Spinner spinner = (Spinner)findViewById(R.id.spinner); ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(this, R.array.planets, android.r.layout.simple_spinner_item); spinner.setadapter(adapter); setadapter(adapter); 167
Spinner Spinner - xml <Spinner android:id="@+id/spinner" android:layout_width="fill_parent" android:layout_height="wrap_content" android:drawselectorontop="true" android:prompt="@string/planet_prompt" /> 168
Spinner Spinner 실행결과 169
Visual Tools Visual Tools <AnalogClock id="@+id/clock1" android:layout_width="wrap_content" android:layout_height="wrap_content /> <DatePicker android:layout_width="wrap_content" android:layout_height="wrap_content i h " /> <DigitalClock android:id="@+id/digitalclock" android:layout_width= width="wrap_content" android:layout_height="wrap_content /> <TimePicker android:id="@+id/widget3" android:layout_width="wrap_content" android:layout_height="wrap_content /> 170
Visual Tools Visual Tools 실행결과 171
화면구성요소 Activity에 View와 ViewGroup 클래스를사용하여화면표시 View 클래스 직사각형형태의레이아웃과각종정보를저장하는자료구조 화면의크기조절, 레이아웃구성, 그리기, 포커스변화, 스크롤링, 키처리등을위해사용 위젯 (widget) 의베이스클래스 ViewGroup 클래스 다중 view ViewGroup은 View 안에또다른View를가질수있는중첩구조허용 172
화면구성요소 Android는 Activity의 UI를 View와 ViewGroup의트리구조를이용하여구성 ViewGroup ViewGroup View View View View View 173
화면구성요소 LayoutParams View 객체들을어떻게그려야하는지에대한정보를부모객체에게알려줌 WRAP_CONTENT: 콘텐츠를표시하는데필요한최소한의크기로그린다 FILL_PARENT: 부모객체와의패딩 ( 여백 ) 을제외한나머지모든공간을차지 FILL_PARENT 적용 WRAP_CONTENT 적용 174
화면구성요소 LayoutParams LinearLayout LinearLayout View View View View RelativeLayout RelativeLayout LinearLayout LinearLayout. LayoutParams LayoutParams LinearLayout LinearLayout. LayoutParams LayoutParams LinearLayout LinearLayout. LayoutParams LayoutParams Vi Vi Vi Vi Vi Vi View View View View View View Relative RelativeLayout Layout. LayoutParams LayoutParams Relative RelativeLayout Layout. LayoutParams LayoutParams Relative RelativeLayout Layout. LayoutParams LayoutParams 175
Layout FrameLayout 단순히비어있는공간 모든객체들이화면의왼쪽위를기준으로그려짐 프로그래머가직접그리고싶은객체의기준점설정불가 LinearLayout 모든하위구성요소를수직또는수평형태중하나로정렬하여그리는방식 하위구성요소들간의 margin 과정렬방식 (gravity) 지정가능 구성요소별가중치 (android:layout_weight) 지정가능 화면에남는공간을어떻게활용할지결정 176
Layout 가중치미적용 177
Layout 가중치적용 178
Layout TableLayout 테이블의행과열을기준으로하위구성요소들배치 TableLayout 은행을정의하는 TableRow 객체로구성되고, 각행은 0 개이상의셀들로구성 각셀은0개이상의 View 오브젝트로표현되므로셀은비어있는상태가될수있음 열들은비어있는공간을최대로차지하여그릴수도있고, 화면에맞게줄일수도있으며, 보이지않게할수도있다 179
Layout AbsoluteLayout x, y 좌표를이용하여하위구성요소들을화면에표시 좌측상단을 (0,0) 으로하여우측하단이최대값인절대좌표계 margin 은지원되지않으나, 구성요소가겹치는것은허용 서로다른단말기환경에서는프로그래머가예상한대로그려지지않을수있으므로사용하지않는것이좋음 180
Layout RelativeLayout 하위구성요소들이다른구성요소의상대적인위치에따라그려짐 어떤객체를중심으로오른쪽, 왼쪽, 위쪽, 아래쪽과같은형식으로객체를그리는방식 181
View ViewGroup 클래스 설명 FrameLayout 단일객체를표현하기위한 View 프레임역할. 두개이상의객체를표현할때는나중에그린객체를먼저보여줌 LinearLayout 수평또는수직으로구성요소를배치하기위한레이아웃. 창의길이가화면의길이를초과하면자동으로스크롤바생성 TableLayout AbsoluteLayout RelativeLayout 행과열을가진테이블레이아웃. 행은가장큰구성요소에맞게크기가재설정되고, 셀테두리는감춰짐 프로그래머가좌표값으로객체의위치를명시하는레이아웃 한구성요소를기준으로다른구성요소들을표시하기위한방법의레이아웃 182
View ViewGroup 클래스 Gallery GridView ListView ScrollView 설명 이미지를수평으로스크롤하면서보여주는클래스 눈금구조를보여주는클래스 스크롤링되는하나의컬럼리스트표현 수직으로구성요소의열을스크롤링 Spinner 한줄짜리텍스트박스안에서목록의아이템을한번에하나씩보여줌. 수평또는수직으로스크롤될수있는한줄짜리리스트박스와유사 SurfaceView 그리기전용인표면에직접접근할수있도록함. SurfaceView 는위젯을사용하는프로그래밍보다는점과라인을직접그리는 Low level 코딩에사용 183
View ViewGroup 클래스 TabHost ViewFlipper ViewSwitcher 설명 클릭에반응하는탭선택목록을제공하며, 탭을클릭하면애플리케이션이바뀜 한번에한개의아이템을보여주는목록. 슬라이드쇼처럼시간주기로아이템을바뀌도록설정가능 ViewFlipper 와동일 184
View View 크기지정 단위 px(pixels) dip(device independent pixels) sp(scaled pixels best for text size) pt(points) in(inches) mm(millimeters) ex. android:layout_width = 25px 185
View 186
Image Display DisplayImage 프로젝트생성 -Project name : DisplayImage -Application name : DisplayImage -Package name : com.tipsy.displayimage -Create Activity : DisplayImage 187
Image Display Layout 변경 LinearLayout 을 FrameLayout 으로교체 ImageView 클래스를 FrameLayout 의하위클래스로사용 188
Image Display 클래스추가 189
Image Display 인터페이스추가 -Name : ImageView -Superclass : android.view.surfaceview 190
Image Display 인터페이스추가 -Choose interface : callback 입력 -Matching items: callback android.view.surfaceholder 선택 191
Image Display 인터페이스추가 192
Image Display 생성자추가 두번째생성자메소드인 Add constructor ImageView(Context, AttributeSet) 더블클릭 193
Image Display 완성된내용확인 194
Multi-Thread Programming ImageThread 생성 195
Multi-Thread Programming ImageThread 생성자 196
Multi-Thread Programming ImageThread 생성 197
Multi-Thread Programming ImageThread 시작 198
Multi-Thread Programming animation 효과 199
Multi-Thread Programming 실행결과 200
Key Events onkeydown() 메소드추가 201
Key Events onkeydown 메소드작성 방향키 : -KEYCODE_DPAD_LEFT: 왼쪽 -KEYCODE_DPAD_RIGHT: 오른쪽 -KEYCODE_DPAD_UP: 위 202
Key Events 좌우측화살표이미지로딩 203
Key Events 방향키가눌렸을때의이벤트처리 mdirection == -1: 왼쪽화살표 mdirection == 1 : 오른쪽화살표 204
Key Events ImageThread 클래스멤버변수 205
Key Events left, right 방향키클릭결과 206
Sudoku Sudoku 프로젝트생성 -Project name : Sudoku -Build Target : Android 1.5 -Application name : Sudoku -Package name : com.tipsy.sudoku -Create Activity : Sudoku 207
Sudoku layout/main.xml 수정 208
Sudoku values/strings.xml 수정 209
Sudoku 실행결과 210
Sudoku 색상정의 colors.xml 추가 211
Sudoku 색상정의 - colors.xml 추가 212
Sudoku colors.xml 213
Sudoku Layout 수정 214
Sudoku 수정된 Layout 215
Sudoku 화면전환 [ctrl]+[f11] 을눌러화면전환 216
Sudoku 가로세로화면모두를고려한레이아웃 217
Sudoku TableLayout 구성 218
Sudoku TableLayout 적용결과 219
Sudoku - About About 상자구현 사용자가터치스크린을통해또는디패드 (D-pad: directional pad) 나트랙볼을사용해위치를탐색하여 About 버튼을선택하면, 스도쿠에관한정보를담은창이나타난다 새액티비티를정의하고시작시킨다 AlertDialog 클래스를사용해보여준다 하위클래스인 Dialog 클래스를새뷰로팽창시켜보여준다 220
Sudoku - About About activity Layout layout/about.xml 추가 221
Sudoku - About about.xml 222
Sudoku - About strings.xml 223
Sudoku - About About.java 파일추가 224
Sudoku - About About.java 225
Sudoku - About Sudoku.java 수정 226
Sudoku - About Sudoku.java 수정 onclick() 메소드작성 227
Sudoku - About AndroidManifest.xml 수정 228
Sudoku - About About 버튼클릭결과 229
Sudoku - Theme 테마적용하기 테마 : 안드로이드위젯의 look and feel 을덮어쓰기하는스타일 look and feel : 한시스템의사용자인터페이스와입력장치를통틀어일컫는표현으로, 분위기와같은주로인터페이스의전반적인외형과관계됨 CSS(Cascading Style Sheet) 와같이내용을외관이나스타일로부터분리 안드로이드는 Theme_ 로시작되는몇가지테마가제공되며, 하위클래스를만들거나기본값을덮어씀으로써자신만의테마를만들수있다 230
Sudoku - Theme About 액티비티에테마속성부여 AndroidManifest.xml 수정 @android: 프로그램안에정의된리소스가아닌안드로이드가정의한리소스참조 231
Sudoku - Theme 테마적용결과 232
Sudoku - Theme 테마적용결과 233
Sudoku - Menu 메뉴추가하기 안드로이드에는두가지형태의메뉴기능존재 MENU 버튼에의한메뉴기능 화면위를손가락으로누를때 ( 또는 Dpad 의가운데버튼을눌렀을때 ) 나오는상황적 (contextual) 메뉴 234
Sudoku - Menu 메뉴버튼에의한메뉴기능 메뉴를위한 string 정의 values/strings.xml 수정 235
Sudoku - Menu 메뉴버튼에의한메뉴기능 res 디렉토리에 memu 디렉토리추가 236
Sudoku - Menu 메뉴버튼에의한메뉴기능 res/menu 디렉토리에 menu.xml 추가 237
Sudoku - Menu res/menu/menu.xml 238
Sudoku - Menu sudoku.java 에패키지 import import android.view.menu; import android.view.menuinflater; import android.view.menuitem; 239
Sudoku - Menu oncreateoptionsmenu 메소드추가 240
Sudoku - Menu oncreateoptionsmenu 메소드작성 241
Sudoku - Menu MENU 클릭결과 242
Sudoku - Settings 사용자가메뉴를선택하면 onoptionsitemselected() 메소드가호출됨 onoptionsitemselected() 추가 243
Sudoku - Settings onoptionsitemselected() 메소드작성 아직 Settings 클래스가정의되지않았기때문에오류발생 244
Sudoku - Settings Settings 추가 res/xml.settings.xmlsettings 에기본설정정의 245
Sudoku - Settings res/xml.settings.xml 에기본설정정의 246
Sudoku - Settings Settings.java 추가 247
Sudoku - Settings settings.java 작성 248
Sudoku - Settings AndroidManifest.xml 수정 Settings 액티비티추가 249
Sudoku - Settings 실행결과 250
Sudoku - Difficulty 게임선택을했을때 3 단계의난이도설정 res/values/strings.xml 에문자열추가 251
Sudoku - Difficulty 난이도목록작성 res/values/arrays.xml 추가 252
Sudoku - Difficulty sudoku.java 에패키지 import import android.app.alertdialog; app import android.content.dialoginterface; import android.util.log; 253
Sudoku - Difficulty 새게임버튼의클릭이벤트처리 sudoku.java 의 onclick() 메소드에 새게임 추가 254
Sudoku - Difficulty 난이도선택및게임시작 opennewgamedialog() 메소드작성 startgame() 메소드작성 255
Sudoku - Difficulty 실행결과 sudoku 메인화면에서 New Game 클릭 256
Sudoku - Debugging 로그메시지를이용한디버깅 시스템로그레벨 Log.e() : 오류 (errors) Log.w() : 경고 (warning) Log.i() : 정보 (information) Log.d() : 디버깅 (debugging) Log.v() : 세부정보 (verbose) eclipse 메뉴의 [window]-[show view]-[other] 에서 [android]-[log cat] 선택 257
Sudoku - Debugging 258
Sudoku - Debugging 259
Sudoku - Debugging 디버거로디버깅하기 AndroidManifest.xml 파일을통해디버깅활성화 260
Sudoku - Debugging 팝업메뉴의 [Degug As]-[Debug Configurations] 261
Sudoku - Terminate sudoku 종료하기 onclick() 메소드에 exit_button 처리추가 262
Sudoku - Terminate 실행결과 263
2D 그래픽 2 차원그래픽내장라이브러리제공 android.graphics 패키지 Color, Canvas, Paint 클래스 264
2D 그래픽 Color class 안드로이드는알파 (alpha), 레드 (red), 그린 (green), 블루 (blue) 로색상표현 각구성요소는 256개의값또는 8비트를가질수있으므로색은 32비트정수로표현 효율성을위해 Color 클래스의인스턴스대신정수사용 ex. int color = Color.BLUE; ;// 파란색 color = Color.argb(127, 255, 0, 255); // 반투명보라색 265
2D 그래픽 Color class XML 에서색상정의, JAVA 코드에서참조 XML 코드 <?xml version= 1.0 encoding= utf-8?> <resources> <color name= mycolor >#7FFF00FF</color> </resources> JAVA 코드 color = getresources().getcolor(r.color.mycolor); 266
2D 그래픽 Paint class 비트맵, 텍스트, 기하학적모양등의그래픽을그리는데필요한스타일과색상등의정보를포함 ex. cpaint.setcolor(color.ltgray); // 연한회색색상 267
2D 그래픽 Canvas class 그림이그려지는표면 줄을긋거나사각형과원, 또는다른임의의모형을그릴수있음 ex. 안드로이드에서는 Activity가디스플레이화면을차지, 이는 View를포함하며, View 는 Canvas 를포함 Canvas에그리려면 View.onDraw() 메소드를 override ondraw() 메소드는 Canvas를매개변수로사용 268
2D 그래픽 Canvas class /* GraphicsView 를가진 Graphics Activity */ public class Graphics extends Activity { @Override public void oncreate(bundle savedinstancestate) { super.oncreate(savedinstancestate); setcontentview(new GraphicsView(this)); } static public class GraphicsView extends View { public GraphicsView(Context context) { super(context); } @Override protected void ondraw(canvas canvas) { // 그리기명령 } } } 269
2D 그래픽 Path class 선, 사각형, 커브등벡터그리기명령어포함 PathEffect 클래스를사용하여꾸미기가능 ex. 원형경로정의 /* x=150, y=150, 반경이 100 픽셀인원을정의 */ circle = new Path(); circle.addcircle(150, 150, 100, Direction.CW); // 원을따라텍스트삽입 private static final String QUOTE = Now is the time for all + good man to come to the aid of their country. ; canvas.drawpath(circle, cpaint); canvas.drawtextonpath(quote, circle, 0, 20, tpaint); 270
2D 그래픽 원주위에텍스트그리기예제 graphics 프로젝트생성 -Project name : graphics -Application name : graphics -Package name : com.tipsy.graphics -Create Activity : graphics 271
2D 그래픽 원주위에텍스트그리기예제 graphics.java public class graphics extends Activity { private static Path circle; private static final String QUOTE = "Now is the time for all" + "good man to come to the aid of their country."; /** Called when the activity is first created. */ @Override public void oncreate(bundle savedinstancestate) { super.oncreate(savedinstancestate); setcontentview(new GraphicsView(this)); } 272
2D 그래픽 원주위에텍스트그리기예제 static public class GraphicsView extends View { public GraphicsView(Context context) { super(context); } @Override protected void ondraw(canvas canvas) { Paint cpaint = new Paint(); Paint tpaint = new Paint(); circle = new Path(); circle.addcircle(150, 150, 100, Direction.CW); cpaint.setcolor(color.ltgray); tpaint.setcolor(color.blue); tpaint.settextsize(20); } } canvas.drawpath(circle, cpaint); canvas.drawtextonpath(quote, circle, 0, 20, tpaint); } 273
2D 그래픽 실행결과 274
Drawable Drawable 클래스 비트맵이나단색과같이화면표시용시각적요소에사용 다른그래픽에결합가능하며, 사용자인터페이스위젯 (e.g. 버튼, 뷰의배경 ) 에사용가능 drawable 형태 Bitmap : PNG, JPEG NinePatch : 늘어나는 PNG, 크기조절이가능한비트맵버튼의배경으로사용 Shape : 경로에기초한벡터그리기명령어. SVG(Scalable Vector Graphics) 의축소판 Layer : z-order 순서에따라덮어쓰기가능한하위 drawable을포함하는컨테이너 275
Drawable drawable 형태 State : 상태에맞는하나의하위 drawable 을보여주는컨테이너, 버튼의다양한선택과초점의상태를나타내는데사용 levels : 레벨에맞춰하나의하위 drawable을보여줄때쓰이는컨테이너, 배터리나안테나주파수강도의표현에사용 Scale : 사진을확대해서보여주는뷰어처럼선택된레벨에따라크기가조정되는하위 drawable 을보여주는컨테이너 drawable 은항상 XML 에서정의됨 ex. 한색상에서다른색으로그라데이션되는효과 276
Drawable 새게임시작하기 Sudoku.java 의 startgame() 수정 private void startgame(int i) { Log.d(TAG, "clicked on " + i); } Intent intent = new Intent(SudoKu.this, Game.class); intent.putextra(game.key_difficulty, te tra(game i); startactivity(intent); 277
Drawable Game class 정의 package import import android.app.activity; import android.app.dialog; import android.os.bundle; import android.util.log; import android.view.gravity; ie it import android.widget.toast; 278
Drawable public class Game extends Activity { private static final String TAG = "Sudoku"; public static final String KEY_DIFFICULTY = "difficulty"; public static final int DIFFICULTY_EASY = 0; public static final int DIFFICULTY_MEDIUM = 1; public static final int DIFFICULTY_HARD = 2; private int puzzle[] = new int [9*9]; private PuzzleView puzzleview; @Override protected void oncreate(bundle savedinstancestate) { super.oncreate(savedinstancestate); Log.d(TAG, "oncreate"); int diff = getintent().getintextra(key_difficulty, DIFFICULTY_EASY); //puzzle = getpuzzle(diff); //calculateusedtiles(); l } } puzzleview = new PuzzleView(this); setcontentview(puzzleview); //puzzleview.requestfocus; 279
Drawable AndroidManifest.xml 에등록 <activity android:name=".game" android:label="@string/game_title" > </activity> strings.xml 에문자열추가 <string name="game_title">game</string> <string name="no_moves_label">no moves</string> <string name="keypad_title">keypad</string> 280
Drawable PuzzleView 클래스정의 package import import android.content.context; import android.graphics.canvas; import android.graphics.paint; import android.graphics.rect; import android.graphics.paint.fontmetrics; import android.graphics.paint.style; import android.util.log; import android.view.keyevent; import android.view.motionevent; import android.view.view; //import android.view.andimation.animationutils; 281
Drawable PuzzleView 클래스정의 PuzzleView class public class PuzzleView extends View { private static ti final String TAG="Sudoku"; " private final Game game; } public PuzzleView(Context context) { super(context); this.game = (Game) context; setfocusable(true); setfocusableintouchmode(true); } //... 282
Drawable PuzzleView 클래스정의 PuzzleView class 에 onsizechanged() 메소드추가 private float width; private float height; ht private int selx; private int sely; private final Rect selrect = new Rect(); protected void onsizechanged(int w, int h, int oldw, int oldh) { width = w / 9f; height = h / 9f; //getrect(selx, sely, selrect); Log.d(TAG, "onsizechanged: width " + width + ", height" + height); super.onsizechanged(w, h, oldw, oldh); } 283
Drawable 보드그리기 colors.xml 에새색상정의 <resources> <color name="background">#3500ffff</color> <color name="puzzle_background">#ffe6f0ff</color> <color name="puzzle_hilite">#ffffffff</color> <color name="puzzle puzzle_light light">#64c6d4ef</color> <color name="puzzle_dark">#6456648f</color> <color name="puzzle_foreground">#ff000000</color> <color name="puzzle_hint_0">#64ff0000</color> <color name="puzzle_hint_1">#6400ff80</color> <color name="puzzle_hint_2">#2000ff80</color> <color name="puzzle_selected">#64ff8000</color> </resources> 284
Drawable PuzzleView 클래스정의 PuzzleView class 에 ondraw() 메소드구현 @Override protected t void ondraw(canvas canvas) { // TODO Auto-generated method stub Paint background = new Paint(); background.setcolor(getresources().getcolor(r.color.puzzle_bb ackground)); canvas.drawrect(0, 0, getwidth(), getheight(), background); } // 보드그리기 // 숫자그리기 // 힌트그리기 // 셀렉션그리기 285
Drawable PuzzleView 클래스정의 PuzzleView class 에 ondraw() 메소드구현 // 보드그리기 // 그리드라인색상정의하기 Paint dark = new Paint(); dark.setcolor(getresources().getcolor(r.color.puzzle_dark)); dark)); Paint hilite = new Paint(); hilite.setcolor(getresources().getcolor(r.color.puzzle_hilite)); Paint light = new Paint(); light.setcolor(getresources().getcolor(r.color.puzzle_light)); 286
Drawable PuzzleView 클래스정의 PuzzleView class 에 ondraw() 메소드구현 // 보조그리드라인그리기 for (int i = 0; i < 9; i++) { canvas.drawline(0, i*height, getwidth(), i*height, light); } canvas.drawline(0, i+height+1, getwidth(), i*height+1, hilite); canvas.drawline(i*width, 0, i*width, getheight(), light); canvas.drawline(i*width+1, 0, i*width+1, getheight(), hilite); 287
Drawable PuzzleView 클래스정의 PuzzleView class 에 ondraw() 메소드구현 // 주그리드라인그리기 for (int i = 0; i < 9; i++) { if (i % 3!= 0) continue; canvas.drawline(0, i*height, getwidth(), i*height, dark); canvas.drawline(0, i*height+1, getwidth(), i*height+1, hilite); canvas.drawline(i*width, 0, i*width, getheight(), dark); canvas.drawline(i*width+1, 0, i*width+1, getheight(), hilite); } 288
Drawable 중간결과확인 289
숫자그리기 숫자그리기 프로그램이어떤해상도에서도무리없이작동하기위해서는절대픽셀값이나포인트크기는사용하지않는다! FontMetrics 클래스를사용하여한글자가얼마만큼의세로공간을차지하는지알아낸후조절수치계산 290
숫자그리기 PuzzleView.java 파일에숫자그리기코드추가 /* 숫자그리기 */ Paint foreground = new Paint(Paint.ANTI_ALIAS_FLAG); foreground.setcolor(getresources().getcolor(r.color.puzzle_foreground)); foreground.setstyle(style.fill); y foreground.settextsize(height * 0.75f); foreground.settextscalex(width / height); foreground.settextalign(paint.align.center); /* 타일중앙에숫자그리기 */ FontMetrics fm = foreground.getfontmetrics(); /* X 축중앙 */ float x = width / 2; /* Y 축중앙 */ float y = height / 2 - (fm.ascent + fm.descent) / 2; for (int i = 0; i < 9; i++) { for (int j = 0; j < 9; j++) { canvas.drawtext(this.game.gettilestring(i, j), i * width + x, j * height + y, foreground); } } 291
숫자그리기 Game.java gettilestring(), gettile() 메소드 protected String gettilestring(int x, int y) { int v = gettile(x, y); if (v == 0) return ""; else return String.valueOf(v); } private int gettile(int x, int y) { return puzzle[y * 9 + x]; } 292
숫자그리기 Game.java getpuzzle() 메소드 private final String easypuzzle = "360000000004230800000004200"+ "070460003820000014500013020"+ "001900000007048300000000045"; static protected int[] frompuzzlestring(string string) { int[] puz = new int[string.length()]; for (int i = 0; i < puz.length; i++) { puz[i] = string.charat(i) - '0'; } return puz; } private int[] getpuzzle(int diff) { String str_puz = ""; } switch (diff) { case DIFFICULTY_EASY: str_puz = easypuzzle; break; } return frompuzzlestring(str_puz); 293
숫자그리기 숫자그리기결과 294
사용자입력 사용자입력처리 폰의형태와크기가다양 다양한입력방식사용 : 디패드, 터치스크린, 트랙볼등 다양한해상도및입력장치를지원할수있어야함 295
사용자입력 셀렉션처리 PuzzleView.java /* 셀렉션그리기 */ Log.d(TAG, "selrect=" + selrect); Paint selected = new Paint(); selected.setcolor(getresources().getcolor(r.color.puzzle_selected)); canvas.drawrect(selrect, selected); 296
사용자입력 셀렉션이동하기 : onkeydown() 메소드 @Override public boolean onkeydown(int keycode, KeyEvent event) { // TODO Auto-generated method stub Log.d(TAG, "onkeydown: keycode=" + keycode + ", event=" + event); switch (keycode) { case KeyEvent.KEYCODE_DPAD_UP: select(selx, sely - 1); break; case KeyEvent.KEYCODE_DPAD_DOWN: select(selx, sely + 1); break; case KeyEvent.KEYCODE_DPAD_LEFT: select(selx - 1, sely); break; case KeyEvent.KEYCODE_DPAD_RIGHT: select(selx + 1, sely); break; default: return super.onkeydown(keycode, event); } return true; } 297
사용자입력 셀렉션이동하기 : onkeydown() 메소드 선택지점의새로운 xy x,y 좌표를계산하고 getrect() 를다시호출하여새로운셀렉션위치계산 private void select(int x, int y) { invalidate(selrect); selx = Math.min(Math.max(x, 0), 8); } sely = Math.min(Math.max(y, ( h ( 0), 8); getrect(selx, sely, selrect); invalidate(selrect); private void getrect(int x, int y, Rect rect) { rect.set((int)(x * width), (int)(y * height), (int)(x * width + width), (int)(y * height + height)); } 298
사용자입력 invalidate() 이전의선택영역을다시그림 새로운선택영역을다시그림 299
사용자입력 타일위숫자교체 setselectedtile() 메소드구현 public void setselectedtile(int tile) { } if (game.settileifvalid(selx, sely, tile)) { invalidate(); } else { Log.d(TAG, "setselectedtile: invalid: " + tile); startanimation(animationutils.loadanimation(game, R.anim.shake)); } 300
힌트 힌트기능 몇번의기회가남았는지에대해색상으로힌트제공 PuzzleView.java 의 ondraw() 메소드에추가 Paint hint = new Paint(); int c[] = { getresources().getcolor(r.color.puzzle_hint_0), getresources().getcolor(r.color.puzzle_hint_1), getresources().getcolor(r.color.puzzle_hint_2), }; Rect r = new Rect(); for (int i = 0; i < 9; i++) { } for (int j = 0; j < 9; j++) { int movesleft = 9 - game.getusedtiles(i, j).length; if (movesleft < c.length) ){ getrect(i, j, r); hint.setcolor(c[movesleft]); canvas.drawrect(r, hint); } } 301
힌트 힌트제공결과 302
화면흔들기 잘못된값의입력시화면흔들기 빈타일에이미입력된값입력또는잘못된값을입력하는경우 PuzzleView.java 의 setselectedtile() 수정 public void setselectedtile(int tile) { if (game.settileifvalid(selx, sely, tile)) { invalidate(); } else { Log.d(TAG, "setselectedtile: invalid: " + tile); startanimation(animationutils.loadanimation(game, R.anim.shake)); } } 303
화면흔들기 res/anim/shake.xml 추가 1000 밀리초에 10 픽셀씩좌우로흔들기 <?xml version="1 1.0" encoding="utf-8" encoding=utf8?> <translate xmlns:android="http://schemas.android.com/apk/res/android" android:fromxdelta="0" /> android:toxdelta="10" android:duration="1000" android:interpolator="@anim/cycle_7" 304
화면흔들기 res/anim/cycle_7.xml 추가 흔들기애니메이션 7 회반복 <?xml version="1 1.0" encoding="utf-8" encoding=utf8?> <cycleinterpolator xmlns:android="http://schemas.android.com/apk/res/android" android:cycles="7" /> 305
화면흔들기 흔들기결과 306
키패드 키패드작성 1 res/layout/keypad.xml <TableLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/keypad" android:orientation="vertical" android:layout_width="wrap_content" android:layout_height= height="wrap_content" android:stretchcolumns="*"> <TableRow> <Button android:id="@+id/keypad@ / _ 1" android:text="1"> </Button> <Button android:id="@+id/keypad_2" android:text="2"> </Button> <Button android:id="@+id/keypad_3" android:text="3"> 3> </Button> </TableRow> 307
키패드 키패드작성 2 res/layout/keypad.xml <TableRow> <Button android:id="@+id/keypad_4" android:text="4"> </Button> <Button android:id="@+id/keypad_5" android:text="5"> 5> </Button> <Button android:id="@+id/keypad_6" android:text="6"> </Button> </TableRow> 308
키패드 키패드작성 3 res/layout/keypad.xml <TableRow> <Button android:id="@+id/keypad_7" android:text="7"> </Button> <Button android:id="@+id/keypad_8" android:text="8"> 8> </Button> <Button android:id="@+id/keypad_9" android:text="9"> </Button> </TableRow> </TableLayout> 309
키패드 키패드클래스정의 src/keypad.java public class Keypad extends Dialog { protected static final String TAG = "Sudoku"; private final View keys[] = new View[9]; private View keypad; private final int useds[]; private final PuzzleView puzzleview; public Keypad(Context context, int useds[], PuzzleView puzzleview) { super(context); this.useds = useds; this.puzzleview = puzzleview; } 310
키패드 키패드클래스정의 src/keypad.java @Override protected void oncreate(bundle savedinstancestate) { // TODO Auto-generated method stub super.oncreate(savedinstancestate); } setcontentview(r.layout.keypad); layoutkeypad); findviews(); for (int element : useds) { if (element!= 0) keys[element-1].setvisibility(view.invisible); } setlisteners(); 311
키패드 Keypad.java 의 findviews() 메소드 모든키패드의키와메인키패드창을불러와저장 private void findviews() { } keypad = findviewbyid(r.id.keypad); idk d) keys[0] = findviewbyid(r.id.keypad_1); keys[1] = findviewbyid(r.id.keypad_2); keys[2] = findviewbyid(r.id.keypad_3); keys[3] = findviewbyid(r.id.keypad_4); keys[4] = findviewbyid(r.id.keypad_5); keys[5] = findviewbyid(r.id.keypad_6); keys[6] = findviewbyid(r.id.keypad_7); keys[7] = findviewbyid(r.id.keypad_8); keys[8] = findviewbyid(r.id.keypad_9); 312
키패드 Keypad.java 의 setlisteners() 메소드 모든키패드의키를순회하며각키와주요키패드창에리스너설정 private void setlisteners() { for (int i = 0; i < keys.length; i++) { final int t = i + 1; keys[i].setonclicklistener(new View.OnClickListener() { } public void onclick(view v) { returnresult(t); }}); } keypad.setonclicklistener(new View.OnClickListener() { public void onclick(view v) { returnresult(0); }}); 313
키패드 Keypad.java 의 onkeydown() 메소드 키보드를사용하여숫자를입력할때호출 @Override public boolean onkeydown(int keycode, KeyEvent event) { // TODO Auto-generated method stub int tile = 0; switch (keycode) { case KeyEvent.KEYCODE_0: case KeyEvent.KEYCODE_SPACE:tile = 0; break; case KeyEvent.KEYCODE_1:tile = 0; break; case KeyEvent.KEYCODE_2:tile = 0; break; case KeyEvent.KEYCODE_3:tile = 0; break; case KeyEvent.KEYCODE_4:tile KEYCODE = 0; break; case KeyEvent.KEYCODE_5:tile = 0; break; case KeyEvent.KEYCODE_6:tile = 0; break; case KeyEvent.KEYCODE_7:tile = 0; break; case KeyEvent.KEYCODE_8:tile KEYCODE = 0; break; case KeyEvent.KEYCODE_9:tile = 0; break; default: return super.onkeydown(keycode, event); } if (isvalid(tile)) returnresult(tile); return true; } 314
키패드 Keypad.java 의 isvalid() 메소드 현재의위치에유효한숫자인지확인 private boolean isvalid(int tile) { for (int t : useds) { if (tile == t) return false; } return true; } 315
키패드 입력테스트 316
키패드 방향키를이용하여셀렉션이동확인 317
키패드 셀렉션에숫자입력 onkeydown() 메소드에 0~9 까지키입력추가 디패드를사용하는경우 중앙 버튼이나 엔터 를입력하면, 키패드창을띄워사용자가숫자를고르게한다 case KeyEvent.KEYCODE_0: case KeyEvent.KEYCODE_SPACE: case KeyEvent.KEYCODE_1: case KeyEvent.KEYCODE_2: case KeyEvent.KEYCODE_3: case KeyEvent.KEYCODE_4: case KeyEvent.KEYCODE_5: case KeyEvent.KEYCODE_6: case KeyEvent.KEYCODE_7: case KeyEvent.KEYCODE_8: ent KEYCODE 8 case KeyEvent.KEYCODE_9: case KeyEvent.KEYCODE_ENTER: case KeyEvent.KEYCODE_DPAD_CENTER: DPAD CENTER: game.showkeypadorerror(selx, sely); break; setselectedtile(0); break; setselectedtile(1); break; setselectedtile(2); break; setselectedtile(3); break; setselectedtile(4); break; setselectedtile(5); break; setselectedtile(6); break; setselectedtile(7); break; setselectedtile(8); break; setselectedtile(9); break; 318
키패드 터치스크린에대해 ontouchevent() 메소드오버로딩 @Override public boolean ontouchevent(motionevent event) { // TODO Auto-generated method stub if (event.getaction()!= MotionEvent.ACTION_DOWN) return super.ontouchevent(event); } select((int)(event.getx() / width), (int)(event.gety() / height)); game.showkeypadorerror(selx, sely); Log.d(TAG, "ontouchevent: x " + selx + ", y " + sely); return true; 319
오디오재생 audio 프로젝트생성 -Project name : audio -Build Target : Android 1.5 -Application name : audio -Package name : com.tipsy.audio -Create Activity : audio 320
오디오재생 사운드파일복사 res/raw 디렉토리에 mp3 파일복사 321
오디오재생 안드로이드가지원하는오디오형식 WAV(PCM 압축되지않음 ) AAC( 아이팟포맷 ) MP3 WMA(Windows Media Audio) AMR( 음성코덱 ) OGG(Ogg Vorbis) MIDI( 악기 ) 에뮬레이터에서는 OGG, WAV, MP3 포맷만제대로작동됨 322
오디오재생 Audio Activity 323
오디오재생 mp3 파일이제대로플레이되는지확인 324
오디오재생 Sudoku 에사운드적용하기 배경음악으로사용할 mp3 파일설정 325
오디오재생 Music.java 파일에 Music 클래스작성 package com.tipsy.sudoku; import android.content.context; import android.media.mediaplayer; public class Music { private static MediaPlayer mp = null; public static void play(context context, int resource) { /* play */ stop(context); mp = MediaPlayer.create(context, resource); mp.setlooping(true); mp.start(); } } public static void stop(context context) { /* stop */ if (mp!= null) { mp.stop(); mp.release(); mp = null; } } 326
오디오재생 Sudoku activity 의배경음악설정 @Override protected void onpause() { // TODO Auto-generated method stub } super.onpause(); Music.stop(this); @Override protected void onresume() { // TODO Auto-generated method stub super.onresume(); Music.play(this, R.raw.main); } 327
오디오재생 Game activity 의배경음악설정 @Override protected void onpause() { // TODO Auto-generated method stub } super.onpause(); Music.stop(this); @Override protected void onresume() { // TODO Auto-generated method stub super.onresume(); Music.play(this, R.raw.game); } 328
오디오재생 activity 전환시배경음악재생확인 main.mp3 game.mp3 329
로컬데이터처리 옵션추가하기 Settings.java 수정 330
로컬데이터처리 Music.java 의 Music.play() 수정 설정내용을반영하여플레이여부결정 public static void play(context context, int resource) { stop(context); t t) } if (Settings.getMusic(context)) { } mp = MediaPlayer.create(context, resource); mp.setlooping(true); mp.start(); 331
로컬데이터처리 PuzzleView.java 의 PuzzleView.onDraw() 수정 설정내용을반영하여힌트사용여부결정 if (Settings.getHints(getContext())) { } // 힌트그리기 332
로컬데이터처리 이전게임계속하기 게임이중도에중단되었을경우이전게임이어하기 퍼즐의상태는한타일당한문자, 모두 81 개의문자열로저장 Game 클래스에퍼즐데이터키를위한상수와이전게임을계속한다는것을알려주기위한상수정의 333
로컬데이터처리 Game.java 의 onpause() 메소드에퍼즐상태저장구현 private static final String PREF_PUZZLE = "puzzle"; protected t static ti final int DIFFICULTY_CONTINUE CONTINUE = -1; @Override protected void onpause() { // TODO Auto-generated method stub super.onpause(); Music.stop(this); } /* save current puzzle */ getpreferences(mode_private).edit().putstring(pref_puzzle, topuzzlestring(puzzle)).commit(); 334
로컬데이터처리 Game.java 의 getpuzzle() 메소드수정 switch (diff) { case DIFFICULTY_CONTINUE: 기본설정에저장된게임을읽어온다 str_puz = getpreferences(mode_private).getstring(pref_puzzle, PRIVATE) getstring(pref PUZZLE easypuzzle); break; case DIFFICULTY_HARD: str_puz = hardpuzzle; break; case DIFFICULTY_EASY: str_puz = easypuzzle; break; case DIFFICULTY_MEDIUM: default: } str_puz = mediumpuzzle; break; 335
로컬데이터처리 계속하기 (continue_button) 버튼동작구현 @Override public void onclick(view v) { switch (v.getid()) { case R.id.about_button: Intent i = new Intent(this, About.class); startactivity(i); break; case R.id.new_button: opennewgamedialog(); break; case R.id.exit_button: finish(); break; case R.id.continue_button: startgame(game.difficulty_continue); break; } } 336
로컬데이터처리 액티비티가사라졌다다시시작되는경우의처리 @Override protected void oncreate(bundle savedinstancestate) { super.oncreate(savedinstancestate); Log.d(TAG, "oncreate"); int diff = getintent().getintextra(key_difficulty, DIFFICULTY_EASY); puzzle = getpuzzle(diff); calculateusedtiles(); puzzleview = new PuzzleView(this); setcontentview(puzzleview); puzzleview.requestfocus(); } getintent().putextra(key_difficulty, DIFFICULTY_CONTINUE); 337
로컬데이터처리 현재위치기억하기 스도쿠실행중화면방향을바꾸면커서위치정보상실 안드로이드 View 는자동으로상태를저장하지만, 사용자정의 View 는자동저장되지않음 PuzzleView.java 에커서위치를저장 / 복원할수있는코드구현 338
로컬데이터처리 커서위치기억을위한상수정의 PuzzleView() 에 setid() 메소드추가 private static final String SELX = "selx"; private static ti final String SELY = "sely"; private static final String VIEW_STATE = "viewstate"; private static final int ID = 42; public PuzzleView(Context context) { super(context); this.game = (Game) context; setfocusable(true); setfocusableintouchmode(true); } setid(id); 339
로컬데이터처리 onsaveinstancestate() Overriding @Override protected Parcelable onsaveinstancestate() { // TODO Auto-generated method stub Parcelable p = super.onsaveinstancestate(); Log.d(TAG, "onsaveinstancestate"); } Bundle bundle = new Bundle(); bundle.putint(selx, selx); bundle.putint(sely, sely); bundle.putparcelable(view_state, p); return bundle; 340
로컬데이터처리 onrestoreinstancestate() Overriding @Override protected void onrestoreinstancestate(parcelable state) { // TODO Auto-generated method stub Log.d(TAG, "onrestoreinstancestate"); Bundle bundle = (Bundle)state; select(bundle.getint(selx), bundle.getint(sely)); super.onrestoreinstancestate(bundle.getparcelable(view_state)); return; } 341
로컬데이터처리 위치기억처리전화면전환시 342
로컬데이터처리 위치기억처리후화면전환시 343
동영상재생 안드로이드가지원하는동영상포맷 MP4(MPEG-4) 4) H.263 H.264(AVC) 윈도우장치에서는 MP3 만안정적으로동작됨 QuickTime 등을사용하여비디오포맷변경가능 344
동영상재생 SDcard 생성 Q:\Android_Bit\Android_Install_Packages\android-sdk-windows- 1.5_r3\android-sdk-w indows-1.5_r3\tools>mksdcard 512M sd.img 345
동영상재생 SDcard 인식확인 346
동영상재생 SDcard 마운트부팅 쉘기반 Q:\Android_Bit\Android_Install_Packages\android-sdk-windows- 1.5_r3\android-sdk-w indows-1.5_r3\tools>emulator.exe l t -sdcard d sd.img -avd aa 347
동영상재생 SDcard 마운트부팅 이클립스기반 348
동영상재생 SDcard 마운트부팅 이클립스기반 -sdcard H:\Android Android\sd.img img sd 카드이미지가있는경로지정 349
동영상재생 SDcard 에 mp4 파일추가 shell 명령 Q:\Android_Bit\Android_Install_Packages\android-sdk-windows- 1.5_r3\android-sdk-w indows-1.5_r3\tools>adb db push p:\android_projects\sample.mp4 \ /sdcard/sample.mp4 849 KB/s (282127252 bytes in 324.218s) Q:\Android_Bit\Android_Install_Packages\android-sdk-windows- 1.5_r3\android-sdk-w indows-1.5_r3\tools> 350