Thursday, May 16, 2013

[Android Nâng Cao] Sử Dụng ViewPager Cho Chuyển Đổi View

Xin chào các bạn, hôm nay mình sẽ hướng dẫn các bạn cách sử dụng ViewPager cho việc chuyển Activity đồng thời khi vuốt tay ( giống như khi vào Play Store các bạn vuốt tay qua trái phải để xem Top Paid apps > Top Free apps....).

I. Giới Thiệu ViewPager

Theo android.com, thì ViewPager là một trình quản lý Layout cho phép người dùng vuốt tay qua trái hay qua bên phải để chuyển sang nội dung của trang khác một cách đồng thời. Điểm khác nhau của ViewPager và cách sử dụng Gesture đó là, gesture sẽ chỉ thực hiện khi người dùng thực hiện xong thao tác vuốt tay, trong khi ViewPager thực hiện chuyển màn hình đồng thời với cử chỉ tay người dùng.

II. Code Now


1. Chuẩn bị

ViewPager không phải là một View chuẩn của Android, mà là một thành phần nằm trong gói android.support.v4.View
Nếu bạn chưa có gói này, có thể cài đặt bằng cách, mở Android SDK Manager->Extra-> tick chọn Android Support package->OK

Sau khi cài đặt, các bạn sẽ thấy có thêm một gói android-support-v4.jar nằm trong project của mình.

2. Code Now

a. Tạo mới một project mới, ví dụ đặt tên là MyApps

b. Thay đổi nội dung file main.xml như bên dưới


Mã:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity" >

<android.support.v4.view.ViewPager
android:id="@+id/pager"
android:layout_width="match_parent"
android:layout_height="match_parent"
></android.support.v4.view.ViewPager>

</RelativeLayout>

c. Tạo các layout cho các màn hình khác nhau khi vuốt qua trái, qua phải. Ở đây mình tạo 5 file xml cho 5 màn hình.

- layout_1.xml

Mã:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<TextView
android:id="@+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Nhip"
android:textAppearance="?android:attr/textAppearanceLarge" />
</LinearLayout>

- layout_2.xml

Mã:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >

<TextView
android:id="@+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Song"
android:textAppearance="?android:attr/textAppearanceLarge" />

</LinearLayout>

- layout_3.xml

Mã:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >

<TextView
android:id="@+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Di"
android:textAppearance="?android:attr/textAppearanceLarge" />

</LinearLayout>

- layout_4.xml

Mã:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >

<TextView
android:id="@+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Dong"
android:textAppearance="?android:attr/textAppearanceLarge" />

</LinearLayout>

- layout_5.xml

Mã:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >

<TextView
android:id="@+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Nhipsongdidong.vn"
android:textAppearance="?android:attr/textAppearanceLarge" />

</LinearLayout>

Phần thiết kế màn hình coi như xong.

d. Code

Cũng giống như ListView hay các các thành phần khác, ViewPager bắt buộc phải cần một Adapter để có thể xác định nội dung cần hiển thị lên View.

- Tạo một class mới kế thừa từ PagerAdapter , đặt tên là MyPagerAdapter ( chẳng hạn)

Mã:
public class PagerAdapter extends android.support.v4.view.PagerAdapter{


@Override
public int getCount() {
//Do ở đây mình có 5 Activity nên count trả về là 5
return 5;
}

//Hàm khởi tạo View dùng cho việc hiển thị Activity chính xác
//Hàm có chức năng nôm na như hàm getView thường thấy trong Adapter của ListView, hay chính xác hơn là
//makeView trong ImageSwitcher vậy
@Override
public Object instantiateItem(ViewGroup container, int position) {

LayoutInflater li = (LayoutInflater) container.getContext().
getSystemService(Context.LAYOUT_INFLATER_SERVICE);

int resId=0;
switch(position)
{
case 0:
resId = R.layout.layout_1;
break;
case 1:
resId = R.layout.layout_2;
break;
case 2:
resId = R.layout.layout_3;
break;
case 3:
resId = R.layout.layout_4;
break;
case 4:
resId = R.layout.layout_5;
break;
}

View view = li.inflate(resId, null);
container.addView(view, 0);
return view;
}
//View nào ko còn hiển thị nữa thì xóa đi
@Override
public void destroyItem(ViewGroup container, int position, Object object) {
container.removeView((View) object);

}
@Override
public boolean isViewFromObject(View arg0, Object arg1) {
return arg0 == (View)arg1;
}
}

- Activity chính của chương trình.

Mã:
public class MainActivity extends Activity {

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
PagerAdapter a = new PagerAdapter();
ViewPager p = (ViewPager) findViewById(R.id.pager);
p.setAdapter(a);
p.setCurrentItem(2);
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.activity_main, menu);
return true;
}

}

3. Chạy chương trình và trải nghiệm


Các bạn có thắc mắc có thể góp ý tại đây luôn nhé.
Chúc vui.

Tuesday, April 23, 2013

Nền tảng Android – bức tranh nhìn từ trên cao

Vài nét về quá trình ra đời

Ngày nay, điện thoại di động hiện diện ở khắp mọi nơi. Một người có thể không có máy vi tính nhưng gần như không thể không có điện thoại di động. Điện thoại di động ngày càng thông minh và chúng đang dần thay thế các thiết bị di động cá nhân khác như: đồng hồ, máy tính cầm tay, máy ảnh du lịch, máy nghe nhạc MP3, hoặc các thiết bị có khả năng kết nối internet khác. Rõ ràng thị trường di động là một miếng bánh khổng lồ mà không ai có thể một mình nuốt gọn. Các nhà phát triển cũng cảm thấy sức hấp dẫn mà miếng bánh tỏa ra. Nhưng việc phát triển phần mềm cho các thiết bị di động chưa bao giờ là công việc đơn giản. Có hàng loạt các vấn đề mà các nhà phát triển phần mềm cho thiết bi di động trước kia phải đối mặt:

  • Không có mã nguồn của các nền tảng để giúp họ hình dung ra được cơ chế hoạt động đằng sau đó.
  • Giá thành để phát triển một sản phẩm cao do phải trả phí mua bản quyền API hoặc công cụ phát triển.
  • Vướng phải những ràng buộc hoặc giới hạn nhất định về tính năng khi phát triển kể cả khi họ có giấy phép phát triển.
  • Không có một bộ công cụ phát triển (SDK) nào thực sự dễ dàng cho việc xây dựng ứng dụng di động.
  • Không có một cơ chế phân phối sản phẩm hiệu quả đến người dùng cuối cũng như cách thức cài đặt phần mềm đơn giản lên thiết bị của họ.
