Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

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ộ.

pdf286 trang | Chia sẻ: lylyngoc | Lượt xem: 3267 | Lượt tải: 2download
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:

  • pdfthesis_appendix_final_139.pdf