2. 2
Tổng quan hệ điều hành Android
Đặc điểm
Kiến trúc
Phiên bản
Lập trình trên môi trường Android
Môi trường lập trình
AVD
Quá trình phát triển ứng dụng Android.
Ứng dụng cơ bản Android
Tìm hiểu Android project
Các cách tiếp cận trong lập trình Android.
Nội dung
3. 3
Tập phần mềm dành cho thiết bị di động bao gồm
Một hệ điều hành
Midleware
Các ứng dụng cơ sở
Sử dụng Linux để cung cấp dịch vụ hệ thống lõi
Security
Memory management
Process management
Power management
Hardware drivers
Hệ điều hành mã nguồn mở
Google Android ?
5. 5
Vesion code và version name không giống nhau.
Mỗi version name (platform level) thì có duy nhất một
version code (API level) đi kèm.
Android vesioning
Platform Codename API Level
Android 1.5 Cupcake 3
Android 1.6 Donut 4
Android 2.0
Eclair
5
Android 2.0.1 6
Android 2.1 7
Android 2.2 Froyo 8
Android 2.3
Android 2.3.2
Gingerbread
9
Android 2.3.3
Android 2.3.7
10
Android 3.0, 3.1,3.2 Honeycomb 11, 12, 13
6. 6
Nguồn: Android developer, Oct 3, 2011
Version distribution
http://developer.android.com/resources/dashboard/platform-versions.html
7. 7
Chuẩn bị môi trường trên PC
Cài đặt JDK
http://www.oracle.com/technetwork/java/javase/downloads/in
dex.html
Nếu dùng Eclipse để phát triển ứng dụng thì download
một phiên bản Eclipse
http://www.eclipse.org/downloads/
Download SDK Start package
http://developer.android.com/sdk/index.html
Giải nén thư mục này vào ổ đĩa, nhớ note lại thư mục
để tham chiếu trong bước cài đặt Eclipse.
Installling Android SDK
8. 8
Cài đặt ADT plugin cho Eclipse
Plugin này gọi là Android Development Tool, hỗ trợ
công cụ để phát triển ứng dụng Android
Mở rộng Eclipse với chức năng
Tạo mới Android project
Tạo ứng dụng UI Android
Test ứng dụng trên emulator Android SDK
Debug ứng dụng dùng Android SDK Tool.
Nếu dùng IDE khác thì không cần cài Eclipse + ADT
plugin!
Installling Android SDK
9. 9
Cài đặt ADT plugin cho Eclipse: Install New Software
Installling Android SDK
11. 11
Add Site, có 2 lựa chọn
Nếu download file zip chứa ADT rồi thì chọn Archive
browse đến file zip (vd: ADT-12.0.0.zip)
Nếu chưa download và muốn cài trực tiếp thì nhập URL
sau vào location
https://dl-ssl.google.com/android/eclipse/
Cuối cùng chọn OK, để thực hiện install ADT
Sau khi cài xong ADT thì restart lại Eclipse!
Installling Android SDK
12. 12
Configuring the ADT Plugin
Bước này cài đặt ADT tham chiếu đến Android SDK mà ở
bước trước đã download và install vào thư mục trên đĩa.
Chọn Window > Preferences trong Eclipse, trong SDK
location, browse đến thư mục Android SDK
Installling Android SDK
Sau bước này
hoàn tất việc
tạo môi
trường để xây
dựng Android
app
13. 13
Emulator là thành phần quan trọng để test ứng dụng
nhưng không thể thay thế hoàn toàn thiết bị thật!
Emulator trên Android được gọi là Android Virtual
Devices (AVDs)
Android SDK và AVD manager cho phép tạo các AVDs
hướng tới bất kỳ phiên bản Android API.
AVD cho phép cấu hình:
Resolution
RAM
SD card
Skin
Hardware khác
Android Emulator & AVD
17. 17
Sử dụng bàn phím của máy tính
Sử dụng pointer máy tính như "finger"
Sử dụng kết nối internet của máy tính
Các button: Home, Menu, Back, Search…
Ctrl + F11: landscape portrait
Alt + Enter: full screen mode
Emulator basic
Hãy bỏ ra ít thời gian để làm quen với
Android Emulator!!!
18. 18
Không hỗ trợ việc gọi và nhận thật sự cuộc gọi
Giả lập cuộc gọi và tin nhắn qua emulator console
Không hỗ trợ
USB connection
Camera/video (input)
Headphone
Battery charge level & AC charging state
Bluetooth
Emulation limitations
Test your app
on an actual
device!
19. 19
Mở chức năng Android SDK và AVD manager trong
Eclipse
Setting up an Emulator
SDK/AVD Manager
20. 20
Mở chức năng Android SDK và AVD manager trong
Eclipse
Setting up an Emulator
21. 21
Chọn New virtual device
Setting up an Emulator
Đặt tên
Chọn platform
Chọn SD card
nếu cần
Chọn skin
HVGA
22. 22
Với project Android đang làm việc, chọn Run (Ctrl +F11),
lúc này emulator đã thiết lập sẽ khởi động.
Lần đầu tiên thời gian khởi động emulator khá lâu (vài
phút ) do phải tạo môi trường virtual Linux system.
Running the app in the emulator
Port number
AVD name
23. 23
Để thuận tiện cho việc coding, build & run thì emulator
khởi động một lần trong suốt quá trình làm việc.
Ta cứ việc code, build và run, khi đó emulator tự động
cập nhật mã lệnh mới, không cần phải restart lại
emulator!
Running the app: emulator
Run Emulator
1 lần cho suốt
phiên làm
việc!
24. 24
Always with the user
Typically have Internet access
Typically GPS enabled
Typically have accelerometer & compass
Many have cameras & microphones
Many apps are free or low-cost
Mobile Devices: Advantages
25. 25
Mobile Devices: Disadv
Limited screen size
Limited battery life
Limited processor speed
Limited and sometimes slow network access
Limited or awkward input: soft keyboard, phone keypad,
touch screen, or stylus
Limited web browser functionality
Range of platforms & configurations across devices
26. 26
Được xây dựng trên Java và SDK mới
Không support một số thư viện Java như Swing &
AWT
Oracle đang kiện Google vi phạm bản quyền!
Java code được biên dịch vào Dalvik byte code (.dex)
Được tối ưu cho thiết bị di động (memory, battery…)
Dalvik VM chạy những file .dex
Android Apps
Mã Java được
biên dịch
sang Dalvik
byte code!
29. 29
New Android Project
Chọn tên project, build target (platform) và package
name
First Android Application
Package name: ký tự
đầu tiên phải chữ
thường, phải có dấu
chấm (2 định danh)
Tên project
platform
Scroll down để thấy
phần package name
30. 30
Toàn bộ Adroid project được khởi tạo từ Eclipse
First Android Application
Chọn Package
Explorer để xem cấu
trúc của ứng dụng
Code Java
Chứa resource
File cấu hình app
32. 32
src/NguyenhagiangActivity.java
Activity của ứng dụng, hiển thị khi ứng dụng chạy
res/layout/main.xml
Định nghĩa layout & widgets cho activity
res/values/strings.xml
Khai báo hằng chuỗi dùng trong chương trình
gen/R.java (Don’t touch!)
File được tạo tự động các ID từ các file *.xml
AndroidManifest.xml
Khai báo tất cả thành phần của app (tất cả các activity).
Tên thư viện cần thiết được dùng trong ứng dụng
Xác định những permission mà ứng dụng được cấp.
Phiên bản, cấu hình…
Important Files
33. 33
Activity là thành phần sẽ hiển thị khi chạy ứng dụng.
Do ứng dụng này đơn giản chỉ có 1 activity nên là activity
chính của ứng dụng!
src/NguyenhagiangActivity.java
35. 35
Khai báo hằng chuỗi dùng trong app
Hỗ trợ Localization
res/values-es/values/strings.xml (Spanish)
res/values-fr/values/strings.xml (French)
…
res/values/string.xml
Nội dung chuỗi
Tên truy cập chuỗi
36. 36
File được tự động khởi tạo với các định danh từ main.xml,
string.xml và các phần khác.
gen/R.java
Không
được chỉnh
sửa!
37. 37
Khai báo tất cả các thành phần của app với system
Phiên bản: version code, version name
Application: icon, name, label…
Tham chiếu đến tên các thư viện mà app có sử dụng
Quy định các permission mà ứng dụng được phép.
AndroidManifest.xml
38. 38
Thiết lập UI cho một activity
Create UI
public class HelloWorldActivity extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
}
main.xml chứa trong thư mục res/layout
39. 39
Tạo một nội dung trực tiếp từ code không dùng XML
Create UI
public class HelloWorldActivity extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
TextView tv = new TextView(this);
tv.setText("Hello, Android");
setContentView(tv);
}
}
40. 40
Tạo button đáp ứng sự kiện click
Basic Event handler
public class HelloWorldActivity extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Button btn = new Button(this);
btn.setText("Click me!");
setContentView(tv);
}
}
41. 41
Khai báo listener để xử lý sự kiện click
Basic Event handler (2)
// thiết lập event click handler
btn.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(
getApplicationContext(),
"Hello World",
Toast.LENGTH_LONG).show();
}
});
43. 43
Java-based
Sử dụng Java để định nghĩa String, layout window, tạo
các GUI, gán event handler, giống như lập trình Swing
XML-based
Sử dụng file XML để định nghĩa String, layout window,
tạo các GUI, gán event handler. Phương thức Java chỉ
đọc layout từ file XML và truyền vào setContentView.
Hybrid
Sử dụng file XML định nghĩa String, layout window, và
tạo GUI control. Sử dụng Java để gán event handler.
Three Main Approaches
44. 44
Java-based approach
public class NguyenHaGiangActivity extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
String message="Message 1";
LinearLayout window = new LinearLayout(this);
TextView txt = new TextView(this);
txt.setText(message);
Button btn = new Button(this);
btn.setText("Button Label");
btn.setOnClickListener(new SomeHandler());
window.addView(txt); window.addView(btn);
setContentView(window);
}// end onCreate
… //(next page)
Code Java
45. 45
Java-based approach
... //(previous page)
private class SomeHandler implements OnClickListener{
@Override
public void onClick(View clickedButton)
{
// doSomething();...
Toast.makeText(getApplicationContext(), "Hello World",
Toast.LENGTH_LONG).show();
} // end onClick
} // end class SomeHandler
} // end class NguyenHaGiangActivity
Code Java
47. 47
Java
XML
Lấy control thông qua IDs
Không sử dụng android:onClick để gán handler
Hybrid approach
public class SomeClass extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Button b = (Button)findViewById(R.id.button_id);
b.setOnClickListener(new SomeHandler());
}
private class SomeHandler implements OnClickListener {
@Override
public void onClick(View clickedButton) {
doSomething(...);
}
} }
49. 49
Approach
Sử dụng Java để định nghĩa chuỗi, layout window, tạo
GUI control, gán trình xử lý sự kiện.
Avantages
Thân thiện với giới Java desktop developer. Giống cách
tiếp cận để xây dựng Swing, SWT, và AWT.
Thuận tiện cho việc xây dựng layout động, tuỳ biến vào
logic lập trình.
Disadvantages
Phần code và phần UI xen lẫn với nhau.
Chỉ thấy được giao diện khi chạy ứng dụng.
Main idea
50. 50
Phần code trong onCreate
Code (Main Method)
String appName = "Demo Java-baed Application";
String windowText = "Press the button";
String buttonLabel = "Show Greeting";
LinearLayout mainWindow = new LinearLayout(this);
mainWindow.setOrientation(LinearLayout.VERTICAL);
setTitle(appName);
TextView label = new TextView(this);
label.setText(windowText); label.setText(windowText);
mainWindow.addView(label);
Button greetingButton = new Button(this);
greetingButton.setText(buttonLabel);
greetingButton.setOnClickListener(new Toaster());
mainWindow.addView(greetingButton);
setContentView(mainWindow);
51. 51
Lớp thực thi interface onClickListener
Code (Main Method)
private class Toaster implements OnClickListener {
@Override
public void onClick(View clickedButton) {
String greetingText = "Hello from Android!";
Toast t = Toast.makeText(getApplicationContext(), greetingText,
Toast.LENGTH_LONG);
t.show();
}
}
54. 54
Approach
Sử dụng file XML để định nghĩa chuỗi, layout window,
tạo UI control và gán event handler
Định nghĩa layout và control in res/layout/main.xml
Định nghĩa các chuỗi trong res/values/strings.xml
Advantages
Dễ quản lý
Dùng visual layout editor của eclipse
Đây là cách tiếp cận được khuyến khích
Disaventages
Việc tạo layout động.
Main Idea
55. 55
res/layout/main.xml
Định nghĩa layout và widget với mô tả XML
<LinearLayout …> define widget </LinearLayout>
Tham chiếu đến chuỗi (strings.xml) với
@string/string_name
Gán event handler với android:onClick
res/value/strings.xml
Định nghĩa chuỗi dùng trong GUI
Java code
Tham chiếu đến layout với R.layout.main
Tham chiếu đến chuỗi với
getString(R.string.string_name)
Tham chiếu đến widget với findViewById(R.id.xyz_id)
More details
res/layout/main.xml
56. 56
Project layout
Tham chiếu đến layout được định nghĩa trong
res/layout/main.xml với R.layout.main
Định nghĩa giao diện và widget. Đôi khi có
phần khai báo event handler.
Tham chiếu đến string định nghĩa trong
res/values/strings.xml với cú pháp
@string/string_name
Định nghĩa chuỗi được dùng trong UI
57. 57
Code (res/layout/main.xml)
Các thuộc tính orientation,
layout_width… được định nghĩa
trong JavaDoc API cho LinearLayout
Chuỗi được định nghĩa trong
res/values/strings.xml
Phương thức này là public
khai báo trong main class,
giá trị trả về là void, có
một tham số là View
58. 58
Code (res/values/strings.xml)
Tên của ứng dụng
Các chuỗi được định nghĩa trong strings.xml được
tham chiếu trong main.xml và java code
main.xml: @string/string_name
Java code: getString(R.string.string_name)
59. 59
Java code
Tham chiếu đến main.xml
Tham chiếu đến chuỗi tên
greeting_text được định
nghĩa trong strings.xml
61. 61
Approach
Sử dụng XML để định nghĩa string, layout window, và UI
widget
Sử dụng Java để gán event handler
Advantages
Tương tự như cách tiếp cận XML-based
Ngoài ra việc gán event handler từ code có thể dễ hiểu
hơn, do event handler cũng là phần java code.
Disadvantages
Khó tạo layout động.
Main idea
62. 62
Code (res/layout/main.xml)
Định nghĩa id cho button để button có
thể được tham chiếu trong Java code
với findViewById(R.id.greetind_button)
Không gán event handler ở đây, do ta
sẽ làm trong java code!
64. 64
Code (java)
Phải thiết lập setContentView
trước khi gọi findViewById, nếu
không sẽ nhận được null
65. 65
Viết ứng dụng basic calculator cho phép tính các phép
toán cơ bản {cộng,trừ, nhân, chia} theo các cách tiếp cận
như sau:
Java based
XML based
Hybrid
Bài tập
68. 68
XML-based
Khai báo layout trong res/layouts/some_layout.xml
Thiết lập thuộc tính XML
Sử dụng visual editor trong Eclipse
Load layout với setContentView(R.layout.some_layout)
Java-based
Tạo thể hiện layout, thiết lập thuộc tính, chèn sub-layout
LinearLayout window = new LinearLayout(this)
// thiết lập các thuộc tính cho window
…
window.addView(widgetOrLayout)
Load với phương thức setContentView(window)
Layout Strategies
69. 69
Mỗi lớp Layout đều có lớp inner là LayoutParams định
nghĩa tham số XML cho layout sử dụng.
Các tham số này có tên android:layout_xyz, thường
dùng để định kích thước và canh lề.
VD:
<LinearLayout
android:layout_width = "match_parent"
android:layout_height= "wrap_content"
android:gravity = "center_horizontal"
android:background = "@color/color_1">
…
</LinearLayout>
XML Layout Attributes
70. 70
Size
android:layout_width, android:layout_height
match_parent: fill the parent space (minus padding)
Phiên bản cũ là fill_parent
wrap_content: kích thước bao nội dung
android:layout_weight:
Giá trị số cho biết tỷ lệ phân chia kích thước
Alignment
android:layout_gravity
Cho biết cách thức canh lề của view ở trong containing
view
android:gravity
Cho biết cách thức text và thành phần bên trong view
được canh lề.
Commonly Used Attributes
71. 71
Alignment (tt)
Giá trị thường dùng
Top, bottom, left, right, center_vertical, center_horizontal,
center, fill_vertical, fill_horizontal, fill, clip_vertical,
clip_horizontal.
Margin (blank space outside)
Android:layout_marginBottom,
android:layout_marginTop, android:layout_marginLeft,
android:layout_marginRight
Units
dp: density-independent pixels (scaled by device resol.)
sp: scaled pixel (font size)
px: pixels, in: inches, mm: milimeters.
Commonly Used Attributes
72. 72
Padding (blank space inside)
android:paddingBottom/Top/Left?Right
Giá trị là con số theo đơn vị unit bên trên
ID
android:id
Sử dụng khi java code cần tham chiếu đến view
Sử dụng trong RelativeLayout khi cần tham chiếu đến
view nào đó để làm mốc.
Colors
android:background (color, image)
android:textColor
Giá trị thường dùng
"#rrggbb", "#aarrggbb", "@color/color_name"
Commonly Used Attributes
73. 73
Ý nghĩa
Cho phép đặt những thành phần theo 1 dòng hay 1 cột
Có thể lồng ghép để tạo thành những dòng với các cột.
Các thuộc tính XML quan trọng.
android:orientation
"horizontal" (row) or "vertical" (column)
Horizontal là mặc định
android:gravity
Cách các view bên trong được canh lề
Basic LinearLayout
76. 76
Example (nested layout)
Horizontal LinearLayout
Chứa 2 layout Horizontal LinearLayout
Layout đầu tiên màu vàng có
layout_width ="wrap_content" và
gravity ="left"
Layout thứ hai màu xanh có
layout_width="match_parent"và
gravity là "right"
77. 77
Example (nested layout)
Horizontal LinearLayout
Chứa 3 vertical bên trong
1. LinearLayout với orientation là
vertical và 4 button bên trong
2. Chứa RadioGroup với orientation
là vertical và 4 RadioButton bên
trong.
3. LinearLayout với orientation là
vertical và 4 LinearLayout bên
trong.
2 cột đầu có layout_width là
wrap_content và cột thứ 3 là
match_parent.
78. 78
Example (nested layout)
Vertical LinearLayout
Layout này chứa 4 horizontal bên
trong.
1. Gravity là center_horizontal
2. Gravity là left
3. Gravity là right
4. Chứa 2 horizontal LinearLayout
bên trong
1. Layout_width là wrap_content
và gravity là left
2. Layout_width là match_parent
và gravity là right
80. 80
Mặc dù màu có thể định nghĩa cụ thể trong file layout
(background="#ff0000"), tuy nhiên có thể định nghĩa tên
màu trong file riêng biệt, khi đó tham chiếu thông qua tên
màu.
Nếu cần thì chỉ thay đổi giá trị của màu, lúc đó sẽ tác
động lên toàn bộ nơi tham chiếu đến tên màu.
Syntax
Convention
Sử dụng file res/values/colors.xml
Có thể đặt với bất cứ tên nào miễn hợp lệ!
Setting Colors
<resources>
<color name="color_name_1">#rrggbb</color>
… <!-- Other colors -->
</resources>
82. 82
Tham chiếu màu trong file layout.
Tham chiếu trong code
getResource().getColor(R.color.red)
Layout file
<TextView
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:id="@+id/textView1"
android:text="@string/red"
android:layout_marginTop="20px"
android:layout_centerHorizontal="true"
android:padding="25dp"
android:background="@color/red">
</TextView>
83. 83
Ý nghĩa
Gán những con số cho android:layout_weight, kích
thước sẽ được phân chia theo tỷ số này.
Cách dùng (cho height)
Thiết lập android:layout_height = 0dp
Sử dụng những giá trị tương ứng cho layout_weight
Vd: nếu có 3 thành phần với layout_weight tương ứng
là 1, 1 và 2 thì tỷ lệ tương ứng là 25%, 25% và 50% của
3 thành phần so với chiều cao của cha.
Tương tự cho thiết lập width!
Có thể xem giá trị weight là 100, sử dụng những giá trị 25,
25, và 50 cũng tương ứng như 1, 1 và 2!
Layout Weight
86. 86
Ý tưởng
Mỗi view có id xác định
Cho phép xác định vị trí tương đối của view với những
view khác thông qua id.
Thuộc tính XML quan trọng
Align với container
layout_alignParentBottom (Top,Right,Left)
layout_centerInParent (centerHorizontal, centerVertical)
Tất cả giá trị là true hay false
Align với view
layout_alignBottom (Top, Right, Left)
layout_toLeftOf ( toRightOf, above, below)
Tất cả giá trị là id của view nào đó
RelativeLayout
87. 87
Button thứ 1
<Button id = "@+id/button_1"
android:layout_alignParentRight="true"… />
Button thứ 2
<Button android:layout_toLeftOf="@id/button_1"… />
Referring to Existing IDs
@+id: để gán id mới
@id: (không có dấu cộng)
tham chiếu đến button đã có
91. 91
Idea
Cho phép widget và layout khác chứa bên trong grid
(không có đường biên)
Tương tự như HTML table, số dòng và cột xác định tự
động, không cần phải khai báo.
Các view được đặt bên trong TableRow
XML attributes
android:stretchColumns
Chứa chỉ số cột sẽ được stretch khi table nhỏ hơn parent
android:shrinkColumns
Liệt kê các cột sẽ co lại khi table lớn hơn parent
android:collapseColumns
Những cột sẽ bị thu lại, có thể lập trình để hiện ra sau.
TableLayout
92. 92
Dùng để định nghĩa một dòng trong TableLayout
Thuộc tính XML quan trọng sử dụng bên trong TableRow
android:layout_column
Có thể xác định chính xác cột của thành phần, cột bỏ qua
đó sẽ rỗng.
android:layout_span
Số cột mà thành phần sẽ chiếm giữ, giống colspan trong
HTML table
Không có thuộc tính tương ứng với rowspan trong HTML,
dùng nested table để thực hiện.
TableRow
101. 101
Là nút nhấn có nhãn bên trên
Listener: View.OnClickListener
Nếu sử dụng phương pháp XML based thì có thể không
cần phải khai báo lớp Listener này.
Thuộc tính XML thường dùng
android:text
Nhãn của button, có thể truy xuất bằng code java thông
qua phương thức setText và getText
android:onClick
Basic Button
102. 102
Là nút nhấn có ảnh hiển thị bên trên
Listener: View.OnClickListener
Thuộc tính XML
android:src
ảnh hiển thị trên button, tham chiếu đến tên (không có
phần mở rộng) của ảnh trong thư mục res/drawable
Hỗ trợ các kiểu ảnh png, jpeg, gif và bmp.
Có thể dùng Java code để thiết lập với setImageDrawable
android:onClick
ImageButton
104. 104
Là nút chọn, cho phép chọn một trong số mục chọn cùng
nhóm.
Listener
View.OnClickListener
Gán cho mỗi nút nếu quan tâm đến sự kiện chọn trên
từng item.
Có thể dùng cách khác là bắt sự kiện trên RadioGroup.
Thuộc tính XML
android:text, android:onClick
RadioButton
105. 105
Tương tự như LinearLayout, cho phép chứa các
RadioButton bên trong.
Quản lý trạng thái RadioButton là exclusive.
Listener: OnCheckedChangeListener
Thuộc tính XML
Tương tự như LinearLayout
Sử dụng android:id để tham chiếu trong chương trình
(khi thiết lập OnCheckedChangeListener)
Không có thuộc tính andoird:onXYZ để thiết lập
RadioGroup listener trong XML.
RadioGroup
106. 106
Minh hoạ
Đáp ứng với mỗi click trên từng radio button bằng cách
hiện thông điệp message nào đó
Cách thực hiện
Đặt các radiobutton vào trong radiogroup
Gán event handler, sử dụng onClick cho mỗi
RadioButton.
Không cần id cho RadioGroup, không cần listener cho
RadioGroup.
Event handler cho RadioButton
108. 108
Minh hoạ
Mỗi khi nút nào được nhấn thì hiển thị message báo tên
nút được nhấn
Cách thực hiện
Đặt RadioButton bên trong RadioGroup
Trong XML, tạo id cho RadioGroup
Trong Java, xác định RadioGroup và thiết lập Listener
Event handler cho RadioGroup
111. 111
Là dạng tương tự như combo box
Listener
AdapterView.OnItemSelectedListener
AdapterView.OnItemClickedListener
Thuộc tính XML
android:id, android:prompt
android:entry
Định nghĩa mục chọn, có thể định nghĩa trong strings.xml
hoặc arrays.xml
Spinner
116. 116
Có thể dùng Intent để gọi một activity từ một activity đang
hiển thị.
Cú pháp
Dùng Intent để gọi Activity
Intent activityIntent = new Intent(this, NewActivity.class);
startActivity(activityIntent);
…
// khai báo trong AndroidManifest.xml
<activity android:name = "NewActivity"
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<action android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
117. 117
Cách thực hiện
Tạo đối tượng Bundle, chứa dữ liệu cần gởi cho activity
mới, attach đối tượng Bundle này kèm theo Intent
Cú pháp
Java (original Activity)
Java (new Activity)
Gởi dữ liệu giữa Activity
Intent activityIntent = new Intent(this, NewActivity.class);
Bundle newActivityInfo = new Bundle();
newActivityInfo.putXYZ(…); //putDouble, putString…
activityIntent.putExtras(newActivityInfo);
startActivity(activityIntent);
Intent intent = getIntent();
Bundle info = intent.getExtras();
If (info != null) {
// getXYZ()…
}
118. 118
VD: Truyền dữ liệu từ original activity sang new activity.
Gởi dữ liệu giữa Activity
119. 119
Hàm xử lý submit
Gởi dữ liệu giữa Activity
public void submit(View v)
{
Intent newActivity = new Intent(this,NewActivity.class);
Bundle info = new Bundle();
String sName, sEmail;
EditText ed1 = (EditText)findViewById(R.id.editText1);
EditText ed2 = (EditText)findViewById(R.id.editText2);
info.putString("Name", ed1.getText().toString());
info.putString("Email", ed2.getText().toString() );
newActivity.putExtras(info);
startActivity(newActivity);
}
120. 120
Xử lý trong new activity
Gởi dữ liệu giữa Activity
setContentView(R.layout.new_activity);
// tham chiếu đến intent
String sName, sEmail;
Intent intent = getIntent();
Bundle info = intent.getExtras();
if (info != null)
{
sName = info.getString("Name");
sEmail = info.getString("Email");
TextView tv1 = (TextView)findViewById(R.id.tvHoTen);
tv1.setText(sName);
TextView tv2 = (TextView)findViewById(R.id.tvEmail);
tv2.setText(sEmail);
}
121. 121
Tình huống:
Activity mới sau khi tương tác với user, thu thập được
dữ liệu, kết thúc activity và gởi lại cho activity gọi nó
(original activity).
Gởi dữ liệu giữa Activity
Activity A Activity B
Gọi activity B (có thể
truyền dữ liệu cho B tuỳ ý)
Acvitity B kết thúc và
gởi dữ liệu về cho A
122. 122
Phần xử lý ở lớp activity A (Original Activity)
Phần xử lý trên thường đặt trong hàm xử lý sự kiện của
button hay menu.
Gởi dữ liệu giữa Activity
Intent newActivity = new Intent(this, ActivityB.class);
final int result = 1;
// gọi activity B hiển thị và chờ lấy kết quả trả về
startActivityForResult(newActivity, result);
123. 123
Phần xử lý ở lớp activity A (Original Activity), khi nhận kết
quả trả về từ activity B (new Activity).
Override phương thức onActivityResult trong ActivityA để
nhận kết quả trả về (khi ActivityB đóng).
Gởi dữ liệu giữa Activity
protected void onActivityResult(int requestCode,
int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
// lấy Bundle chứa dữ liệu
Bundle bundle = data.getExtras();
int data1 = bundle.getInt("<tên dữ liệu 1>");
int data2 = bundle.getInt("<tên dữ liệu 2>");
String data3 = bundle.getString("<tên dữ liệu 3>");
…
}
124. 124
Phần xử lý trong activity B (activity được gọi từ A)
Gởi dữ liệu giữa Activity
// gởi dữ liệu về activity trước
Intent intent = new Intent();
Bundle bundle = new Bundle();
// gởi dữ liệu vào bundle
bundle.putInt("<tên dữ liệu 1>", data1);
bundle.putInt("<tên dữ liệu 2>", data2);
Bundle.putString("<tên dữ liệu 3>", data3);
intent.putExtras(bundle); // gởi kèm dữ liệu
setResult(RESULT_OK, intent); // gởi kết quả về
finish(); // đóng activity
125. 125
Cung cấp URI tham chiếu đến new activity
New Activity sẽ đăng ký trong androidmanifest có mô tả
dùng URI
Cú pháp
Java (original Activity)
XML (phần khai báo cho activity được gọi)
Gọi Activity thông qua URI
Uri uri = Uri.parse("call://ex.intent.uri/ActivityC");
Intent intent = new Intent(Intent.ACTION_VIEW, uri);
startActivity(intent);
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<data android:scheme="call" android:host="ex.intent.uri"/>
</intent-filter>
126. 126
Ý tưởng
Nhúng tham số trong URI, tương tự như query string
trong Web.
Cú pháp
Java (original Activity)
Java (new Activity)
Gởi dữ liệu qua tham số URI
Uri uri = Uri.parse("call://ex.intent.uri/ActivityC?str=hello class");
Intent intent = new Intent(Intent.ACTION_VIEW, uri);
startActivity(intent);
Uri uri = getIntent().getData();
String str = uri.getQueryParameter("str");
// xử lý với chuỗi, nếu truyền là chuỗi số thì chuyển sang số
…
127. 127
Extras
Pros
Can send data of different types
No parsing required in Activity that receives the data
Cons
More complex for originating activity
Requires parsing in originating activity if values come from
EditText
URI parameters
Pros:
Simpler for originating Activity, especially if EditText used
More consistent with URI usage
Cons
Can send Strings only
Requires parsing in receiving Activity
Extras vs. URI parameter
128. 128
Ý tưởng
Tạo tab window, mỗi tab là một activity
Có thể gọi activity thông qua class hay URI
Gởi dữ liệu thông qua extras Bundle hay URI
Tab Window Activity và các activity phải cùng project.
Cú pháp
Java
Mở rộng từ lớp TabActivity, sử dụng TabHost, TabSpec
XML: (androidManifest.xml)
Tương tự như phần trước.
Activity với Tabbed Window
132. 132
Service là thành phần nền tảng của Android.
Đôi khi ứng dụng run process với khoảng thời gian lâu và
không có hoặc hiếm khi có sự can thiệp từ người dùng.
Tiến trình nền này có thể xử lý ngay cả khi phone được sử
dụng cho activity/task khác.
Các lớp thực thi service phải mở rộng từ lớp Service trong
gói android.app.Service
Các phương thức override là: onCreate, onDestroy,
onStart
Service
133. 133
Minh hoạ:
Tạo một service thực thi việc chạy file nhạc nền.
Service này được gọi thông qua UI trên Activity.
Service
Sử dụng ToggleButton
để on/off service
134. 134
Bước 1: Chuẩn bị file nhạc mp3.
Tạo thư mục raw trong res (nếu chưa có raw)
Import một file nhạc mp3 nào đó vào thư mục res/raw
Service
Ví dụ import file
only_time.mp3 vào thư
mục raw
135. 135
Bước 2: Tạo layout cho activity chính của ứng dụng
Service
<LinearLayout
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:gravity="center_horizontal" >
<TextView android:text="Services Demo"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="35dp" >
</TextView>
<ToggleButton android:text="ToggleButton"
android:id="@+id/toggleButton1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="doService" >
</ToggleButton>
</LinearLayout>
136. 136
Bước 3: Tạo một lớp mới extend từ Service
Service
Tên lớp service sẽ tạo
Extend từ lớp Service
137. 137
Bước 4:
Override các phương
thức onCreate,
onDestroy, onStart
của service.
Tạo đối tượng player
là MediaPlayer
Service
public class MyService extends Service {
private static final String TAG ="HaGService";
private MediaPlayer player;
@Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return null;
}
@Override
public void onCreate() {
// TODO Auto-generated method stub
}
@Override
public void onDestroy() {
// TODO Auto-generated method stub
}
@Override
public void onStart(Intent intent, int startId) {
// TODO Auto-generated method stub
}
}
138. 138
Bước 5: viết các phần xử lý cho onCreate
Hiển thị một messge báo "Service created"
Hiển thị thông tin debug trong LogCat
Load file nhạc vào biến player
Thiết lập cờ looping.
Service
@Override
public void onCreate() {
// TODO Auto-generated method stub
Toast.makeText(this, "Service created", Toast.LENGTH_LONG).show();
Log.d(TAG,"onCreate");
player = MediaPlayer.create(this, R.raw.only_time);
player.setLooping(false);
}
139. 139
Bước 6: thực thi hàm onStart và onDestroy
Service
@Override
public void onStart(Intent intent, int startId) {
// TODO Auto-generated method stub
Toast.makeText(this, "Service started", Toast.LENGTH_LONG).show();
Log.d(TAG, "onStart");
player.start(); // chạy file nhạc
}
@Override
public void onDestroy() {
// TODO Auto-generated method stub
Toast.makeText(this, "Service stopped", Toast.LENGTH_LONG).show();
Log.d(TAG,"onDestroy");
player.stop(); // dừng file nhạc
}
140. 140
Bước 7: viết phần xử lý cho sự kiện onClick của
ToggleButton trong activity chính của ứng dụng
Service
public void doService(View view)
{
// tham chiếu đến ToggleButton
ToggleButton btn = (ToggleButton)view;
if (btn.isChecked()==true) {
startService( new Intent(this,MyService.class) );
}
else {
stopService( new Intent(this,MyService.class) );
}
}
141. 141
Bước 8: khai báo service trong AndroidManifest.xml
Việc khai báo service trong file AndroidManifest là bắt
buộc.
Nếu thiếu phần khai báo thì service sẽ không chạy
được.
Service
<service android:name="MyService" android:enabled="true"></service>
Tên của service Thiết lập trạng thái
của Service là anable
142. 142
Broadcast Receivers
Thành phần có thể respond lại các thông báo của hệ
thống.
VD:
Thông báo màn hình bị tắt, pin yếu, ảnh được chụp
Thông báo cuộc gọi đến, tin nhắn đến…
Ngoài ra ứng dụng cũng có thể khởi tạo broadcast để
báo cho ứng dụng khác hay hệ thống biết thông tin gì
đó
Ứng dụng báo đã hoàn thành việc download về thiết bị và
sẵn sàng cho việc sử dụng.
Có thể dùng để start một service chạy nền nào đó.
Phần tìm hiểu thêm
143. 143
Content providers
Quản lý sự chia sẻ dữ liệu của ứng dụng. Bao gồm các
dạng
Shared preferences
Internal storage
Local cache
External storage
SQLite database (Chapter 12: Android App Dev for Dummies)
Network connection
Phần tìm hiểu thêm
Editor's Notes
3 cách cơ bản trong việc xây dựng ứng dụng Android