Vậy chúng ta cần những gì để tạo ra một thiết bị di động tốt hơn, chi phí phát triển rẻ hơn và tạo ra nhiều lợi ích cho người dùng hơn? Đó chính là câu hỏi mà liên minh Open Handset Alliance gồm trên 40 hãng từ nhiều lĩnh vực liên quan do Google khởi sướng muốn giải đáp. Và câu trả lời của họ chính là hệ sinh thái Android.
Hình 1: Các thành viên trong liên minh OHA
Vào tháng 10-2008, thiết bị đầu tiên chạy Android được Google và HTC phối hợp phát triển đã ra đời với tên gọi G1. Từ đó đến nay, Android đã trải qua nhiều phiên bản với nhiều cải tiến, đã có vô số các thiết bị chạy nền tảng này được tung ra thị trường với mức độ đa dạng chưa từng thấy. Hiện Samsung đang là hãng sản xuất và phân phối hàng đầu các thiết bị chạy Android trên toàn cầu.
Nền tảng Android về cơ bản đáp ứng được những đòi hỏi của OHA:

  • Đó là một nền tảng mở vì vậy các nhà phát triển dễ dàng đào sâu tìm hiểu cũng như dễ dàng tạo ra những thành phần tích hợp hoặc tùy biến cho nó.
  • Ngoài ra cộng đồng phát triển Android còn được hỗ trợ bộ công cụ phát triển (SDK) hoàn chỉnh và dễ sử dụng.
  • Kênh phân phối sản phẩm đến tay người sử dụng rất phong phú cả về phần cứng lẫn phần mềm.
Để đạt được những điều đó yêu cầu Android phải có một kiến trúc mềm dẻo, khai thác được tối đa sức mạnh phần cứng cũng như sự thân thiện trong giao diện người dùng. Tuy vậy, Android không phải là không có những nhược điểm so với những nền tảng cạnh tranh khác, tuy nhiên trong phạm vi bài viết này ta sẽ chỉ mô tả bức tranh về Android như là nó vốn thế.

Nền tảng Android

Android được phát triển dựa trên nhân của Linux nên kế thừa được khả năng quản lý tài nguyên tốt từ hệ thống này. Toàn bộ các ứng dụng được thực thi bởi Dalvik VM, một máy ảo tượng tự như JVM nhưng đã được tối ưu cho thiết bị di động. Các ứng dụng được phát triển trên một framework linh hoạt giúp khai thác các tài nguyên của hệ thống. Hình dưới đây cho thấy bức tranh khái quát về các khối phần mềm trong toàn bộ nền tảng Android.

Hình 2: Các khối cơ bản trong nền tảng Android
Điểm đặc biệt đối với các ứng dụng Android là chúng được phát triển trên cùng một cấp, do vậy khái niệm phần mềm hệ thống và phần mềm thông thường chỉ mang tính chất tương đối. Bất cứ một ứng dụng hệ thống cơ bản nào (như ứng dụng gọi điện, nhắn tin, trình duyệt v.v…) cũng có thể bị thay thế bằng các ứng dụng khác tương tự.

Ngôn ngữ phát triển và cách thức biên dịch

Ngôn ngữ lập trình chính để viết các ứng dụng Android là Java, vì vậy nếu bạn có hứng thú phát triển ứng dụng cho nền tảng này thì hãy đầu tư thời gian vào Java căn bản trước khi bắt tay vào nghiên cứu nó.
Các ứng dụng Android có thể được phân làm hai loại căn cứ vào ngôn ngữ phát triển và cách thức biên dịch:
  • Ứng dụng Dalvik: ứng dụng được viết bằng ngôn ngữ lập trình Java, sử dụng các công cụ trong bộ SDK (Google) và JDK (Oracle) biên dịch và đóng gói thành file .apk trước khi cài đặt vào thiết bị.
Hình 4: Quá trình biên dịch từ mã nguồn Java của loại ứng dụng Dalvik
  • Ứng dụng Native: bên cạnh sử dụng mã nguồn Java, ta có thể sử dụng mã nguồn C/C++ kết hợp để xây dựng ứng dụng nhằm tối ưu hóa và tăng tốc độ thực thi hoặc khai thác các thư viện cấp thấp. Để biên dịch được ứng dụng loại này ngoài bộ SDK bạn phải cần thêm bộ NDK.
Hình 5: Quá trình biên dịch của ứng dụng Native
Mặc dù các ứng dụng Android được phát triển và biên dịch thông qua JDK nhưng không phải tất cả mọi thứ trong JDK đều có thể sử dụng được. Dưới đây là hình ảnh tham khảo về API trong JDK và mức độ được sử dụng trong Android:
Hình 6: Một phần Core Java trong Android

Kiến trúc ứng dụng

Ứng dụng Android được xây dựng từ nhiều thành phần có thể coi là những viên gạch cơ bản trong ứng dụng. Những viên gạch này bao gồm nhiều loại có thể chia thành ba nhóm căn cứ vào mục đích sử dụng:
  1. Những thành phần tạo giao diện người dùng: Activity, View/Widget
  2. Những thành phần cung cấp dịch vụ và tích hợp: Service, Broadcast Receiver/Intent.
  3. Những thành phần cung cấp dữ liệu, tài nguyên và cấu hình của ứng dụng: Content Provider, Resource, ApplicationManifest.
Hình 7: Các thành phần cơ bản trong một ứng dụng Android

