Dùng lại các lớp HTTPQueue.java, HTTPThread.java,
RemoteImageView.java: phục vụ cho việc chạy ngầm tải hình ảnh từ server
về dưới dạng danh sách hàng đợi dùng Thread.
Hiệu chỉnh lớp MagnatuneAPI.java nhưng có chỉnh sửa lại cho phù
hợp để phục vụ việc lưu vết thư mục tạm lưu trữ hình ảnh từ server về.
Hiệu chỉnh lớp LazyAdapter.java phục vụ hiển thị một item trên
ListView.
Hiệu chỉnh lớp LazyActivity.java, đây là lớp mà nhóm tham khảo kỹ
nhất và thực hiện viết lại một số tính năng cho phù hợp vì trong lớp này chứa
giải pháp giải quyết vấn đề của EndlessList cực kỳ hiệu quả đó là dùng Task
không đồng bộ.
286 trang |
Chia sẻ: lylyngoc | Lượt xem: 3267 | Lượt tải: 2
Bạn đang xem trước 20 trang tài liệu Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa, để xem tài liệu hoàn chỉnh bạn click vào nút DOWNLOAD ở trên
envelope.getResponse();
result.toString();
// xử lý kết quả nhận được từ webservice
String resultFromWebservice = "";
for (int i = 0; i <
result.getPropertyCount(); i++) {
resultFromWebservice += "\n"
+
result.getProperty(i).toString();
}
Toast.makeText(getBaseContext(),
233
"Result From Server: \n" +
resultFromWebservice,
Toast.LENGTH_LONG).show();
} catch (Exception e) {
Toast.makeText(getBaseContext(), "" +
e.toString(),
Toast.LENGTH_LONG).show();
}
}
});
Hoàn cảnh ở đây là ta cần phát lệnh yêu cầu máy chủ webservice trả về cho
chúng ta tập giá trị ứng với yêu cầu mà ta đã gửi lên trước đó.
Trên là đoạn mã lệnh thực hiện đọc dữ liệu webservice và thể hiện lên màn
hình Android. Trong project mẫu hướng dẫn có tên là HelloWebservice có một
webservice đã viết sẵn. Bạn chạy webservice đó lên máy của bạn; sau đó thiết lập IP
thích hợp cho máy của bạn. Ở đây, chúng tôi tạm thiết lập IP như trên và từ đây
máy tính của bạn trở thành một server có webservice cung cấp thông tin cho ứng
dụng Android.
Đầu tiên ta phải thiết lập các thông số SOAP_ACTION, METHOD_NAME,
NAMESPACE, URL. Sau đó khởi tạo môi trường kết nối tới webservice thông qua
SoapSerializationEnvelope và SoapObject để gửi yêu cầu lên webservice. Tiếp
theo gọi và lấy kết quả về thông qua HttpTransportSE . Tùy theo từng hoàn cảnh
mà ta phân giải giá trị tương ứng thông qua phương thức getProperty().
I.9.5.3 Nhận xét
Cũng như SQLite, ta nên tạo một lớp để chuyên thực thi kết nối tới
webservice và lấy dữ liệu về từ máy chủ. Trong ứng dụng eSaleShopping, chúng tôi
đã tạo ra lớp ServiceProvider bao gồm các phương thức cơ bản để kết nối và yêu
cầu dữ liệu từ máy chủ.
I.10 Lập trình với MapView
I.10.1 Giới thiệu
234
Lập trình bản đồ là thế mạnh của Android do nó được sự hậu thuẫn tối đa từ
Google. Ứng dụng bản đồ và vị trí dùng các lớp trong gói android.location và các
thư viện mở rộng của Google.
Android cho phép ứng dụng truy xuất đến các dịch vụ vị trí (có một phần cần
phải có sự hỗ trợ của thiết bị) thông qua gói android.location. Thành phần chính
của android.location là LocationManager sẽ cung cấp các hàm API để xác định vị
trí nếu có sự hỗ trợ của thiết bị (như GPS hay vị trí thông qua trạm thu phát sóng
điện thoại).
Cũng như các dịch vụ hệ thống khác, ta không khởi động thực thể
LocationManager trực tiếp mà phải nhờ hệ thống gọi hàm
getSystemService(Context.LOCATION_MANAGER). Hàm này sẽ trả ra một thực
thể LocationManager để quản lí bản đồ và vị trí.
Một khi có thực thể LocationManager thì ứng dụng có thể làm những việc
sau:
Tìm lại danh sách các LocationProvider để tìm giá trị vị trí lần cuối
cùng mà LocationProvider có (LocationProvider là các thiết bị nhận tín hiệu
vị trí thông qua GPS, Wifi, Mạng điện thoại).
Thiết lập hay gỡ bỏ thiết lập cho khoảng thời gian nhận giá trị cập
nhật cho LocationProvider.
Tuy nhiên, khi dùng máy ảo để chạy ứng dụng bản đồ thì ta không thể nhận
giá trị vị trí thật từ LocationPrivider (như mạng hay GPS). Trong hoàn cảnh này, ta
có thể dùng DDMS để gửi tín hiệu giả lập cho máy ảo.
Google cung cấp cho ta thư viện mở rộng gồm gói
com,google.android.maps. Các lớp con của gói này cung cấp cho ta bản đồ, canh
chỉnh bản đồ, lưu vết bản đồ và nhiều sự hỗ trợ khác nữa.
Lớp quan trọng của gói Maps là MapView, là một lớp con của ViewGroup.
MapView hiển thị bản đồ với dữ liệu có được từ dịch vụ Google Map. Tùy theo
người dùng thao tác lên màn hình mapView mà nó sẽ phóng to, thu nhỏ bản đồ. Nó
cung cấp các phần tử giao diện cần thiết để quản lí bản đồ như la bàn đi kèm chẳng
235
hạn. Ngoài ra, MapView có chứa các lớp để quản lí và vẽ các loại hình ảnh “đè” lên
bản đồ chẳng hạn như các nút ghim, các chú thích ...
Gói thư viện Maps không phải là phần thư viện chính thức từ thư viện
Android, vì thế nếu bạn muốn lập trình ứng dụng có sự hỗ trợ của Google Maps thì
phải dùng thêm thư viện và thêm vào reference của ứng dụng như là phần KSOAP
của Webservice.
I.10.2 Cách thức lập trình
Chúng tôi hướng dẫn bạn theo từng bước để tạo một ứng dụng có áp dụng
bản đồ.
I.10.2.1 Bước 1:
Dĩ nhiên là tạo project. Tạm đặt tên là HelloOtherWidget.
I.10.2.2 Bước 2:
Khai báo là ta có sử dụng bản đồ trong AndroidManifest.xml với giá trị qui
định nằm trong thẻ như sau:
I.10.2.3 Bước 3:
Do ta cần truy xuất Internet để truy xuất bản đồ của Google; vì thế ta cần cấp
phép dùng Internet. Trong tập tin AndroidManifest.xml, thì thêm vào giá trị bên
trong thẻ như sau:
I.10.2.4 Bước 4:
Cũng trong tập tin AndroidManifest.xml ta thiết lập thuộc tính không thể
hiện tiêu đề cho Activity bản đồ như sau:
<Activity android:name=".HelloMapView" android:label="@string/app_name"
android:theme="@android:style/Theme.NoTitleBar">
<action android:name="android.intent.action.MAIN"
/>
<category
android:name="android.intent.category.SAMPLE_CODE" />
236
Thuộc tính qui định không có tiêu đề có hay không có đều được.
I.10.2.5 Bước 5:
Mở tập tin qui định giao diện, chúng tôi tạo một tập tin giao diện XML mới
có tên là hello_mapView.xml và thiết kế như sau:
<RelativeLayout
xmlns:android=""
android:id="@+id/mainlayout" android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<com.google.android.maps.MapView
android:id="@+id/mapView" android:layout_width="fill_parent"
android:layout_height="fill_parent" android:clickable="true"
android:apiKey="0zAN4n_WR-D5XultBqPDnHAv2g_krHVOK8m4D3g" />
Ta lưu ý ở trên có mục apiKey. Mục này là khóa mà Google Maps đưa cho
mỗi người khác nhau với từng debug.keystore khác nhau.
Trong tài liệu phụ lục này có mục trình bày cài đặt máy ảo và có phần yêu
cầu các bạn chú ý đến phần debug.keystore để sau này lập trình bản đồ. Google
Maps yêu cầu với mỗi nhà lập trình trên mỗi máy khác nhau thì cần có một apiKey
khác nhau. Để lấy được apiKey ta theo các bước sau:
Vào thư mục chứa máy ảo để lấy đường dẫn debug.keystore. Ở đây
tôi có đường dẫn sau: C:\Users\ThanhTrung\.android\debug.keystore.
Hình phụ lục 171 Hình minh họa thư mục chứa tập tin debug.keystore (Windows 7)
237
Mở CommandPromt và vào đến thư mục và chạy dòng lệnh:
C:\Program Files\Java\jdk1.6.0_16\bin>keytool -list -keystore
"C:\Users\ThanhTrung\.android\debug.keystore"
Khi đó màn hình sẽ xuất hiện nội dung sau:
***************** WARNING WARNING WARNING
*****************
* The integrity of the information stored in your keystore *
* has NOT been verified! In order to verify its integrity, *
* you must provide your keystore password. *
***************** WARNING WARNING WARNING
*****************
Keystore type: JKS
Keystore provider: SUN
Your keystore contains 1 entry
androiddebugkey, 07-12-2009, PrivateKeyEntry,
Certificate fingerprint (MD5):
AD:35:5C:24:54:36:76:AB:42:7B:4F:2B:D4:D9:38:DB
Vào website
ons/google-apis/maps-api-signup.html và nhập vào mã số Certificate
fingerprint (MD5) như hình sau:
238
Hình phụ lục 172 Hình minh họa trang web lấy mã đăng ý Google Maps ApiKey từ Google
Cuối cùng Google yêu cầu ta đăng nhập với tài khoản của GoogleMail
vào và ta sẽ nhận được apiKey. Lúc đó, ta lưu lại apiKey để sử dụng cho các
chương trình sau.
Lúc này ta dùng apiKey đó cho phần apiKey ở mục trên.
Chú ý là không dùng apiKey như đã ví dụ ở trên vì chắc chắn màn hình bản
đồ sẽ không hiển thị được Google Map khi bạn dùng apiKey của máy khác.
I.10.2.6 Bước 6
Tạo tập tin Java có tên là HelloMapView.Java và thừa kế lớp MapActivity
public class HelloMapView extends MapActivity
I.10.2.7 Bước 7
Trong mỗi lớp nào kế thừa từ lớp MapActivity đề phải viết lại hàm
isRouteDisplayed().
@Override
protected boolean isRouteDisplayed() {
return false;
}
239
I.10.2.8 Bước 8
Thiết kế nội dung hàm onCreate() như sau:
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.hello_mapView);
MapView mapView = (MapView) findViewById(R.id.mapView);
// chỉnh độ phóng to của bản đồ
mapView.getController().setZoom(17);
// gắn bộ ZoomController vào bản đồ
mapView.setBuiltInZoomControls(true);
}
Thế là xong ứng dụng có bản đồ.
I.10.3 Nhận xét
Trên là những bước cơ bản để tạo nên bản đồ có sử dụng tính năng của
Google Maps. Ngoài ra, việc khai thác bản đồ dường như là vô tận khi ta thêm các
đối tượng trên màn hình bản đồ để phục vụ cho từng ý tưởng liên quan đến bản đồ.
Cho nên việc vẽ các nút nhấn, các biểu tượng lên trên đó là điều rất cần thiết. Để
tìm hiểu kĩ hơn phần này ta vào mục Part 2: Adding Overlay Items trong trang
web:
để tìm hiểu thêm.
I.11 Lập trình thao tác WebKit
I.11.1 Giới thiệu
Android hỗ trợ ta mở trình duyệt web ngay trên phần mềm ứng dụng
Android. Chỉ cần vài thao tác đơn giản ta có thể mở các trang web ngay trên màn
hình thao tác của ứng dụng mà không cần tốn công mở trình duyệt web lên.
240
Phần lập trình với Webkit chúng tôi đã làm trong project mẫu
HelloOtherWidget mục Webkit.
I.11.2 Cách thức lập trình
I.11.2.1 Tạo giao diện
Tạo tập tin giao diện XML với nội dung đơn giản như sau:
<LinearLayout xmlns:android=""
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical">
<WebView android:id="@+id/webkit"
android:layout_height="fill_parent"
android:layout_width="fill_parent" />
Các bạn không quên kiểm tra sự pho phép dùng Internet trong thẻ permission
thuộc tập tin AndroidManifest.xml có tồn tại chưa.
I.11.2.2 Mã lệnh Java
Thiết kế lớp Activity đơn giản như sau.
public class HelloWebKit extends Activity {
WebView browser;
/** Called when the Activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.hello_webkit);
// tạo một WebView
browser = (WebView) findViewById(R.id.webkit);
browser.getSettings().setJavaScriptEnabled(true);
// nạp vào WebView địa chỉ web
browser.loadUrl("");
}
}
241
Nó sẽ mở một trình duyệt web và vào thẳng trang web www.google.com .
Bạn chú ý, khi thiết kế bạn có thêm TextView hay các widget khác thì trình duyện
cũng che lấp hết các widget ấy.
I.11.3 Nhận xét
Cũng giống như các trình gọi điện thoại hay gửi tin nhắn, thì trình trình duyệt
web giúp nhà lập trình có thể gọi trực tiếp màn hình duyệt web ngay từ chương
trình và sẽ thuận tiện cho người dùng khi nhấp vào các đường liên kết thì nó sẽ mở
trang web ứng với đường liên kết ấy.
I.12 Lập trình với các widget khác
I.12.1 Widget Date/Time
I.12.1.1 Giới thiệu
Điều khiển này cho phép ta chọn ngày/ giờ hệ thống. Chúng có giao diện như
sau:
Hình phụ lục 173 Hình minh họa Date widget
Hình phụ lục 174 Hình minh họa Time widget
I.12.1.2 Cách thức lập trình
242
Việc lập trình trên widget này tương đối dễ. Các bạn có thể tự tìm hiểu thêm
phần này trong ứng mẫu HelloOtherWidget với phần
HelloDateTimeSelectionWidget.Java.
I.12.2 Widget Tab
I.12.2.1 Giới thiệu
Phần tab giúp ta nhìn trên nhìn khung nhìn khác nhau. Tùy theo từng chương
trình ứng dụng mà ta có thể áp dụng chúng:
Hình phụ lục 175 Hình minh họa giao diện dạng Tab trong Android
I.12.2.2 Cách thức lập trình
Đầu tiên, tạo tập tin giao diện XML như sau:
243
Hình phụ lục 176 Mã XML minh họa cho việc tạo một khung ứng dụng Tab đơn giản
Ta chú ý, giao diện tab có 3 thành phần chính:
Tabhost: là khung chứa chính cho nút lệnh tab và nội dung tab.
Tabwidget: là phần chứa số nút tab bao gồm chữ và biểu tượng.
FrameLayout: là nơi chứa nội dung tab.
Hình phụ lục 177 Hình minh họa cấu trúc của một Tab widget
Như trong phần mã lệnh XML ta có thể hiện từng TextView ứng với từng
Tab trong TabWidget.
Tiếp đến vào mã lệnh Java để thiết lập cho từng tab như sau:
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.hello_tabwidget);
TabHost mTabHost = getTabHost();
244
mTabHost.addTab(mTabHost.newTabSpec("tab_test1").setIndicator("TAB
1")
.setContent(R.id.textView1));
mTabHost.addTab(mTabHost.newTabSpec("tab_test2").setIndicator("TAB
2")
.setContent(R.id.textView2));
mTabHost.addTab(mTabHost.newTabSpec("tab_test3").setIndicator("TAB
3")
.setContent(R.id.textView3));
mTabHost.setCurrentTab(0);
}
Lúc này, tab được hình thành theo ý muốn của chúng ta.
245
Phụ lục J Lập trình với EndlessList
J.1 Giới thiệu
Việc tạo một danh sách trên Android như ta đã biết ở các phần phụ lục trước
là một việc hết sức dễ dàng và nhanh chóng. Ở đây, chúng ta chỉ cần tạo một
ListView trên màn hình giao diện và dùng bất kỳ một Adapter nào để gắn kết dữ
liệu vào ListView này. Việc lập trình như vậy nếu xét về khía cạnh cục bộ trên một
thiết bị di động thì không có gì phải bàn nhưng nếu xét trên ngữ cảnh thiết bị đó
hoạt động trên môi trường mạng thì đây lại là một vấn đề thách thức đối với các nhà
lập trình.
Việc hiển thị dữ liệu cục bộ (nguồn dữ liệu có thể là các mảng chuỗi lưu
trong tài nguyên chương trình hay lưu trong CSDL SQLite) được Android thực hiện
rất nhanh chóng và chính xác. Tuy nhiên việc lấy dữ liệu từ server về và hiển thị lên
ListView là một điều khó do nó phụ thuộc vào nhiều yếu tố như: chất lượng đường
truyền của mạng, độ lớn của dữ liệu... Ví dụ như việc hiển thị một list các bài nhạc
hay album từ một website âm nhạc nào đó lên màn hình cho người dùng xem và
nghe thử trước khi mua bài hát hay album nào đó. Có nhiều cách để thực hiện công
việc này. Cách đơn giản nhất là ta tải hết toàn bộ dữ liệu từ server về một lần sau đó
mới hiển thị lên cho người dùng xem và chọn. Cách này tuy đơn giản nhưng bộc lộ
không ít các nhược điểm đó là: nếu nguồn dữ liệu khá lớn thì người dùng sẽ đợi
“dài cổ” để cho dữ liệu được tải về hết và ngoài ra nó còn tiềm ẩn lỗi cho chương
trình nếu như đường truyền mạng bị trục trặc.
Để giải quyết bài toán nêu ra ở trên thì khái niệm EndlessList ra đời và được
các nhà lập trình áp dụng với nhiều cách thức khác nhau. Một bộ dữ liệu lớn trên
server sẽ được “chẻ” nhỏ và chương trình sẽ download tuần tự từng bộ dữ liệu được
“chẻ” nhỏ này và thể hiện lên trên một ListView lúc này ListView sẽ được gọi nôm
na là EndlessList.
246
J.2 Cách thức tạo EndlessList
Việc lập trình tạo ra EndlessList tương đối là phức tạp, vì vậy để thực hiện
được một EndlessList điều đầu tiên là ta phải biết được cách gắn kết dữ liệu vào
ListView thông qua một SimleAdapter (phần này đã được trình bày kỹ ở phần phụ
lục I.1).
Điều tiên quyết tiếp theo là nguồn dữ liệu từ server trả ra cho client phải
được “chẻ” nhỏ ra để ta có thể lấy về từng bộ nhỏ này về hiển thị lên ListView của
chương trình (ví dụ trên server có 100 record thì bộ dữ liệu này phải được chia nhỏ
làm 10 phần, mỗi phần có 10 record đủ nhỏ để cho phù hợp với việc truyền tải dữ
liệu trên môi trường thiết bị di động).
J.2.1 Cách thức vận hành của EndlessList:
Chương trình sẽ download về trước phần dữ liệu nhỏ đầu tiên và hiển thị lên
trên ListView. Khi người dùng duyệt đến dòng cuối cùng của ListView, chương
trình sẽ bắt được sự kiện này và tiến hành gửi một yêu cầu lên server để yêu cầu
phần dữ liệu tiếp theo.
Nếu server báo không còn phần dữ liệu nào nữa thì ứng dụng sẽ hoàn tất và
không còn gửi yêu cầu lên server nữa. Lúc này danh sách đã được tải và thể hiện
đầy đủ lên trên màn hình.
Ngược lại thì chương trình sẽ tiếp tục download về phần dữ liệu tiếp theo.
Sau khi download xong chương trình sẽ thực hiện gắn nối tiếp phần dữ liệu này vào
ListView (tức là nối liền phần dữ liệu ban đầu với phần dữ liệu mới này và hiển thị
lên List). Tiến trình trên cứ được lặp đi lặp lại cho đến khi chương trình download
hết các phần dữ liệu về.
Người dùng sẽ tốn một khoảng thời gian nhỏ cho mỗi lần chờ một phần dữ
liệu được tải về. Tuy nhiên việc chờ đợi này là chấp nhận được hơn so với việc phải
ngồi chờ rất lâu để tải hết trọn bộ dữ liệu về máy rồi mới xem.
Hình ảnh minh họa cho một EndlessList được ứng dụng trong bài toán
eSaleShopping.
247
Hình phụ lục 178 Hình minh họa cho một EndlessList được áp dụng vào eSaleShopping
J.2.2 Cách thức lập trình tạo EndlessList
Phần này chúng tôi sẽ không trình bày chi tiết các mã lệnh để tạo ra
EndlessList mà chỉ nêu vấn đề ở mức tổng quát nhất do từng hoàn cảnh thực tế mà
ta sẽ có cách áp dụng EndlessList khác nhau.
Theo như sự tìm hiểu của chúng tôi, ta sẽ tạo một lớp dẫn xuất từ lớp
SimpleAdapter và task không đồng bộ (AsyncTask) để có thể tạo một EndlessList.
Cách thức hoạt động và cơ chế sẽ được nêu rõ ở phần bên dưới.
Tạo một lớp mở rộng từ lớp SimpleAdapter như sau:
public class TestSimpleAdapter extends SimpleAdapter {
public TestSimpleAdapter(TestEndlessSlow context,
List> data, int resource,
String[] from, int[] to) {
super(context, data, resource, from, to);
}
@Override
public View getView(int position, View convertView, ViewGroup
parent) {
248
// kiểm tra xem có cần load thêm dữ liệu về từ server hay
không
if (!mDone && (getCount() - position) <= 1) {
if (mTestEndlessSlow.isAsyncTaskFinished()) {
mTestEndlessSlow.loadNextValues();
}
}
View ret = super.getView(position, convertView, parent);
if (ret != null) {
// Do something
}
return ret;
}
// ...
}
Lớp này có nhiệm vụ gắn kết dữ liệu với ListView (cách thức sử
dụng lớp dẫn xuất từ SimpleAdapter để gán dữ liệu vào ListView thông
qua phương thức setAdapter() như đã được trình bày ở phụ lục I.1),
đồng thời kiểm tra xem hiện thời ListView đã được cuộn tới cuối danh
sách chưa. Nếu đã tới cuối danh sách thì ta tạo một Task không đồng bộ
thực hiện việc tải tiếp phần dữ liệu mới về. Task không đồng bộ này sẽ
được trình bày kỹ hơn ở phần bên dưới.
Việc kiểm tra xem cuối danh sách của ListView hay chưa ta sẽ
thiết kế hàm đặt ở bên trong phương thức public View getView(int
position, View convertView, ViewGroup parent) {}
Gọi thực thi một AsyncTask để thực thi việc lấy dữ liệu ngầm từ
server về:
AsyncTask là một task không đồng bộ do Android hỗ trợ các nhà
lập trình thực hiện các hoạt động chạy nền bên dưới và đẩy kết quả thực
hiện được ra luồng UI (UI Thread) mà không cần thông qua Handler hay
Thread. Để hiểu rõ hơn ta có thể tham khảo thêm định nghĩa và cách
249
dùng AsyncTask từ trang
Khi một AsyncTask được gọi thực thi, nó phải trải qua 4 bước như
sau (và ta sẽ lợi dụng 4 bước này để thực hiện việc tải ngầm từng phần dữ
liệu từ server và sau khi tải xong phần nào sẽ “đẩy” phần đó lên trên giao
diện)
onPreExcute() phương thức này sẽ được gọi một lần khi
AsyncTask được kích hoạt. Ta sẽ khởi động các hiệu ứng của
progressBar lên trên màn hình để báo cho người dùng biết là phải chờ đợi
để tải thêm thông tin về từ server.
doInBackground() phương thức này là một thread chạy ngầm và
được chạy ngay sau khi hàm onPreExcute() được thực hiện xong. Ta sẽ
thiết kế các hàm đọc dữ liệu từ server ngay bên trong phương thức này.
Ngay khi đọc được bộ dữ liệu nào từ server ta có thể gửi kết quả này qua
hàm onProgressUpdate() để xử lý kết quả thông qua phương thức
publishProgress(ket_qua_doc_duoc).
onProgressUpdate() phương thức này được chạy trên UI Thread,
phương thức này được dùng để xử lý dữ liệu được gửi qua từ phương
thức doInBackground(). Từng record khi được gửi qua đây sẽ được thêm
vào một List, List này chính là nơi chứa dữ liệu cũ đang hiển thị
trên ListView và giờ sẽ chứa thêm dữ liệu mới vừa thêm vào. Mối liên hệ
giữa List SimpleAdapter ListView đã được nói rõ trên phần phụ
lục I.1 nên phần này sẽ không được đề cập ở đây.
onPostExcute() phương thức này cũng được chạy trên UI Thread
và được gọi thực thi khi tác vụ tính toán chạy ngầm đã thực thi hoàn tất.
Ta sẽ gọi thực hiện tắt hiệu ứng progressBar đi và yêu cầu ListView cập
nhật thêm dữ liệu mới (thông qua việc dùng phương thức
notifyDataSetChanged()của lớp dẫn xuất từ SimpleAdapter được mô tả
như ở phần trên).
250
J.3 Nhận xét
Việc lập trình với EndlessList tuy có phần phức tạp nhưng một khi đã nắm
vững được cách thức hoạt động của EndlessList thì việc áp dụng EndlessList vào
các ứng dụng có dạng kết nối dữ liệu với server sẽ nâng cao tính linh hoạt và uyển
chuyển cho ứng dụng khi hoạt động trên môi trường mạng, và người dùng không
phải tốn công chờ một lượng lớn dữ liệu tải về mà thay vào đó là “nhâm nhi” dần
dần dữ liệu.
Theo sự nhận xét của chúng tôi, EndlessList thường được dùng cho các ứng
dụng thương mại, tin tức và thường được dùng để liệt kê danh sách sản phẩm đang
bán hay quảng bá sản phẩm tới người dùng điển hình như ứng dụng Google Market
hay Magnatune (… và ứng dụng
eSaleShopping cũng đã có áp dụng EnlessList cho việc hiển thị danh sách hàng hóa
đang được bán từ các siêu thị khác nhau.
251
Phụ lục K Cấu trúc và ý nghĩa các thành phần của
một project Android
MyApp/
AndroidManifest.xml (rất cần) Chứa các khai báo về một project
như tên project, tên gói package, các lớp
Activity, lớp Activity chính khi chương trình
được chạy…
src/
/myPackagePath/.../MyClass.Java
(rất cần) Thư mục này chứa tất cả các source
code của chương trình.
res/ (rất cần) Thư mục này chứa tất cả các
resource của chương trình
anim/
animation1.xml
...
(không bắt buộc) Chứa các file XML về khai
báo animation mà chương trình cần sử dụng
drawable/
some_picture.png
some_stretchable.9.png
some_background.xml
...
(không bắt buộc) Các files trong thư mục này
sẽ được biên dịch trong resources
Android.graphic.drawable. Các file này
thường là các file ảnh như PNG. JPG hay
GIF.
layout/
screen_1_layout.xml
...
(không bắt buộc) Chứa tất cả các file XML
mô tả về giao diện màn hình hay một phần
giao diện màn hình.
values/
arrays
classes.xml
colors.xml
dimens.xml
strings.xml
(không bắt buộc) Đây là các file XML chứa
các thông tin thêm như strings, color hay
styles.
252
styles.xml
values.xml
xml/ Các file XML có thể được đọc trong thời gian
chạy trên thiết bị
raw/ (không bắt buộc) Tất cả các file trong thư mục
này sẽ được chép trực tiếp lên thiết bị.
Bảng B.1 Cấu trúc project Android
Bảng B-1 Cấu trúc project Android được tham khảo từ Khóa luận 2008
“Nghiên cứu và xây dựng từ điển trên G-Phone” của Tô Xuân Khôi Nguyên và
Đoàn Chánh Thức thực hiện.
Đối với các resource, bên cạnh những resource do người dùng tạo ra, Android
cũng hỗ trợ một số resource khác trong gói Android.R. (các resource do người dùng
thêm vào được sử dụng bằng cách gọi R.)
253
Phụ lục L Hướng dẫn sử dụng, thao tác chính trên
chương trình eSaleShopping
L.1 Sơ đồ liên kết các màn hình chức năng trong ứng dụng
eSaleShopping
Để tiện việc trình bày phần hướng dẫn sử dụng các chức năng trong chương
trình eSaleShopping chúng tôi đưa ra sơ đồ liên kết các màn hình chức năng trong
ứng dụng như hình bên dưới.
Hình phụ lục 179 Sơ đồ liên kết các màn hình của ứng dụng eSaleShopping
Màn hình
chính
MH tìm theo
danh mục
MH tìm theo
Loại hàng
hóa
MH danh
sách hàng
hóa
MH chi tiết
hàng hóa
MH tìm theo
hệ thống siêu
thị
...
MH tìm theo
chuỗi
MH danh
sách hàng
hóa
MH chi tiết
hàng hóa
MH tìm theo
mã vạch
MH danh
sách hàng
hóa
MH chi tiết
hàng hóa
MH hàng hóa
cần mua
MH hàng hóa
ưu thích
MH tùy chọn
MH thông tin
chương trình
254
Hình phụ lục 180 Sơ đồ liên kết các màn hình của ứng dụng eSaleShopping (tiếp)
L.2 Giới thiệu chức năng của màn hình chính
Hình phụ lục 181 Màn hình chính của ứng dụng eSaleShopping
L.2.1 Các chức năng trên màn hình chính
Tìm hàng hóa theo mã vạch: chọn chức năng này nếu chúng ta
muốn chụp thông tin của một mã vạch hàng hóa nào đó và tìm thông tin của
Màn hình tìm
theo hệ thống
siêu thị
MH chỉ đường đi
ngắn nhất
MH lựa chọn của
một siêu thị trong
hệ thống siêu thị
MH thông tin
siêu thị
MH chỉ đường
đến siêu thị
MH tìm hàng hóa
theo chuỗi
MH tìm hàng hóa
theo mã vạch
MH tìm hàng hóa
theo danh mục
255
hàng hóa đó hiện đang bán ở tại siêu thị nào, có giá cả là bao nhiêu, có
khuyến mãi hay không, .v.v…
Tìm hàng hóa theo siêu thị: chọn chức năng này nếu ta muốn
tìm các thông tin về hàng hóa hiện đang bán tại siêu thị của một hệ thống
siêu thị nào đó và các thông tin khác như bản đồ đường đi đến siêu thị hoặc
thông tin siêu thị, …
Tìm hàng hóa theo danh mục: chọn chức năng này nếu ta
muốn tìm thông tin hàng hóa theo các danh mục đã được chia sẵn theo nhiều
tiêu chí như: hàng gia dụng, thực phẩm đông lạnh… Khi chọn chức năng
này, chương trình sẽ hiển thị thông tin các hàng hóa được phân hoạch theo
danh mục hàng hóa, loại hàng hóa cho người dùng tiện theo dõi.
Tìm hàng hóa theo chuỗi: chọn chức năng này nếu người dùng
muốn tìm kiếm hàng hóa thông qua các từ khóa, các chuỗi … Ví dụ, khi
người dùng gõ vào từ khóa “trà xanh” và nhấn nút tìm kiếm thì chương trình
sẽ lấy dữ liệu danh sách những mặt hàng nào có chứa từ khóa “trà xanh” từ
server về và hiển thị chúng ra trên màn hình.
Quản lý danh sách hàng hóa ưu thích: chọn chức năng này nếu
ta muốn thêm, xóa, sửa hay xem thông tin của một hàng hóa ưu thích nào đó.
Quản lý danh sách hàng hóa cần mua: chọn chức năng này
nếu ta muốn thêm, xóa, sửa hay xem thông tin của một hàng cần mua.
L.2.2 Thực đơn (menu) chức năng của màn hình chính
256
Hình phụ lục 182 Menu chức năng của màn hình chính
Menu chức năng trong màn hình chính gồm có 3 chức năng chính như sau:
Thiết lập chương trình: đây là chức năng mà người dùng có thể thiết
lập hay sử dụng các chức năng như: xóa rác hình ảnh, cập nhật lại toàn bộ dữ
liệu của chương trình.
Thông tin chương trình: chức năng này cho biết thông tin phiên bản
phần mềm cũng như thông tin tác giả thực hiện.
Thoát chương trình: chức năng thoát chương trình.
L.3 Thao tác trên màn hình chụp mã vạch
Hình phụ lục 183 Màn hình chụp và tìm kiếm hàng hóa dựa theo mã vạch
L.3.1 Sử dụng chức năng chụp mã vạch
Để tiện việc trình bày hướng dẫn sử dụng chức năng chụp mã vạch chúng tôi
sẽ tóm lược lại bằng một kịch bản sử dụng như sau:
257
Người dùng thực hiện nhấn nút “Đọc Mã Vạch” . Chương trình
sẽ kiểm tra trên điện thoại có cài chương trình Barcode Scanner hay không.
Nếu không có chương trình Barcode Scanner để chụp mã vạch thì sẽ
hỏi xem người dùng có cần tải ứng dụng chụp mã vạch này về hay không.
Nếu cần thì chương trình sẽ dò tìm và tải về ứng dụng Barcode Scanner từ
Android Market về và cài đặt lên trên điện thoại theo trình tự sau:
Hình phụ lục 184 Các bước tiến hành tải về ứng dụng Barcode Scanner
258
Nếu điện thoại đã có sẵn chương trình Barcode Scanner thì ứng dụng
này sẽ được kích hoạt để chụp mã vạch hàng hóa
Hình phụ lục 185 Màn hình chụp thông tin của một mã vạch hàng hóa
Nếu chụp được mã vạch của hàng hóa, kết quả sẽ được phân tích
thành chuỗi số gồm 13 ký tự và được hiển thị lại trên màn hình
chụp mã vạch như sau
Hình phụ lục 186 Màn hình hiển thị kết quả đọc được từ quá trình chụp mã vạch
259
Nếu không chụp được mã vạch thì chương trình sẽ đưa ra gợi ý là
có tiếp tục tìm kiếm thông tin hàng hóa bằng cách sử dụng “Màn
hình tìm kiếm chuỗi” hay không.
Hình phụ lục 187 Màn hình gợi ý tìm hàng hóa theo chuỗi
L.3.2 Các chức năng thực hiện sau khi chụp được mã vạch hàng hóa
Sau khi chụp được mã vạch của hàng hóa, ta có 3 chức năng có thể thực hiện
được như sau: thêm vào danh sách mua hàng, thêm vào ưa thích và tìm hàng hóa.
Cả 3 chức năng trên đều có một kịch bản chung là khi nhấn chọn một trong ba chức
năng thì chương trình sẽ tiến hành gửi thông tin mã vạch vừa chụp được trên server,
yêu cầu server tìm các thông tin hàng hóa ứng với mã vạch đó. Sau khi xử lý yêu
cầu server sẽ trả kết quả này về cho client. Trên client sẽ hiển thị các thông tin này
dưới dạng một danh sách như hình phụ lục.
260
Hình phụ lục 188 Màn hình danh sách hàng hóa ứng với một mã vạch nào đó
Khi nhấn chọn vào một dòng trên danh sách ta sẽ thực hiện chức năng ứng với chức
năng từ lần nhấn chọn bên ngoài màn hình chụp mã vạch như sau:
Ứng với chức năng thêm vào danh sách mua hàng: các thông tin của
một hàng hóa trên danh sách các hàng hóa ứng với mã vạch được chụp sẽ
được chuyển sang “Màn hình thêm hàng hóa cần mua”. Trong màn hình này
ta sẽ có 2 thao tác chính như sau:
Nhấn nút “Thêm” để tiến hành thêm thông tin này vào danh sách
hàng hóa cần mua. Sau khi chương trình xử lý thêm xong, ta có
thể nhập thêm thông tin của một hàng hóa khác nữa vào danh sách
hàng hóa cần mua.
Nếu chỉ muốn thêm một hàng hóa và xem liền danh sách cần mua
thì ta nhấn chọn “Thêm và Xem”.
261
Hình phụ lục 189 Màn hình thêm thông tin của một hàng hóa vào danh sách hàng hóa cần mua
Ứng với chức năng thêm vào ưa thích: thông tin hàng hóa sẽ được lưu
thẳng vào danh sách các mặt hàng ưa thích và Màn hình danh sách các mặt
hàng ưa thích sẽ được hiển thị cho người dùng xem.
Hình phụ lục 190 Màn hình danh sách các hàng hóa ưa thích
Ứng với chức năng tìm hàng hóa: thông tin chi tiết của hàng hóa sẽ
được hiển thị ra cho người dùng xem.
262
Hình phụ lục 191 Màn hình thông tin chi tiết của một hàng hóa
L.4 Thao tác trên màn hình tìm theo danh mục hàng hóa
Hình phụ lục 192 Màn hình tìm kiếm theo danh mục hàng hóa và loại hàng hóa tương ứng
Nhấn chọn icon trên màn hình chính để mở ra được màn hình lựa
chọn danh mục hàng hóa. Nhấn chọn một dòng trên Danh mục hàng hóa sẽ mở lên
Màn hình loại hàng hóa chứa tất cả danh sách của các loại hàng hóa ứng với một
danh mục hàng hóa nào đó. Ví dụ như trong danh mục hàng hóa là “Thực Phẩm
263
Đông Lạnh” có các loại hàng hóa như “Các Loại Kem”, “Các Loại Lẩu Đông
Lạnh”…
Trên màn hình lựa chọn loại hàng hóa, khi nhấn chọn vào một dòng thì
chương trình sẽ mở ra màn hình danh sách hàng hóa nằm trong một loại hàng hóa
nào đó
Hình phụ lục 193 Màn hình danh sách hàng hóa
Và khi ta nhấn vào một dòng trên danh sách hàng hóa thì chương trình sẽ mở ra
màn hình chi tiết của hàng hóa đó.
264
L.5 Thao tác trên màn hình tìm theo chuỗi
Hình phụ lục 194 Màn hình tìm kiếm hàng hóa theo chuỗi
Nhấn chọn icon trên màn hình chính, chương trình sẽ mở ra màn
hình tìm hàng hóa theo chuỗi để giúp người dùng có thể tìm thấy hàng hóa mà mình
cần tìm.
Trong màn hình này ngoài tìm kiếm bằng chuỗi ta còn có thể nhấn nút
để gọi màn hình chụp mã vạch để lấy chuỗi mã vạch qua bên màn hình tìm theo
chuỗi này để thực hiện việc tìm kiếm chính xác hơn.
Khi người dùng điền đầy đủ các thông tin cần tìm thì người dùng nhấn nút
để yêu cầu server tìm kiếm các mặt hàng nào thỏa mãn yêu cầu tìm
kiếm của người dùng và trả về danh sách kết quả cho người dùng.
Khi người dùng nhấn nút Menu trên máy sẽ có thêm 2 chức năng phụ đó là:
trợ giúp và thoát chương trình
Hình phụ lục 195 Menu của màn hình tìm kiếm hàng hóa theo chuỗi
265
Khi ta nhấn chọn menu “Giúp Đỡ” chương trình sẽ mở ra màn hình
gợi ý giúp cho người dùng có thể thực hiện việc tìm kiếm chính xác hơn.
Hình phụ lục 196 Màn hình trợ giúp người dùng tìm kiếm hiệu quả hơn
Khi ta nhấn chọn menu “Thoát Chương Trình” thì sẽ thoát ứng dụng
eSaleShopping.
L.6 Thao tác trên màn hình tìm theo hệ thống siêu thị
Đây là chức năng hỗ trợ người dùng tìm kiếm các thông tin như:
Thông tin hệ thống siêu thị, siêu thị.
Bản đồ chỉ đường đến siêu thị nào đó hay đường đi đến siêu thị gần
nhất trong một hệ thống siêu thị.
Tìm kiếm hàng hóa đang được bán tại siêu thị theo các tiêu chí như:
tìm kiếm theo mã vạch, tìm kiếm theo chuỗi, tìm kiếm theo danh mục hàng
hóa.
L.6.1 Thao tác chính
Chọn biểu tượng từ màn hình chính ta sẽ tới được màn hình thể hiện
danh sách các hệ thống siêu thị như hình phụ lục 197
266
Hình phụ lục 197 Màn hình tìm theo danh sách hệ thống các siêu thị
Tiếp tục ta chọn một logo của hệ thống siêu thị tương ứng, ví dụ như logo
của hệ thống siêu thị Metro ta sẽ được màn hình có thể hiện danh sách
các siêu thị con của hệ thống siêu thị Metro
Hình phụ lục 198 Màn hình danh sách siêu thị con của hệ thống siêu thị
267
Khi nhấn chọn một siêu thị trong danh sách các siêu thị ta sẽ thấy các chức
năng như sau:
Thông tin của siêu thị được chọn.
Chỉ đường đi đến siêu thị.
Tìm hàng hóa của siêu thị đó theo chuỗi.
Tìm hàng hóa của siêu thị đó theo mã vạch.
Tìm hàng hóa của siêu thị đó theo danh mục.
Hình phụ lục 199 Các chức năng khi chọn vào một siêu thị trong một hệ thống siêu thị
L.6.2 Thao tác trên các chức năng trên một siêu thị được chọn
L.6.2.1 Thông tin siêu thị
268
Hình phụ lục 200 Màn hình thông tin chi tiết của một siêu thị
Đây là chức năng thể hiện thông tin chi tiết của một siêu thị như tên, địa chỉ,
số điện thoại liên hệ, giờ mở cửa, chương trình của siêu thị, hay các thông tin hỗ trợ
vận chuyển lắp đặt, hỗ trợ thanh toán thẻ, thông tin các máy rút tiền có tại siêu thị.
Nhấn để xem thông tin bản đồ đường đi đến siêu thị.
Nhấn để thực hiện gọi điện thoại tới số điện thoại của siêu thị.
Nhấn vào vùng để hiển thị ra vùng thông tin khác chức
thông tin của siêu thị như: thông tin hỗ trợ vận chuyển lắp đặt…
L.6.2.2 Chỉ đường đến siêu thị
269
Hình phụ lục 201 Màn hình thông tin bản đồ đường đi đến siêu thị
Đây là chức năng thể hiện bản đồ đường đi đến một siêu thị và có kết hợp
phần chỉ dẫn đường đi cụ thể.
Nhấn vào icon để mở ra vùng hướng dẫn chỉ dẫn đường đi cụ thể. Nhấn
lại icon một lần nữa để đóng lại vùng hiển thị này.
Nhấn Menu trên máy ta sẽ nhận được menu của ứng dụng bản đồ đường đi.
nhấn chọn “Chế Độ Xem” để hiển thị thêm 2 lựa chọn chế độ xem bản đồ là hình vẽ
hay hình vệ tinh.
Hình phụ lục 202 Menu của ứng dụng bản đồ đường đi đến siêu thị
L.6.3 Tìm hàng hóa siêu thị theo chuỗi
Đây là chức năng tìm kiếm hàng hóa theo một chuỗi nào đó. Hướng dẫn cách
thức thao tác trên màn hình tìm kiếm hàng hóa tìm theo chuỗi đã được chúng tôi
trình bày trong phần phụ lục L.5.
L.6.4 Tìm hàng hóa siêu thị theo mã vạch
270
Khi chọn lựa chức năng này, chương trình sẽ chuyển sang Màn hình chụp mã
vạch như đã hướng dẫn ở phần phụ lục L.3.
L.6.5 Tìm hàng hóa siêu thị theo danh mục
Hình phụ lục 203 Màn hình tìm kiếm theo danh mục hàng hóa và loại hàng hóa tương ứng
Khi chọn chức năng này, chương trình sẽ chuyển sang Màn hình lựa chọn
danh mục hàng hóa để cho phép người dùng lựa chọn. Phần hướng dẫn thao tác với
Màn hình danh mục hàng hóa đã được trình bày trong phần phụ lục L.4.
L.7 Thao tác quản lý danh sách hàng hóa ưa thích
Người dùng nhấn chọn từ màn hình chính để mở màn hình danh sách
hàng hóa ưa thích. Đây là màn hình có chức năng xem danh sách các mặt hàng ưa
thích cũng như xem giá cả hiện thời của món hàng ưu thích nào đó hiện đang bán ở
siêu thị nào, giá cả bao nhiêu.
Khi người dùng nhấn chọn vào một dòng trong danh sách hàng hóa ưa thích,
một vùng hiển thị danh sách các hệ thống siêu thị hiện đang bán mặt hàng đó sẽ
được cập nhật từ server và mở ra như hình phụ lục 195. Để thu vùng này lại ta cần
nhấn nút .
271
Hình phụ lục 204 Màn hình danh sách các mặt hàng ưa thích
L.8 Thao tác quản lý danh sách hàng hóa cần mua
Người dùng nhấn chọn từ màn hình chính để mở ra danh sách hàng
hóa cần mua. Đây là màn hình giúp ta quản lý được mặt hàng nào mua rồi, mặt
hàng nào cần mua thông qua 2 danh sách là Danh sách hàng hóa cần mua và Danh
sách hàng hóa đã được mua.
Hình phụ lục 205 Màn hình danh sách hàng hóa cần mua
272
Khi người dùng đang đứng ở danh sách này mà nhấn chọn một hàng hóa nào
đó thì hàng hóa đó sẽ được di chuyển qua danh sách còn lại.
Người dùng nhấn nút Menu trên thiết bị sẽ thấy được 3 chức năng đó là:
Thêm hàng cần mua, Xóa hàng cần mua, Gửi tin hàng cần mua.
Hình phụ lục 206 Menu của màn hình danh sách hàng cần mua
L.8.1 Thao tác thêm hàng cần mua
Hình phụ lục 207 Màn hình thêm hàng hóa cần mua
Màn hình này giúp người dùng nhập các thông tin hàng hóa cần mua. Người
dùng nếu muốn chỉ thêm một hàng cần mua và xem danh sách hàng cần mua thì
nhấn nút “Thêm và Xem”, còn nếu muốn nhập nhiều lần thì nhấn nút “Thêm”.
L.8.2 Thao tác xóa hàng cần mua
273
Hình phụ lục 208 Màn hình xóa hàng cần mua
Màn hình này giúp người dùng xóa một phần hoặc xóa hết danh sách hàng
hóa cần mua. Nếu muốn xóa một mặt hàng người dùng nhấn chọn vào một dòng,
chương trình sẽ hiện lên hộp thoại hỏi lại người dùng có thực sự muốn xóa mặt
hàng đó hay không. Còn người dùng nếu muốn xóa toàn bộ danh sách thì chỉ cần
nhấn nút “Xóa Hết”.
Hình phụ lục 209 Hộp thoại hỏi người dùng có thực sự muốn xóa một mặt hàng nào đó hay không
L.8.3 Thao tác gửi tin nhắn hàng cần mua
274
Hình phụ lục 210 Màn hình gửi tin nhắn hàng cần mua
Đây là chức năng gửi tin nhắn SMS cho một người nào đó nhờ họ mua giùm
các mặt hàng có trong danh sách hàng hóa cần mua. Người dùng chỉ việc kiểm tra
lại nội dung tin nhắn lần cuối và nhấn nút gửi đi.
275
Phụ lục M Các cấu trúc, mã lệnh, ứng dụng tham
khảo được sử dụng trong ứng dụng eSaleShopping
M.1 Bộ gõ Tiếng Việt IME
Đóng góp phần không nhỏ cho ứng dụng eSaleShopping đó chính là ứng
dụng bộ gõ Tiếng Việt để thực hiện tìm kiếm thông tin hàng hóa bằng Tiếng Việt.
Nhóm đã quyết định là dùng bộ gõ Tiếng Việt IME (đã được diễn đàn tinhte.com
giới thiệu gần đây - ản-
1.9-bộ-gõ-tiếng-Việt-đầu-tiên-trên-Android) để có thể gõ được Tiếng Việt trên
Android và phục vụ cho chức năng tìm kiếm hàng hóa bằng Tiếng Việt.
Bộ gõ Tiếng Việt IME do tác giả Phạm Cao Trí phát triển và phát hành miễn
phí đối với người dùng tại địa chỉ Phiên
bản mới nhất là VietnameseIME-1.9.1 hỗ trợ 2 kiểu gõ Tiếng Việt là VNI và
TELEX rất tốt, giao diện đẹp. Ở phiên bản này tác giả đã cải tiến, thêm một số tính
năng mới như: hỗ trợ tốt cho các phiên bản Android (từ 1.5 đến 2.1), chỉnh độ rung
khi gõ phím, chỉnh âm lượng khi gõ phím, có tùy chọn màu sắc bàn phím, và chức
năng đặc sắc là hỗ trợ từ điển gợi ý Tiếng Việt kết hợp với chức năng tự tạo một từ
điển gợi ý cho riêng người dùng. Hình bên dưới là hình chụp màn hình gửi tin nhắn
SMS dùng bộ gõ Tiếng Việt IME để gõ tiếng Việt với 2 phiên bản Android là 1.5 và
2.1.
276
Hình phụ lục 211 Màn hình sử dụng bộ gõ Tiếng Việt IME trên Android 1.5 và 2.1
M.2 Chụp mã vạch hàng hóa (barcode)
Trong ứng dụng eSaleShopping có chức năng chụp mã vạch của một hàng
hóa bất kỳ, sau đó lấy kết quả mã vạch phân tích được từ hình chụp gồm 13 chữ số
và tiến hành gửi mã vạch này lên server yêu cầu server trả về thông tin hàng hóa
ứng với mã vạch đó.
Trong quá trình tìm hiểu ý tưởng, công nghệ để hỗ trợ cho chức năng vừa
nêu, nhóm đã gặp nhiều khó khăn. Khó khăn lớn nhất là làm sao chụp được hình
ảnh của một mã vạch được in trên hàng hóa và phân tích hình ảnh này thành chuỗi
số để có thể gửi lên cho server yêu cầu tìm kiếm thông tin hàng hóa. Việc viết riêng
một chương trình chụp mã vạch là một điều không khả thi. Nhóm đã chuyển sang
tìm hiểu theo một hướng khác là tích hợp các module chụp mã vạch đã được công
bố trên mạng vào chương trình eSaleShopping. Sau nhiều lần tìm kiếm giải pháp
trên mạng, nhóm đã tìm thấy ZXing ("Zebra Crossing") một project mở với giấy
phép Apache License 2.0 ( được
công bố trên Google Code ( Khi tải về bộ mã
277
nguồn của ZXing chúng tôi nhận thấy toàn bộ mã nguồn hỗ trợ cho nhiều nền tảng,
hệ điều hành khác nhau như RIM, iPhone, Android…
Hình phụ lục 212 Nội dung của một gói mã nguồn ZXing
Hình phụ lục 213 Mã nguồn ZXing dành cho HĐH Android
Tuy “gánh nặng” chụp mã vạch đã được giảm bớt nhưng việc áp dụng
project ZXing này vào ứng dụng cũng là một khó khăn không nhỏ do toàn bộ mã
nguồn được công bố hết sức “đồ sộ”. Để nắm bắt và ứng dụng được bộ mã nguồn
này thì lượng thời gian bỏ ra để tìm hiểu là không nhỏ. Sau một hồi lần tìm giải
pháp trên mạng, nhóm chúng tôi cũng tìm được một giải pháp thay thế đó chính là
nhờ chương trình Barcode Scanner chụp phân giải mã vạch và trả kết quả về cho
278
ứng dụng eSaleShopping. Barcode Scanner cũng do nhóm ZXing phát triển (địa chỉ
tải về ứng dụng Việc
gọi thực thi Barcode Scanner để lấy kết quả mã vạch được thực hiện thông qua gọi
Intent cũng được nhóm ZXing hướng dẫn cụ thể tại:
public Button.OnClickListener mScan = new Button.OnClickListener() {
public void onClick(View v) {
Intent intent = new
Intent("com.google.zxing.client.android.SCAN");
intent.putExtra("SCAN_MODE", "QR_CODE_MODE");
startActivityForResult(intent, 0);
}
};
public void onActivityResult(int requestCode, int resultCode, Intent
intent) {
if (requestCode == 0) {
if (resultCode == RESULT_OK) {
String contents = intent.getStringExtra("SCAN_RESULT");
String format = intent.getStringExtra("SCAN_RESULT_FORMAT");
// Handle successful scan
} else if (resultCode == RESULT_CANCELED) {
// Handle cancel
}
}
}
Để tiện dụng hơn, nhóm chúng tôi đã dùng lớp IntentIntegrator.java và lớp
IntentResult.java (các lớp này được tiết kế bởi các tác giả: Sean Owen, Fred Lin,
Isaac Potoczny-Jones) để thực hiện việc gọi Intent kích hoạt chương trình Barcode
Scanner chụp ảnh mã vạch và yêu cầu lấy kết quả trả về thông qua các phương thức
initiateScan(…) và parseActivityResult(…) trên các Activity gọi và nhận kết
quả từ chương trình Barcode Scanner.
Cách gọi ứng dụng Barcode Scanner trên Activity ManHinhTimTheoMaVach:
việc gọi Intent được thực hiện thông qua sự kiện nhấn nút “Đọc Mã Vạch”
// button chụp barcode
btnReadBarcode.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
IntentIntegrator.initiateScan(ManHinhTimTheoMaVach.this);
IntentIntegrator.initiateScan(ManHinhTimTheoMaVach.this,
279
"Thông Báo",
"Đồng ý tải về chương trình Barcode Scanner không?",
"Đồng Ý", "Không");
}
});
Cách thức lấy kết quả trả về từ ứng dụng Barcode Scanner:
protected void onActivityResult(int requestCode, int resultCode, Intent
data) {
switch (requestCode) {
case IntentIntegrator.REQUEST_CODE: {
if (resultCode != RESULT_CANCELED) {
IntentResult scanResult =
IntentIntegrator.parseActivityResult(
requestCode, resultCode, data);
if (scanResult != null) {
String upc = scanResult.getContents();
TextView txtBarcodeResult = (TextView)
findViewById(R.id.TextViewBarcodeResult);
txtBarcodeResult.setText("" + upc);
// . . .
break;
}
}
Một điểm thú vị của 2 lớp IntentIntegrator.java và lớp IntentResult.java là
khi điện thoại không có sẵn chương trình đọc mã vạch là Barcode Scanner thì sẽ
xuất hiện thông báo và hỏi người dùng có muốn tải về ứng dụng Barcode Scanner
hay không. Nếu đồng ý tải về thì chương trình sẽ tìm kiếm ứng dụng Barcode
Scanner thông qua Android Market để tiến hành tải và cài đặt ứng dụng.
Nhóm chúng tôi rất hoan nghênh và cám ơn cộng đồng mã nguồn mở cũng
như các nhà lập trình đã phát triển và cung cấp những ứng dụng, project thật sự hay
và có chất lượng như bộ mã mở ZXing như đã đề cập ở trên.
M.3 Ứng dụng bản đồ và vị trí
M.3.1 Các tham số Google Map hỗ trợ tìm kiếm đường đi
280
Việc Google mở rộng hỗ trợ chỉ đường đi cho Việt Nam là một điều thuận
lợi cho nhóm tích hợp phần chỉ đường đi này vào bản đồ và chỉ ra đường đi tới siêu
thị gần nhất. Thông tin yêu cầu đường đi sẽ được gửi lên Google với các tham số
theo quy định ( Sau khi tính toán
lộ trình đường đi, Google sẽ trả ra kết quả là một tập tin KML có cấu trúc dạng các
thẻ XML. Ta chỉ việc phân tích thông tin từ tập tin này để có được hướng dẫn chỉ
đường đi từ Google.
Sau đây là ví dụ mẫu về yêu cầu tìm đường đi từ 2 điểm có kinh độ và vĩ độ
biết trước và gửi yêu cầu lên Google tìm đường đi giữa 2 điểm ấy:
848731,106.773877&ie=UTF8&0&om=0&output=kml. Với saddr là thông tin
kinh độ, vĩ độ của điểm xuất phát; dsddr là thông tin kinh độ, vĩ độ của điểm cần
đến.
Nội dung của một tập tin KML được trả về từ Google
<kml
xmlns="">Nguyễn Trãi to
Unknown road<Style
id="roadStyle">7fcf00646</LineSt
yle><a
href="
r=10.848731,106.773877&ie=UTF8&om=0">Printable
view]]>Head east on Nguyễn Trãi
toward Nguyen Bieu<![CDATA[go
0.2 km]]>Nguyễn
Trãinormal<h
ref>
<hotSpot x="0.500000" y="0.000000" xunits="fraction"
yunits="fraction"
/>
ALL/mapfiles/kml/paddle/go-lv.png . . .
M.3.2 Thể hiện đường đi trên bản đồ Google Map
Nhóm đã tham khảo và áp dụng bài viết chỉ dẫn vẽ đường đi lên bản đồ
GoogleMap là: Android - Driving Direction (Route Path) tại địa chỉ
tw.blogspot.com/2009/06/android-driving-direction-route-path.html để hiện thực
hóa chức năng chỉ đường đi đến siêu thị.
281
Hình phụ lục 214 Ứng dụng vẽ đường đi trên bản đồ Google Map trong eSaleShopping
Nhóm đã tham khảo 2 lớp là Direction.java (truyền tham số lên Google) và
MyOverlay.java (vẽ đường đi trên bản đồ) để áp dụng vào ứng dụng
eSaleShopping. Bên cạnh tham khảo 2 lớp này, nhóm đã tiến hành xử lý lại thuật
toán đọc tập tin KML để có thể lấy về cũng như tính toán ra đường đi ngắn nhất đến
một siêu thị gần nhất.
M.3.3 Cách thức tìm vị trí thiết bị thông qua GPS hoặc mạng
Để chương trình có thể xác định được vị trí hiện tại nhóm đã tham khảo bài
viết “Android Examples - Using Location API”, được viết bởi tác giả Marko
Gargenta tại địa chỉ
và mã nguồn tham khảo của bài viết tại địa chỉ
Đồng thời nhóm cũng có tham khảo bài viết của thành viên có nickname là
jagtap.jj1 trên diễn đàn anddev.org với phần bài viết là “app with GPS-enable but
the device is indoor” (
enable_but_the_device_is_indoor-t8997.html) để tham khảo 2 phương:
282
startLocationReceiving(), stopLocationReceiving() cho việc khởi động hay
dừng các thiết bị nhận tín hiệu xác định vị trí hiện tại.
M.4 Ứng dụng EndlessList
Khái niệm EndlessList đã được chúng tôi trình bày trong phụ lục J. Ở phần
này chúng tôi chỉ trình bày 2 giải pháp tiêu biểu mà chúng tôi có dịp tham khảo và
áp dụng vào ứng dụng eSaleShopping.
M.4.1 Giải pháp của M.Murphy
Mark Murphy hiện làm việc cho Commons Ware, email liên hệ:
mmurphy@commonsware.com
Tác giả có cung cấp sẵn mã nguồn cũng như hướng dẫn sử dụng project
CWAC EndlessAdapter tại địa chỉ
Nhóm đã có dịp dùng và ứng dụng EndlessAdapter của M.Murphy vào bài toán
EndlessList. Việc ứng dụng EndlessList vào tuy đã giải quyết được vấn dề của
EndlessList nhưng bên cạnh đó EndlessAdapter còn tồn tại một lỗi nhỏ đó là vòng
tròn xoay thể hiện tiến trình download dữ liệu mới từ server để gắn thêm vào
ListView hiển thị bị lỗi. Chúng hiển thị không có kiểm soát trên màn hình
ListView. Do mã nguồn của ứng dụng được tác giả đóng gói thành một tập tin .jar
nên nhóm chúng tôi không thể hiệu chỉnh lại lỗi này nên đã tiến hành tìm kiếm giải
pháp khác cho vấn đề EndlessList. Hình bên dưới thể hiện ứng dụng chạy của
EndlessAdapter và bug lỗi của nó.
283
Hình phụ lục 215 Hình minh họa và bug lỗi cũa EndlessAdapter
M.4.2 Giải pháp của Evan Charlton
Tác giả Evan Charlton hiện là sinh viên năm 4 của học viện công nghệ
Rochester ( Trong bài viết công bố trên mạng của
tác giả ( nhóm
thấy đây là một nguồn tham khảo rất hữu ích. Ứng dụng Magnatune
( của tác giả không những
giải quyết rất tốt vấn đề của EndlessList đồng thời cũng có cách giải quyết việc
download hình ảnh minh họa về máy một cách linh hoạt và uyển chuyển. Ứng dụng
Magnatune sẽ tải về máy thông tin (chuỗi ký tự) tên các bài hát, album, thông tin
nhạc sĩ ca sĩ từ server về hiển thị trước trên ListView và hình ảnh sẽ được download
về tại thẻ nhớ và khi download được hình nào thì sẽ hiển thị lên trên ListView ngay
sau đó như hình minh họa bên dưới.
Nhóm chúng tôi đã dùng lại các hàm thiết kế của tác giả để phục vụ cho ứng
dụng eSaleShopping là:
284
Dùng lại các lớp HTTPQueue.java, HTTPThread.java,
RemoteImageView.java: phục vụ cho việc chạy ngầm tải hình ảnh từ server
về dưới dạng danh sách hàng đợi dùng Thread.
Hiệu chỉnh lớp MagnatuneAPI.java nhưng có chỉnh sửa lại cho phù
hợp để phục vụ việc lưu vết thư mục tạm lưu trữ hình ảnh từ server về.
Hiệu chỉnh lớp LazyAdapter.java phục vụ hiển thị một item trên
ListView.
Hiệu chỉnh lớp LazyActivity.java, đây là lớp mà nhóm tham khảo kỹ
nhất và thực hiện viết lại một số tính năng cho phù hợp vì trong lớp này chứa
giải pháp giải quyết vấn đề của EndlessList cực kỳ hiệu quả đó là dùng Task
không đồng bộ. Vấn đề dùng Task không đồng bộ đã được nhóm trình bày
tại phụ lục J.
Hình phụ lục 216 Hình minh họa của ứng dụng Magnatune
M.5 Mã nguồn android-misc-widgets
Đây là một project được viết bởi tác giả có nickname là pskink
( được đăng tải trên Google Code tại địa chỉ
285
Đây là một project chứa một loạt
các hiệu ứng chuyển động (animation) và widget mới rất tiện dụng và hữu ích.
Nhóm chúng tôi đã áp dụng một số lớp, thiết kế trong projec android-misc-widget
để làm phong phú thêm cho ứng dụng eSaleShopping.
M.5.1 Hiệu ứng hoạt cảnh
Nhóm chúng tôi đã dùng lại hết các lớp tạo hiệu ứng chuyển động vào ứng
dụng eSaleShopping. Đó là các ứng với hình minh họa bên dưới.
Hình phụ lục 217 Các lớp tạo hiệu ứng chuyển động được dùng lại trong ứng dụng eSaleShopping
M.5.2 Các widget mới
Nhóm đã dùng lại 2 widget mới đó có tên là Panel và Switcher để làm cho
ứng dụng eSaleShopping thêm phần phong phú hơn.
286
Hình phụ lục 218 Ứng dụng Panel tạo khung chỉ đường đi trên bản đồ trong eSaleShopping
Hình phụ lục 219 Ứng dụng Switcher tạo lựa chọn hình thức bán hàng trong eSaleShopping
Các file đính kèm theo tài liệu này:
- thesis_appendix_final_139.pdf