1. Những thành phần tạo giao diện người dùng

  • Activity: đây chính là không gian cửa sổ nơi mà mọi thứ được hiển thị ra. Tuy nhiên trên màn hình nhỏ thì mỗi Activity sẽ chiếm trọn màn hình thiết bị, người dùng có thể di chuyển qua lại giữa các Activity thông qua thao tác điều hướng. Về mặt kiến trúc Activity tương đương với ViewModel trong kiến trúc MVVM (Model – View – ViewModel) rất quen thuộc trong các nền tảng lập trình khác như Windows Phone, WPF, JavaFX v.v… Với kiến trúc như vậy mỗi Activity được kết hợp với một Layout mô tả bố cục và các thành phần hiển thị trên đó (các View). Những mô tả này sử dụng ngôn ngữ XML và được đặt trong thư mục /res (xem hình 10).
  • View: đây là các thành phần hiển thị trên Activity như Button, CheckBox v.v… nó được thiết kế theo mô hình Composite giống như tất cả các hệ thống GUI khác. Sơ đồ sau đây thể hiện các lớp cơ bản để dựng giao diện trong Android:
Hình 8: Sơ đồ phân cấp của View
  • Widget: về bản chất đây là một ViewGroup, có khả năng hiển thị trên màn hình Home các thành phần cơ bản trong hệ thống View. Nhưng sự khác biệt này làm cho màn hình Home của Android trở nên rất sinh động và hữu dụng.
Hình 9: Hình ảnh về các widget trên màn hình Home

2. Những thành phần cung cấp dịch vụ và tích hợp

Android cung cấp một loại các thành phần nghiệp vụ cho phép các nhà phát triển khai thác các tính năng phần cứng cũng như các dịch vụ cơ bản của hệ thống để tạo nên những ứng dụng phong phú. Có thể chỉ ra một số thành phần cơ bản như:

  • Service: lập trình viên có thể khai thác các dịch vụ có sẵn hoặc tạo ra các dịch vụ chạy ngầm định khác trong hệ thống. Các dịch vụ này có thể được truy cập từ bất cứ ứng dụng nào.
  • Broadcast Receiver: đây là thành phần thú vị giúp ứng dụng của bạn có khả năng phản ứng lại với các sự kiện trong hệ thống hoặc liên quan đến việc xử lý một dữ liệu nào đó. Nhờ nó các ứng dụng trong Android tạo nên một môi trường ứng dụng thống nhất, người dùng thay vì có cảm giác “đang chạy một ứng dụng để làm việc gì đó” sẽ thấy rằng mình “đang làm một việc gì đó trong ngữ cảnh với một ứng dụng phù hợp”.
  • Intent: đây là thành phần cơ bản trong cơ chế quản lý giao tiếp của Android, nó cho phép chuyển đổi, truyền và nhận thông điệp giữa các Activity.

3. Những thành phần cung cấp dữ liệu, tài nguyên và cấu hình ứng dụng

  • Content Provider: có thể hình dung Content Provider giống như một database server thu nhỏ cung cấp khả năng truy vấn vào các nguồn dữ liệu khác nhau (phổ biến là SQLite) thông qua một URI (ví dụ như các dữ liệu Contact, Message v.v…). Kết quả truy vấn của Content Provider luôn trả về đối tượng Cursor (có thể hình dung nó như là ResultSet trong JDBC).
  • Resource: tài nguyên có thể sử dụng trong ứng dụng rất phong phú bao gồm hình ảnh, âm thanh, văn bản, văn bản đa ngôn ngữ, layout, xml v.v… tất cả chúng nằm trong thư mục /res. Mọi thứ trong /res không đơn giản chỉ là một phần được đóng gói đi cùng ứng dụng mà chúng có thể được thao tác và truy xuất từ trong code một cách dễ dàng ở thời điểm chạy cũng như khi đang biên địch (thông qua một lớp được sinh tự động nhằm tối ưu hóa việc truy xuất tài nguyên có tên là R.java).
  • AndroidManifest.xml: đây là file cấu hình cho mỗi ứng dụng android, nó chứa các thông tin cơ bản của ứng dụng cho hệ điều hành như điểm truy xuất, các quyền hạn, các thông tin cài đặt, cấu hình v.v…

Hình 10: Cấu trúc của một Android Project trong Eclipse

Bắt đầu khám phá

Bài viết đến đây mới chỉ là sự khởi đầu, ta vừa nhìn xuống “thành phố Android” từ trên máy bay, khi đó ta chỉ cảm nhận được những mảng, khối cơ bản mà không thấy chi tiết. Nhưng hy vọng với từng đó đã giúp bạn định vị được rằng để tiếp tục cuộc hành trình khám phá “thành phố” này bạn nên bắt đầu từ đâu và như thế nào. Chúc các bạn có một chuyến đi vui vẻ!

Tài nguyên

ebook: Android In Practice by Charlie Collins & Michael Galpin & Matthias Kaeppler
http://www.ibm.com/developerworks/library/os-android-devel/
http://software.intel.com/en-us/articles/android-application-development-and-optimization-on-the-intel-atom-platform
http://vladnevzorov.com/2011/04/30/android-application-architecture-part-ii-architectural-styles-and-patterns/
http://apcmag.com/whats-android.htm
https://vkroz.wordpress.com/category/android/

Nguồn: tapchilaptrinh

Monday, April 15, 2013

Socket trong Android

Trong bài này mình sẽ giới thiệu với các bạn về lập trình Socket(bài này mình chỉ nói đến lập trình Socket cho TCP/IP) trong Android.
Lập trình Socket chắc hẳn rất quen thuộc với các bạn học CNTT, vì thế mình chỉ nói lại một số vấn đề chính liên quan đến Socket:
- Socket là một phương pháp để thiết lập kết nối truyền thông giữa một chương trình yêu cầu dịch vụ ( client) và một chương trình cung cấp dịch vụ (server) trên mạng LAN, WAN hay Internet. Một socket trên máy yêu cầu dịch vụ có địa chỉ mạng được cấp sẵn để gọi một socket trên máy cung cấp dịch vụ. Một khi socket đó được thiết lập phù hợp, hai bên có thể trao đổi dịch vụ và dữ liệu.
-Tóm váy lại là thằng Server thì phải tạo một Server luôn luôn lắng nghe (luôn luôn thấu hiểu) ở một cổng nào đó ví dụ 8888 chẳng hạn. Thằng Client muốn kết nối được đến Server để gửi yêu cầu thì phải xác định được cổng đó và IP của Server.


Cơ bản về lý thuyết chỉ có thế, các bạn muốn tìm hiểu kĩ thì cứ Google mà tra, sau đây là phần Socket cho Android. Mình sẽ làm một ví dụ minh họa: Bên Client sẽ gửi 2 số sang bên Server, Server nhận được sẽ tính tổng 2 số đó và gửi lại Client hiển thị

1.Về Server:
Các bạn có thể viết Server bằng bất kỳ ngôn ngữ j, ở đây mình viết bằng Java cho mọi người dễ hiểu:

-Đầu tiên ta tạo một class ServerSocket với port 9999: (chú ý phải đặt trong try catch)


Code:
ServerSocket ss=new ServerSocket(9999);
-Tạo vòng lặp để luôn lắng nghe yêu cầu của Client:
Code:
while (true){
Socket cl=ss.accept();//Chap nhan client ket noi den
System.out.printf("Client Connect");

BufferedReader br=new BufferedReader(new InputStreamReader(cl.getInputStream())); //Khoi tao luong doc du lieu
String a=br.readLine();
String b=br.readLine();//Doc 2 so a va b client gui den

PrintWriter pr=new PrintWriter(cl.getOutputStream(),true);//Khoi toi luong ghi du lieu
float c=Float.parseFloat(a)+Float.parseFloat(b);
pr.println(c);
cl.close();
}

2.Về bên Client:(Viết trên Android)
Các bạn New một project mới và tạo các file như sau:
-Khởi tạo giao diện: chúng ta thiết kế một layout bao gồm các TextView, EditText để nhập 2 số a, b và hiển thị kết quả. Ngoài ra ta thêm một nút Tinh để gửi a, b cho bên Server.
Code: main.xml

Code:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:gravity="center_horizontal"
>
<LinearLayout
android:id="@+id/linearLayout1"
android:layout_height="wrap_content"
android:layout_width="wrap_content">
<TextView
android:text="Nhap so thu 1:"
android:layout_width="100dp"
android:layout_height="wrap_content">
</TextView>
<EditText
android:hint=" a "
android:id="@+id/a"
android:layout_width="150dp"
android:layout_height="wrap_content">
</EditText>
</LinearLayout>
<LinearLayout
android:id="@+id/linearLayout2"
android:layout_height="wrap_content"
android:layout_width="wrap_content">
<TextView
android:text="Nhap so thu 2:"
android:layout_width="100dp"
android:layout_height="wrap_content">
</TextView>
<EditText
android:hint=" b "
android:id="@+id/b"
android:layout_width="150dp"
android:layout_height="wrap_content">
</EditText>
</LinearLayout>
<LinearLayout
android:id="@+id/linearLayout3"
android:layout_height="wrap_content"
android:layout_width="wrap_content">
<TextView
android:text="Ketqua: "
android:layout_width="100dp"
android:layout_height="wrap_content">
</TextView>
<EditText
android:hint=" "
android:id="@+id/kqua"
android:layout_width="150dp"
android:layout_height="wrap_content">
</EditText>
</LinearLayout>
<Button
android:text="Tinh"
android:id="@+id/tinh"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
</Button>

</LinearLayout>
 
 
-Tiếp theo, ta mở file mainActivity.java (do các bạn tự đặt tên khi tạo Project)

+Tạm thời để cái hàm onCreat sang một bên, ta xử lý sau, ta đi xây
dựng hàm kết nối, gửi nhận dữ liệu với server thông qua IP và port, hàm
này sẽ trả lại cho ta giá trị tổng của 2 số a và b ta nhập vào từ các
EditText:
public String connectSever(final String ip, final String port, final float a,final float b){
String output=null;
try {
Socket cl=new Socket(ip,Integer.parseInt(port));//ket noi server

PrintWriter pw=new PrintWriter(cl.getOutputStream(),true);//tao luong gui du lieu
pw.println(""+a);
pw.println(""+b);

BufferedReader br=new BufferedReader(new InputStreamReader(cl.getInputStream()));//tao luong nhan du lieu
output=br.readLine();
cl.close();
} catch (NumberFormatException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}


return output;//tra ve ket qua cua a+b
}
 
        +Bây giờ chúng ta chỉ phải hiển thị cái layout và xử lý sự kiện cho nút bấm trong hàm onCreat:
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);

final EditText ed1=(EditText)findViewById(R.id.a);
final EditText ed2=(EditText)findViewById(R.id.b);
final EditText ed3=(EditText)findViewById(R.id.kqua);
Button tinh=(Button)findViewById(R.id.tinh);

View.OnClickListener tinhOnClick=new OnClickListener() {

public void onClick(View v) {
// TODO Auto-generated method stub
String op=connectSever("10.0.2.2", "9999", Float.parseFloat(ed1.getText().toString()), Float.parseFloat(ed2.getText().toString()));
ed3.setText(op);
}
};
tinh.setOnClickListener(tinhOnClick);
}
 
 
 
 
 



Đọc nội dung file .txt trong sdcard [ For Newbie ]

try{ 
File f = new File(Environment.getExternalStorageDirectory()+"/test.txt");
fileIS = new FileInputStream(f);
BufferedReader buf = new BufferedReader(new InputStreamReader(fileIS));
String readString = new String();
//đọc theo từng dòng
while((readString = buf.readLine())!= null){
// hiển thị ra LOGCAT
Log.d("line: ", readString);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e){
e.printStackTrace();
}
Khi chạy bạn nhớ bật Logcat để xem kết quả. Đoạn code đặt ngay trong hàm onCreate() nhé.

[Code snippets] Download 1 HTTP file với progess notification

try {
// Khai báo url
URL url = new URL("http://somewhere.com/some/webhosted/file");

//tạo HTTP connection
HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();

//setup phương thức cho HTTP connecton
urlConnection.setRequestMethod("GET");
urlConnection.setDoOutput(true);

// kết nối
urlConnection.connect();


// khởi tạo sdcard . Lưu ý phương thức Environment.getExternalStorageDirectory(); trả lại đường dẫn đến sdcard
File SDCardRoot = Environment.getExternalStorageDirectory();
// Tạo 1 file để lưu nội dung trang web
File file = new File(SDCardRoot,"somefile.ext");

//Khai báo FileInputStream để tương tác với InputStream
FileOutputStream fileOutput = new FileOutputStream(file);

//InputStream để đọc dẽ liệu từ url
InputStream inputStream = urlConnection.getInputStream();

//lấy size của dữ liệu tải về
int totalSize = urlConnection.getContentLength();
// khai báo 1 biến để biết dữ liệu tải về ( realtime)
int downloadedSize = 0;

//tạo buffer
byte[] buffer = new byte[1024];
int bufferLength = 0; //used to store a temporary size of the buffer

//đọc dữ liệu từ buffer
while ( (bufferLength = inputStream.read(buffer)) > 0 ) {
//ghi từ buffer vào textfile ở sdcard
fileOutput.write(buffer, 0, bufferLength);
//update downloadSize
downloadedSize += bufferLength;
//dựa vào biến downloadSize để update progess
updateProgress(downloadedSize, totalSize);

}
//đóng outputstream khi hoàn thành
fileOutput.close();

} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}

[Code Snippets] Lấy thông tin về Battery

main.xml
[JAVA]
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:eek:rientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/hello"
/>

<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Battery Info."
/>
<TextView
android:id="@+id/batterylevel"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Battery Level:"
/>
<TextView
android:id="@+id/batteryvoltage"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Battery Voltage:"
/>
<TextView
android:id="@+id/batterytemperature"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Battery Temperature:"
/>
<TextView
android:id="@+id/batterytechology"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Technology:"
/>
<TextView
android:id="@+id/batterystatus"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Status:"
/>
<TextView
android:id="@+id/batteryhealth"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Health:"
/>
</LinearLayout>

[/JAVA]

Main Activity

[JAVA]
package com.exercise.AndroidBattery;

import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.BatteryManager;
import android.os.Bundle;
import android.widget.TextView;

public class AndroidBattery extends Activity {

private TextView batteryLevel, batteryVoltage, batteryTemperature,
batteryTechnology, batteryStatus, batteryHealth;


/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);

batteryLevel = (TextView)findViewById(R.id.batterylevel);
batteryVoltage = (TextView)findViewById(R.id.batteryvoltage);
batteryTemperature = (TextView)findViewById(R.id.batterytemperature);
batteryTechnology = (TextView)findViewById(R.id.batterytechology);
batteryStatus = (TextView)findViewById(R.id.batterystatus);
batteryHealth = (TextView)findViewById(R.id.batteryhealth);

this.registerReceiver(this.myBatteryReceiver,
new IntentFilter(Intent.ACTION_BATTERY_CHANGED));
}

private BroadcastReceiver myBatteryReceiver
= new BroadcastReceiver(){

@Override
public void onReceive(Context arg0, Intent arg1) {
// TODO Auto-generated method stub

if (arg1.getAction().equals(Intent.ACTION_BATTERY_CHANGED)){
batteryLevel.setText("Level: "
+ String.valueOf(arg1.getIntExtra("level", 0)) + "%");
batteryVoltage.setText("Voltage: "
+ String.valueOf((float)arg1.getIntExtra("voltage", 0)/1000) + "V");
batteryTemperature.setText("Temperature: "
+ String.valueOf((float)arg1.getIntExtra("temperature", 0)/10) + "c");
batteryTechnology.setText("Technology: " + arg1.getStringExtra("technology"));

int status = arg1.getIntExtra("status", BatteryManager.BATTERY_STATUS_UNKNOWN);
String strStatus;
if (status == BatteryManager.BATTERY_STATUS_CHARGING){
strStatus = "Charging";
} else if (status == BatteryManager.BATTERY_STATUS_DISCHARGING){
strStatus = "Dis-charging";
} else if (status == BatteryManager.BATTERY_STATUS_NOT_CHARGING){
strStatus = "Not charging";
} else if (status == BatteryManager.BATTERY_STATUS_FULL){
strStatus = "Full";
} else {
strStatus = "Unknown";
}
batteryStatus.setText("Status: " + strStatus);

int health = arg1.getIntExtra("health", BatteryManager.BATTERY_HEALTH_UNKNOWN);
String strHealth;
if (health == BatteryManager.BATTERY_HEALTH_GOOD){
strHealth = "Good";
} else if (health == BatteryManager.BATTERY_HEALTH_OVERHEAT){
strHealth = "Over Heat";
} else if (health == BatteryManager.BATTERY_HEALTH_DEAD){
strHealth = "Dead";
} else if (health == BatteryManager.BATTERY_HEALTH_OVER_VOLTAGE){
strHealth = "Over Voltage";
} else if (health == BatteryManager.BATTERY_HEALTH_UNSPECIFIED_FAILURE){
strHealth = "Unspecified Failure";
} else{
strHealth = "Unknown";
}
batteryHealth.setText("Health: " + strHealth);

}
}

};
}

[Code Snippets] Một cách kiểm tra phiên bản mới của ứng dụng

Có nhiều cách để cho người dùng kiểm tra phiên bản mới ứng dụng. Phương pháp sau đây không cần phải có server riêng để kiểm tra phiên bản mà dùng chính Android Market server (đòi hỏi ứng dụng phải có trên Market). Nguyên lý là bạn truy cập trang thông tin ứng dụng của mình để trích xuất thông tin phiên bản, sau đó so sánh với phiên bản hiện tại trong PackageInfo của ứng dụng.

Đoạn code sau đây mình lấy từ chương trình OptiNews (định danh là vn.zerox.optinews, các bạn sẽ thay bằng cái khác):


Tạo thread để check phiên bản:

Mã:
Thread thr = new LoadVersion();
thr.start();
Thread check phiên bản:
Mã:
private class LoadVersion extends Thread {
@Override
public void run() {
handler.sendEmptyMessage(0);

try {
HttpParams params = new BasicHttpParams();
HttpConnectionParams.setConnectionTimeout(params, 10000);
HttpConnectionParams.setSoTimeout(params, 10000);
HttpClient client = new DefaultHttpClient(params);
HttpGet get = new HttpGet("http://market.android.com/details?id=vn.zerox.optinews");
HttpResponse response = client.execute(get);
HttpEntity entity = response.getEntity();
html = EntityUtils.toString(entity, "utf-8");
} catch (Exception e) {
html = null;
}

handler.sendEmptyMessage(1);
}
}
Handler để hiển thị thông tin kiểm tra phiên bản:
Mã:
private Handler handler = new Handler() {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case 0:
if (oncreate) break;
pd = new ProgressDialog(MainCategory.this);
pd.setMessage("Kiểm tra cập nhật...");
pd.setCancelable(false);
Window window = pd.getWindow();
//window.setFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL,WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL);
window.clearFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND);
pd.show();
break;
case 1:
if (!oncreate) pd.dismiss();
if (html == null) {
if (!oncreate) Toast.makeText(MainCategory.this, "Lỗi truy cập thông tin !", Toast.LENGTH_SHORT).show();
} else {
int i = html.indexOf("<dt>Current Version:</dt><dd>");
int j = html.indexOf("</dd>",i+29);
if (i == -1 || j == -1) {
Toast.makeText(MainCategory.this, "Lỗi truy cập thông tin phiên bản !", Toast.LENGTH_SHORT).show();
break;
}
String ver = html.substring(i+29, j);
float nver = Float.parseFloat(ver);
String cur = "1.0";
try {
cur = getPackageManager().getPackageInfo(getPackageName(),0).versionName;
} catch (NameNotFoundException e) {}
float ncur = Float.parseFloat(cur);
String text;
if (ncur >= nver) {
if (oncreate) break;
text = "Bạn đang dùng phiên bản mới nhất !";
}
else text = "Hiện đã có phiên bản mới là " + ver + " !";
AlertDialog.Builder dialog = new AlertDialog.Builder(MainCategory.this);
dialog.setTitle("Kiểm tra cập nhật");
dialog.setMessage(text);
dialog.setNeutralButton("Đóng", null);
dialog.create().show();
}
break;
default:
super.handleMessage(msg);
}
}
};
Chú ý ở đây mình đặt tên phiên bản có dạng n.m (n,m gồm 1 chữ số). Các bạn có thể sửa code để tương thích dạng phiên bản khác như n.mm-beta ...
(Vì trên Market không hiển thị VersionCode nên mình phải dùng VersionName)

Wednesday, April 10, 2013

Android Google Map View Example Tutorial

Step 1 : Obtaining Google API Key
To make use of Google Map or any other Google API you need to have a Google API key.
It is extremely easy to get a Google API Key. You see below I have made a Video which is made up of step-by-step procedure for obtaining the Google API key.

Detailed Steps
  • Proceed to the location exactly where JDK installed.
  • Certainly, there you will see KeyTool.
  • Then simply Copy the path.
  • Start a command prompt then change the directory to the keytool path.
  • copy and paste the below code snippet to command prompt
keytool -list -alias androiddebugkey -keystore
  • At this point we need to copy the path of the debug.keystore
  • Head over to windows/users/[your computer user name]/.android/
  • It’s simple to find the debug.keystore, so copy the path.
  • Next paste the keystore path surrounded with “” combined with the step 5 code snippet.
keytool -list -alias androiddebugkey -keystore "C:.android.keystore" -storepass android -keypass android
  • Last but not least press Enter. You will notice the Certificate Finger Print.

  • At this moment visit this link to sign up to Google API.
  • Enter the Finger print using only number and digits. Stay away from including “:” .
  • After that Tick the Agreement.
  • Simply click Generate API key. You should see the API key now. Copy the actual URL intended for future reference.
Step 2 : Hands-on Google Map in Emulator
Before start to code our Google Map Alert App, we are now going to test it, to ensure we are ready to go.
  • Start a Sample Project named GoogleMapDemo.

  • Choose the Choose bulid SDK to Google API. I choosed Google API Level 16.
  • Then Click Next for the rest, Finally press Finish.

  • Copy the below code to your Layout.
res/layout/activity_main.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<com.google.android.maps.MapView
android:id="@+id/map"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:clickable="true"
android:apiKey="06Q7KxHWP0w3-i0IpzRr8sSRnDLyHWAfJ_lk8mQ" />
</RelativeLayout>

Here you should enter your apikey otherwise it won’t work.
  • Ok in case you are so curious, then simply run it. You will find the below stopped message.

Just what exactly is the mistake we certainly have done. We have setup every little thing as well as enter the MapView component within our layout.
But It is not sufficient to really make it do the job. We have seen lots of android tutorial for beginners. Therefore by now you should capable of finding out, exactly what do we have to do in order to succeed.
Absolutely yes, you are right, we should tell to the Manifest file that we are going to make use of Google Map for this application, and also Internet access.
Android Manifest.xml
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.googlemapdemo"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="7"
android:targetSdkVersion="15" />
<application
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name=".MainActivity"
android:label="@string/google_map_demo" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<uses-library android:name="com.google.android.maps"/>
</application>
<uses-permission android:name="android.permission.INTERNET"/>
</manifest>
Do you believe that this time, it’s going to run the app and show the map.
I am not going to say anything at the moment, just proceed as well as run the project.


So above is the answer. So for we have extends only Activity, but in order to make use of Google Map, Our Java Code should extends MapActivity. :)
  • Then finally include the unimplemented methods.
src/com.example.androidmapviewdemo/AndroidMapViewDemo.java
package com.example.googlemapdemo;
import com.google.android.maps.MapActivity;
import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;
import android.view.MenuItem;
import android.support.v4.app.NavUtils;
public class MainActivity extends MapActivity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.activity_main, menu);
return true;
}
@Override
protected boolean isRouteDisplayed() {
// TODO Auto-generated method stub
return false;
}
}

 
 
 
 
Download Code

Thursday, February 21, 2013

Caching website với CodeIgniter

Nội dung :
  • Tại sao cần phải caching website
  • Sự khác biệt giữa caching và không caching
  • Làm thế nào để caching trong CodeIgniter

1.Tại sao cần phải caching website: 
- Trước hết , bạn hiểu như thế nào là caching : Web caching là việc lưu trữ bản sao của những tài liệu web sao cho gần với người dùng, cả về mặt chức năng trong web client hoặc những web caching servers riêng biệt 
- Ưu điểm : 
  • Load nội dung nhanh hơn
  • Hạn chế việc truy vấn trực tiếp vào Databse


2.Sự khác biệt giữa caching và không caching 
Không sử dụng caching : 
• Kết nối MySQL Database 
• Lấy 10 item trong database 
• Sắp xếp nhửng Item theo thứ tự 
• Đọc template file cho web sau đó cho việc hiển thị 
• Trả kết quả về phía người dùng 
 

- Nếu trong 1 thời gian ngắn có 2 lượt truy cập, thì các thực thi trên không đáng để quan tâm. Nhưng nếu khoảng 500 lượt truy cập trong 1 giờ chẳng hạng thì nó vấn đề mà chúng ta cần phải quan tâm. Liệu Server của bạn có thể đảm đương 500 x (các thực thi trên) không và có thể lượt truy cập còn hơn thế nữa 
-Ở đây mình xin nói thêm "làm sao thống kê được lượt truy cập" . Các bạn có thể tìm hiểu ứng dụng miễn phí google analytics của google 

Sử dụng caching : 
Để làm giảm tải các truy vấn tới CSDL ta có thể sử dụng kĩ thuật Caching website. 
Ví dụ : 
Trong 1 ngày đó , tôi là người truy cập đầu tiên vào website :http://qhonline.info/news 
Thì webserver sẽ thực thi các bước như sau : 
• Kết nối MySQL Database 
• Lấy 10 item trong database 
• Sắp xếp nhửng Item theo thứ tự 
• Đọc template file cho web sau đó cho việc hiển thị 
• Trả kết quả về phía người dùng 

Sau đó lưu nội dung hiển thị http://qhonline.info/newsvào 1 file text đã được mã hóa trên webserver 
Kế tiếp sau tôi là các user cũng truy cập đại chỉ : http://qhonline.info/newsnhưng lần này hệ thống không truy vấn vào CSDL như các bước trên , mà nó sẽ tìm file đã được cache và đọc nó, và như thế 100 người hay 1000 người … truy cập vào http://qhonline.info/newsthì cũcng chỉ đọc nội dung file cached 
- Việc đọc nội dung 1 file text với việc truy vấn vào CSDL thì rõ ràng có sự khác biệt rất lớn về cách xử lý cũng như tốc độ load. 
Bạn có thể xem hình mô tả bên dưới 
 

3.Làm thế nào để caching trong CodeIgniter : 
- Ví dụ : tôi truy cập vào link sau : http://qhonline.info/news/bongba 
Như vậy trong ứng dụng của tôi cần có 

 class News extends Controller 

function
 __construct(){  

   parent::controller(); 
  //code here ………….   
 } 

  function
 bongda(){ //kết nối CSDL 
     //…………… 
      //loadview();

  
 

}
- Làm sao để caching website với nội dunghttp://qhonline.info/news/bongba 
- Bạn thêm hàm : 
PHP Code:
$this->output->cache($n)
dưới cùng của function bongda() với n là thời gian làm mới nội dung cache được tính bằng phút 
Xem có thể xem thêm userguide về hàm này tại :http://codeigniter.com/user_guide/general/caching.html 
Như vậy class có caching của chúng ta bây giờ là : 

PHP Code:
<?php class News extends Controller 

function
 __construct(){ parent::controller(); //code here…………


function
 bongda(){ //kết nối CSDL 
//…………… 
//loadview(); 
$this->output->cache(5) ; // thời gian làm mới là sao 5 phút nếu có lượt truy cập vào nội dung này 
}
Nếu bạn muốn caching toàn bộ cho controller news thì thêm đoạn code$this->output->cache() vào cuối của hàm : 
PHP Code:
function __construct(){..}
PHP Code:
<?php class News extends Controller 

function
 __construct(){ parent::controller(); //code here…………$this->output->cache(5) ; // thời gian làm mới là sao 5 phút nếu có lượt truy cập vào nội dung này 

function
 bongda(){ //kết nối CSDL 
//…………… 
//loadview(); 

}
Các file cache được lưu trong thư mục system/cachecủa CodeIgniter 

Ứng dụng Ajax, Json để Upload file trong CodeIgniter


Chào các bạn, hôm nay mình sẽ hướng dẫn các bạn sử dụng ajax khi chúng ta upload file trong CodeIgniter! 
Để nắm rõ dc TUT này, các bạn phải có kiến thức cơ bản về Json nha ! Tham thảo jsontại :http://www.qhonline.info/forum/showt...highlight=json. 
+++Ở đây, chúng ta sẽ nạp vào thư viện AjaxFileUpload. Các bạn có thể tải tại đây:http://www.phpletter.com/DOWNLOAD/. 

->Các bước cb đã xong !giờ chúng ta bắt tay vào viết ứng dụng nào . 

+Đầu tiên, chúng ta tạo 1 bảng cấu trúc như sau: 

Mã:


CREATE TABLE `files` (
`id` int NOT NULL AUTO_INCREMENT PRIMARY KEY,
`file_name` varchar(255) NOT NULL,
`title` varchar(100) NOT NULL
);
+Tiếp theo, chúng ta có cấu trúc thư mục code như sau: 

- application/ 
--- controllers/ 
------ upload.php 
--- models/ 
------ mupload.php 
--- views/ 
------ upload_view.php 
------ files.php 
- public/ 
--- css/ 
----- style.css 
--- js/ 
----- AjaxFileUpload.js 
----- jquery.js 
- upload/ ->thư mục chứa file chúng ta upload lên. 

->Trong controller upload.php ta xử lý như sau
PHP Code:
class Upload extends CI_Controller
public function
 __construct(){ parent::__construct(); $this->load->helper(array("url","form")); 

public function
 index(){ $this->load->view("upload_view"); 
//hàm trả về các file đã upload dc lưu trong database public function files(){ $this->load->model("mupload"); $data['files'] = $this->mupload->get_all_files(); $this->load->view("files",$data); 

//hàm xử lý việc upload file và xuất thông báo dưới dạng json public function upload_file(){ $status = ""$msg = ""$tit = $this->input->post("title"); 
if(
$tit == NULL){ $status = "error"$msg = "Please enter your title"

if(
$status != "error"){ $config['upload_path'] = '.upload'$config['allowed_types'] = 'gif|jpg|png|doc|txt'$config['max_size'] = 1024 * 8$config['encrypt_name'] = TRUE$this->load->library("upload",$config); 
if(!
$this->upload->do_upload("ufile")){ $status = "error"$msg = $this->upload->display_errors('<p>','</p>'); 
echo
 $msg
}else{ 
$this->load->model("mupload"); $data = $this->upload->data(); $info = array("file_name" => $data['file_name'], "title" => $_POST['title']); $fid = $this->mupload->insert_file($info); 
if(
$fid){ $status = "Success"$msg = "File successfully uploaded"
}else{ 
$status = "error"$msg = "File uploaded fail! PLease try again!"



Echo
 json_encode(array("status" => $status"msg" => $msg)); 

//hàm xử lý xóa file upload public function delete_files($file_id){ $this->load->model("mupload"); 
if(
$this->mupload->delete_file($file_id)){ $status = 'success'$msg = 'File successfully deleted'
}else{ 
$status = 'error'$msg> = 'Something went wrong when deleting the file, please try again'

Echo
 json_encode(array('status' => $status, 'msg' => $msg)); 




->Đây là file model của chúng ta: 
mupload.php: 
PHP Code:
classMupload extends CI_Model
protected
 $_table = "files"
public function
 __construct(){ parent::__construct(); $this->load->database(); 

public function
 insert_file($data){ $this->db->insert($this->_table,$data); 
return
 $this->db->insert_id(); 

public function
 get_all_files($file_id =""){ 
if(
$file_id != ""){ $this->db->where("id",$file_id); 

return
 $this->db->get($this->_table)->result_array(); 

public function
 delete_file($file_id){ $file = $this->get_all_files($file_id); 
if(
$file == ""){ 
return
 FALSE
}else{ 
$this->db->where("id",$file_id); $this->db->delete($this->_table); unlink("./upload/" . $file[pan style="color:rgb(0,0,187);">0
]['file_name']); //xóa file upload trong thư mục chứa return TRUE



Và cuối cùng ta có 2 trang view: 

upload_view.php: 
HTML Code:


<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<script src="<?php echo base_url();?>public/js/jquery.js"></script>
<script src="<?php echo base_url()?>public/js/ajaxfileupload.js"></script>
<link href="<?php echo base_url()?>public/css/style.css" rel="stylesheet" />
<script language="javascript">
refresh_files();//Show ra list cac file da upload

$(document).ready(function(){
//xu ly upload file
$("#submit").click(function(){
$.ajaxFileUpload({
url : "./upload/upload_file",
secureuri : false,
fileElementId : "ufile",
dataType :"json",
data : {"title" : $("#title").val() },
success : function(data, status){
if(data.status != "error"){
$("#files").html("<p>Loading....</p>");
refresh_files();
$("#title").val("");
}
alert(data.msg);
}
});
return false;
}); //ket thuc upload file

//Xu ly delete file upload
$(".delete_file_link").live("click",function(){
if(confirm("Do you want to delete this file?")){
varlink_url = $(this);
//var files = $("#files");
//alert(files);
//alert(link_url.data("file_id"));
$.ajax({
url : "./upload/delete_files/" + link_url.data("file_id"),
dataType : "json",
success : function(data){
files = $("#files");
if(data.status == "success"){
link_url.parents("li").fadeOut("fast", function(){
$(this).remove();
if(files.find('li').length == 0){
files.html('<p>No Files Uploaded</p>');
}
});
}else{
alert(data.msg);
}
}
})
}
})//ket thuc xu ly file upload

})


function refresh_files()
{
$.get('./upload/files/').success(function (data){
$('#files').html(data);
});
}
</script>
</head>
<body>
<h1>Upload File</h1>
<form method="post" action="" id="upload_file" enctype="multipart/form-data">
<label>Title</label>
<input type="text" name="title" id="title"/>

<label>File</label>
<input type="file" name="ufile" id="ufile" size="25" />

<input type="submit" name="submit" id="submit" value="Submit" />
</form>
<h2>Files</h2>
<div id="files"></div>
</body>
</html>
và files.php 
PHP Code:
<?php if(isset($files)){ 
echo
 "<ul>"
foreach(
$files as $items){ 
echo
 "<li class='image_wrap'>"
echo
 "<a href='' class='delete_file_link' data-file_id='$items[id]'>Delete</a>"
echo
 "<strong>$items[title]</strong><br />"
echo
 "<imgsrc='". base_url()."upload/$items[file_name]' width='150' />"
echo
 "</li>"

echo
 "</ul>"

else{ 
echo
 "<p>No Files Uploaded</p>"
?>
Trong đó upload _view.php sẽ là trang chúng ta dùng ajax để xử lý việc upload cũng như delete các file. Còn files.php sẽ là trang dùng để show ra các file chúng ta đã upload thành công. 
-->files.php sẽ dc gọi để hiển thị trong upload_view.php qua function refresh_filestrong đoạn javascript.