Bài 46: Sử dụng .Net Webservice trong Android


Để làm được bài 46 thì các bạn nên xem qua trước bài tập 44 và 45.

Trong bài tập 46 này Tui muốn trình bày 4 ví dụ về cách tương tác từ Android tới .net web service thông qua thư viện KSOAP API.

Các ví dụ này lần lượt sẽ là:

1) Cách lấy dữ liệu Primitive Data từ .net webservice xuống Android

2) Cách lấy dữ liệu Complex Data từ .net webservice xuống Android

3) Cách truyền Parameter primitive data từ Android tới .net web service

4) Cách truyền Object data từ Android tới .net web service

Thư viện KSOAP  API các bạn tải ở đây (tạm thời tự nghiên cứu trước): http://www.mediafire.com/download/kmznar1je4702ga/ksoap2-android-assembly-2.6.0-jar-with-dependencies.jar

Tui sẽ tranh thủ đưa 4 ví dụ trên để các bạn có thể kịp làm bài tập 43.

——————————————————————————

Tất cả 4 ví dụ này Tui sẽ sử dụng Service Description của http://testdrthanh.somee.com/mywebservice.asmx?WSDL ở bài tập trước. Khi bạn mở với Service description thì nó cung cấp cho bạn đầy đủ thông tin như hình Tui chụp dưới đây:

2h46_0

NameSpace và tên hàm là rất quan trọng để dựa vào nó ta truy xuất dữ liệu, nên sai namespace hay method thì chắc chắn không thể truy suất.

Sau đây tui hướng dẫn các bạn những ví dụ ở trên

Các bài phải :

<uses-permission android:name=”android.permission.INTERNET” />

1) Cách lấy dữ liệu Primitive Data từ .net webservice xuống Android

– Bạn tạo một Project Android giống như hình Tui chụp dưới này:

2h46_1

Bạn chú ý là Tui đánh thứ tự từ 1, 2, 3, 4 là có ý đồ kỹ thuật. Bạn phải sắp xếp như vậy thì chương trình mới sử dụng đúng thư viện và có thể truy suất webservice, nếu đặt sai có thể nó báo lỗi không thể thực thi ứng dụng.

Mặc định khi bạn tạo Project thì nó sẽ không đúng thứ tự như vậy đâu, bạn phải tự làm lại thứ tự, cách đổi thứ tự như thế nào Tui sẽ nói rõ cho bạn.

Tiếp tới là bạn phải tham chiếu tới thự Viện KSOAP API mà tui khoanh màu đỏ, bạn lưu nó ở đâu thì bạn tham chiếu tới cho đúng, hoặc bạn có thể nhét nó vào thư viện libs. (bấm chuột phải vào Project / chọn Build Path/ chọn Add External Archives –> chọn đúng thư viện KSOAP API để add vào ứng dụng)

– Cách đổi thứ tự tham chiếu như sau:

Bấm chuột phải vào Project của bạn/ chọn Build Path/Configure build path…:

2h46_2

Cửa sổ mới hiển thị lên/chọn tab Order and export:

2h46_3

Ta sắp xếp như màn hình trên, để di chuyển thì dùng các nút : Up,down, top, bottom.

Bạn chú ý là phải đảm bảo rằng tất cả các mục trong này được CHECKED rồi mới bấm nút OK.

– Sau đây là giao diện chính (rất đơn giản) của project này như sau:

2h46_4– Nút “Get Catalog count” sẽ triệu gọi Service và trả về có bao nhiêu Danh mục trong Cơ sở dữ liệu.

– Cấu trúc XML của giao diện:


<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
 xmlns:tools="http://schemas.android.com/tools"
 android:id="@+id/LinearLayout1"
 android:layout_width="match_parent"
 android:layout_height="match_parent"
 android:orientation="vertical"
 tools:context=".MainActivity" >

<TextView
 android:id="@+id/textView1"
 android:layout_width="wrap_content"
 android:layout_height="wrap_content"
 android:text="Number Of Catalog:" />

<TextView
 android:id="@+id/txtcount"
 android:layout_width="match_parent"
 android:layout_height="wrap_content"
 android:background="#008040"
 android:gravity="center"
 android:textColor="#FFFFFF"
 android:textSize="30sp" />

<Button
 android:id="@+id/btncount"
 android:layout_width="match_parent"
 android:layout_height="wrap_content"
 android:text="Get Catalog Count" />

</LinearLayout>

– Ta tiến hành xử lý coding trong MainActivity.java như sau:


package tranduythanh.com;
import org.ksoap2.SoapEnvelope;
import org.ksoap2.serialization.SoapObject;
import org.ksoap2.serialization.SoapPrimitive;
import org.ksoap2.serialization.SoapSerializationEnvelope;
import org.ksoap2.transport.HttpTransportSE;

import android.os.Bundle;
import android.os.StrictMode;
import android.app.Activity;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;

public class MainActivity extends Activity {
 TextView txtcount;
 Button btncount;
 protected void onCreate(Bundle savedInstanceState) {
 super.onCreate(savedInstanceState);
 setContentView(R.layout.activity_main);
 //thiết lập Permit để kết nối internet
 StrictMode.ThreadPolicy policy = new
 StrictMode.ThreadPolicy.Builder()
 .permitAll().build();
 StrictMode.setThreadPolicy(policy);

 txtcount=(TextView) findViewById(R.id.txtcount);
 btncount=(Button) findViewById(R.id.btncount);
 btncount.setOnClickListener(new
 View.OnClickListener() {
 public void onClick(View arg0) {
 doCount();
 }
 });
 }
 public void doCount(){
 try{
 //khai báo namespace trong Webservice
 final String NAMESPACE="http://tranduythanh.com/";
 //hàm cần truy suất
 final String METHOD_NAME="CountCatalog";
 final String SOAP_ACTION=NAMESPACE+METHOD_NAME;
 //service description
 final String URL="http://testdrthanh.somee.com/mywebservice.asmx?WSDL";
 //khai báo đối tượng SoapOBject
 SoapObject request=new SoapObject(NAMESPACE, METHOD_NAME);
 //thiết lập version
 SoapSerializationEnvelope envelope=
 new SoapSerializationEnvelope(SoapEnvelope.VER11);
 envelope.dotNet=true;
 //thiết lập output
 envelope.setOutputSoapObject(request);
 //tạo đối tượng HttpTransportSE
 HttpTransportSE androidHttpTransport=
 new HttpTransportSE(URL);
 //tiến hành triệu gọi Service
 androidHttpTransport.call(SOAP_ACTION, envelope);
 //lấy kết quả trả về SoapPrimitive, vì hàm CountCatalog chỉ trả về kiểu int (primitive data)
 SoapPrimitive response=(SoapPrimitive) envelope.getResponse();
 //hiển thị kết quả lên giao diện
 txtcount.setText(response.toString());
 }
 catch(Exception e) {
 e.printStackTrace();
 }
 }
}//end MainActivity

– Bạn quan sát dòng lệnh:


StrictMode.ThreadPolicy policy = new
 StrictMode.ThreadPolicy.Builder()
 .permitAll().build();
 StrictMode.setThreadPolicy(policy);

Dòng lệnh trên là cho phép ứng dụng kết nối tới internet, nhưng chú ý cách làm này là không TỐT, phải sửa lại. Từ Android 4.0 nó yêu cầu khi kết nối internet phải viết trong Tiểu Trình (dùng đa tiến trình, các bạn xem lại các ví dụ trước). Còn viết như bên trên TUI viết thì rất dở, nó làm Đơ Ứng Dụng vì phải mất Time Request, chỉ là giải pháp tình huống để các bạn dễ hiểu thôi.

Bạn nên xóa dòng lệnh bên trên đi, đưa hàm doCount() vào một tiểu trình (bạn dùng Handler class hoặc AsyncTask class), cách làm đa tiến trình Tui đã hướng dẫn rất kỹ lưỡng ở những bài trước, bài này các bạn tự làm (nếu không làm được thì chưa đạt).

Bạn tải source code ở đây (nhớ khi down về thì đổi lại tham chiếu tới thư viện KSOAP), bạn nên nhét nó vào thư mục Libs để chép tới nơi khác không phải tham chiếu lại:

http://www.mediafire.com/download/wo4211x3ra3x7q3/LearnWebservice_ForPrimitiveData.rar

Bạn phải chú ý làm nhiều lần để cho hiểu rõ vấn đề.

2) Cách lấy dữ liệu Complex Data từ .net webservice xuống Android

– Ở phần 1 Bạn đã biết cách truy suất webservice và trả về dữ liệu Primivite data, trong bài này Tui hướng dẫn các bạn lấy dữ liệu về dạng Complex Data.

– Cách cấu hình tham chiếu thư viện, đổi thứ tự tham chiếu … thì ở mục 1 tui đã nói, mục này Tui đi thẳng vào ứng dụng:

– Tui muốn tạo 1 Ứng dụng cho phép triệu gọi danh sách Danh Mục Sản phẩm từ webservice với giao diện vô cùng đơn giản như sau (bạn tạo ứng dụng tên là LearnWebservice_complex_data):

2h46_6– Ứng dụng trên sẽ triệu gọi hàm : getListCatalog.

– Nó khác biệt là nó trả về danh sách đối tượng Danh Mục, làm thế nào để ta lấy được danh sách đối tượng nafy???

– Sau đây là XML Layout của ứng dụng:


<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
 xmlns:tools="http://schemas.android.com/tools"
 android:id="@+id/LinearLayout1"
 android:layout_width="match_parent"
 android:layout_height="match_parent"
 android:orientation="vertical"
 tools:context=".MainActivity" >

<Button
 android:id="@+id/btnlistcatalog"
 android:layout_width="match_parent"
 android:layout_height="wrap_content"
 android:text="Get List Catalog" />

<ListView
 android:id="@+id/lvcatalog"
 android:layout_width="match_parent"
 android:layout_height="wrap_content" >
 </ListView>

</LinearLayout>

 Source code Xử lý trong MainActivity như sau:


package tranduythanh.com;

import java.util.ArrayList;

import org.ksoap2.SoapEnvelope;
import org.ksoap2.serialization.MarshalFloat;
import org.ksoap2.serialization.SoapObject;
import org.ksoap2.serialization.SoapSerializationEnvelope;
import org.ksoap2.transport.HttpTransportSE;

import android.os.Bundle;
import android.os.StrictMode;
import android.app.Activity;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ListView;

public class MainActivity extends Activity {
 Button btngetlist;
 ListView lvcatalog;
 final String URL="http://testdrthanh.somee.com/mywebservice.asmx?WSDL";
 ArrayList<String> arrCate=new ArrayList<String>();
 ArrayAdapter<String>adapter=null;
 protected void onCreate(Bundle savedInstanceState) {
 super.onCreate(savedInstanceState);
 setContentView(R.layout.activity_main);
 StrictMode.ThreadPolicy policy = new
 StrictMode.ThreadPolicy.Builder()
 .permitAll().build();
 StrictMode.setThreadPolicy(policy);
 lvcatalog=(ListView) findViewById(R.id.lvcatalog);
 btngetlist=(Button) findViewById(R.id.btnlistcatalog);
 btngetlist.setOnClickListener(new View.OnClickListener() {
 public void onClick(View arg0)
 {doGetList();}
 });
 adapter=new ArrayAdapter<String>
 (this, android.R.layout.simple_list_item_1, arrCate);
 lvcatalog.setAdapter(adapter);
 }
 public void doGetList() {
 try{final String NAMESPACE="http://tranduythanh.com/";
 final String METHOD_NAME="getListCatalog";
 final String SOAP_ACTION=NAMESPACE+METHOD_NAME;
 SoapObject request=new SoapObject(NAMESPACE, METHOD_NAME);
 SoapSerializationEnvelope envelope=
 new SoapSerializationEnvelope(SoapEnvelope.VER11);
 envelope.dotNet=true;
 envelope.setOutputSoapObject(request);
 //Nếu truyền số thực trên mạng bắt buộc phải đăng ký MarshalFloat
 //không có nó thì bị báo lỗi
 MarshalFloat marshal=new MarshalFloat();
 marshal.register(envelope);

 HttpTransportSE androidHttpTransport=
 new HttpTransportSE(URL);
 androidHttpTransport.call(SOAP_ACTION, envelope);
 //Get Array Catalog into soapArray
 SoapObject soapArray=(SoapObject) envelope.getResponse();
 arrCate.clear();
 //soapArray.getPropertyCount() return number of
 //element in soapArray
 //vòng lặp duyệt qua từng dòng dữ liệu
 for(int i=0; i<soapArray.getPropertyCount(); i++)
 {
 //(SoapObject) soapArray.getProperty(i) get item at position i
 SoapObject soapItem =(SoapObject) soapArray.getProperty(i);
 //soapItem.getProperty("CateId") get value of CateId property
 //phải mapp đúng tên cột:
 String cateId=soapItem.getProperty("CateId").toString();
 String cateName=soapItem.getProperty("CateName").toString();
 //đẩy vào array
 arrCate.add(cateId+" - "+cateName);
 }
 //xác nhận cập nhật giao diện
 adapter.notifyDataSetChanged();
 }
 catch(Exception e){}}
}

Như vậy bạn chú ý có sự khác biệt trong Vòng lặp duyệt để lấy thông tin từng dòng đối tượng, bạn chú ý ngẫm nghĩ để tự áp dụng cho các bài toán khác (lấy danh sách sản phẩm, lấy danh sách sản phẩm theo danh mục ….)

Bạn tải source code mẫu ở đây: http://www.mediafire.com/download/r2i7sayask0m9xl/LearnWebservice_complex_data.rar

Chú ý phải làm lại nhiều lần, nhất là Tui đảm bảo các bạn còn Quáng Gà với vòng lặp lấy dữ liệu ở trên.

3) Cách truyền Parameter primitive data từ Android tới .net web service

– Hai phần trên các bạn đã biết cách lấy dữ liệu primitive data và complex data từ Server về client, phần 3 này các bạn sẽ được học cách thức truyền dữ liệu từ client lên server thông qua Webservice như thế nào.

– Giao diện của bài tập 3 như sau:

2h46_7

– Mô tả sương sương như sau: Màn hình chính cho phép hiển thị danh mục, mỗi lần nhấn vào danh mục nào đó thì hiển thị danh sách sản phẩm của danh mục này. Ở đây ta dùng hàm getListProductByCatalogId của webservice để hiển thị danh sách sản phẩm theo danh mục.

-Bạn tạo Project như dưới đây:

2h46_8

– Vậy chương trình có 2 Activity, một số class: Product, Cate…

– Layout “activity_main.xml”:


<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
 xmlns:tools="http://schemas.android.com/tools"
 android:id="@+id/LinearLayout1"
 android:layout_width="match_parent"
 android:layout_height="match_parent"
 android:orientation="vertical"
 tools:context=".MainActivity" >

<Button
 android:id="@+id/btnlistcatalog"
 android:layout_width="match_parent"
 android:layout_height="wrap_content"
 android:text="Get List Catalog" />

<ListView
 android:id="@+id/lvcatalog"
 android:layout_width="match_parent"
 android:layout_height="wrap_content" >
 </ListView>

</LinearLayout>

– Layout “activity_list_product_by_catalog.xml”:


<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
 xmlns:tools="http://schemas.android.com/tools"
 android:id="@+id/LinearLayout1"
 android:layout_width="match_parent"
 android:layout_height="match_parent"
 android:orientation="vertical"
 tools:context=".ListProductByCatalogActivity" >
 <ListView
 android:id="@+id/lvproduct"
 android:layout_width="match_parent"
 android:layout_height="wrap_content" >
 </ListView>

</LinearLayout>

– Lớp Product:


package tranduythanh.com;

public class Product {
 private String productId;
 private String productName;
 private int quantity;
 private double unitPrice;
 private double totalMoney;
 public String getProductId() {
 return productId;
 }
 public void setProductId(String productId) {
 this.productId = productId;
 }
 public String getProductName() {
 return productName;
 }
 public void setProductName(String productName) {
 this.productName = productName;
 }
 public int getQuantity() {
 return quantity;
 }
 public void setQuantity(int quantity) {
 this.quantity = quantity;
 }
 public double getUnitPrice() {
 return unitPrice;
 }
 public void setUnitPrice(double unitPrice) {
 this.unitPrice = unitPrice;
 }
 public double getTotalMoney() {
 return totalMoney;
 }
 public void setTotalMoney(double totalMoney) {
 this.totalMoney = totalMoney;
 }
 public Product(String productId, String productName, int quantity,
 double unitPrice, double totalMoney) {
 super();
 this.productId = productId;
 this.productName = productName;
 this.quantity = quantity;
 this.unitPrice = unitPrice;
 this.totalMoney = totalMoney;
 }
 @Override
 public String toString() {
 return this.productName+"-"+(this.totalMoney);
 }

}

– Lớp Cate:


package tranduythanh.com;

public class Cate {
 private String cateId;
 private String cateName;
 public String getCateId() {
 return cateId;
 }
 public void setCateId(String cateId) {
 this.cateId = cateId;
 }
 public String getCateName() {
 return cateName;
 }
 public void setCateName(String cateName) {
 this.cateName = cateName;
 }
 public Cate(String cateId, String cateName) {
 super();
 this.cateId = cateId;
 this.cateName = cateName;
 }
 @Override
 public String toString() {
 return this.cateId.trim()+" - "+this.cateName.trim();
 }

}

– Lớp MainActivity:


package tranduythanh.com;

import java.util.ArrayList;

import org.ksoap2.SoapEnvelope;
import org.ksoap2.serialization.MarshalFloat;
import org.ksoap2.serialization.SoapObject;
import org.ksoap2.serialization.SoapSerializationEnvelope;
import org.ksoap2.transport.HttpTransportSE;

import android.os.Bundle;
import android.os.StrictMode;
import android.app.Activity;
import android.content.Intent;
import android.view.View;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ListView;
import android.widget.Toast;

public class MainActivity extends Activity {
 Button btngetlist;
 ListView lvcatalog;
 final String URL="http://testdrthanh.somee.com/mywebservice.asmx?WSDL";
 ArrayList<Cate> arrCate=new ArrayList<Cate>();
 ArrayAdapter<Cate>adapter=null;
 protected void onCreate(Bundle savedInstanceState) {
 super.onCreate(savedInstanceState);
 setContentView(R.layout.activity_main);
 StrictMode.ThreadPolicy policy = new
 StrictMode.ThreadPolicy.Builder()
 .permitAll().build();
 StrictMode.setThreadPolicy(policy);
 lvcatalog=(ListView) findViewById(R.id.lvcatalog);
 btngetlist=(Button) findViewById(R.id.btnlistcatalog);
 btngetlist.setOnClickListener(new View.OnClickListener() {
 public void onClick(View arg0)
 {doGetList();}
 });
 adapter=new ArrayAdapter<Cate>
 (this, android.R.layout.simple_list_item_1, arrCate);
 lvcatalog.setAdapter(adapter);

 lvcatalog.setOnItemClickListener(new OnItemClickListener() {
 @Override
 public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,
 long arg3) {
 //xử lý hiển thị danh sách sản phẩm theo danh mục
 Cate c=arrCate.get(arg2);
 Intent in=new Intent(MainActivity.this, ListProductByCatalogActivity.class);
 in.putExtra("cateid", c.getCateId());
 startActivity(in);
 }
 });
 }

 public void doGetList() {
 try{final String NAMESPACE="http://tranduythanh.com/";
 final String METHOD_NAME="getListCatalog";
 final String SOAP_ACTION=NAMESPACE+METHOD_NAME;
 SoapObject request=new SoapObject(NAMESPACE, METHOD_NAME);
 SoapSerializationEnvelope envelope=
 new SoapSerializationEnvelope(SoapEnvelope.VER11);
 envelope.dotNet=true;
 envelope.setOutputSoapObject(request);
 //Nếu truyền số thực trên mạng bắt buộc phải đăng ký MarshalFloat
 //không có nó thì bị báo lỗi
 MarshalFloat marshal=new MarshalFloat();
 marshal.register(envelope);

 HttpTransportSE androidHttpTransport=
 new HttpTransportSE(URL);
 androidHttpTransport.call(SOAP_ACTION, envelope);
 //Get Array Catalog into soapArray
 SoapObject soapArray=(SoapObject) envelope.getResponse();
 arrCate.clear();
 //soapArray.getPropertyCount() return number of
 //element in soapArray
 //vòng lặp duyệt qua từng dòng dữ liệu
 for(int i=0; i<soapArray.getPropertyCount(); i++)
 {
 //(SoapObject) soapArray.getProperty(i) get item at position i
 SoapObject soapItem =(SoapObject) soapArray.getProperty(i);
 //soapItem.getProperty("CateId") get value of CateId property
 //phải mapp đúng tên cột:
 String cateId=soapItem.getProperty("CateId").toString();
 String cateName=soapItem.getProperty("CateName").toString();
 //đẩy vào array
 Cate c=new Cate(cateId, cateName);
 arrCate.add(c);
 }
 //xác nhận cập nhật giao diện
 adapter.notifyDataSetChanged();
 }
 catch(Exception e)
 {
Toast.makeText(this, e.getMessage(), Toast.LENGTH_LONG).show();
 }
 }
}

– Lớp ListProductByCatalogActivity:


package tranduythanh.com;

import java.util.ArrayList;

import org.ksoap2.SoapEnvelope;
import org.ksoap2.serialization.MarshalFloat;
import org.ksoap2.serialization.SoapObject;
import org.ksoap2.serialization.SoapSerializationEnvelope;
import org.ksoap2.transport.HttpTransportSE;

import android.os.Bundle;
import android.os.StrictMode;
import android.app.Activity;
import android.content.Intent;
import android.view.Menu;
import android.widget.ArrayAdapter;
import android.widget.ListView;

public class ListProductByCatalogActivity extends Activity {
 ListView lvproduct;
 final String URL="http://testdrthanh.somee.com/mywebservice.asmx?WSDL";
 ArrayList<Product> arrProduct=new ArrayList<Product>();
 ArrayAdapter<Product>adapter=null;
 String cateId="";
 @Override
 protected void onCreate(Bundle savedInstanceState) {
 super.onCreate(savedInstanceState);
 setContentView(R.layout.activity_list_product_by_catalog);

StrictMode.ThreadPolicy policy = new
 StrictMode.ThreadPolicy.Builder()
 .permitAll().build();
 StrictMode.setThreadPolicy(policy);
 lvproduct=(ListView) findViewById(R.id.lvproduct);

adapter=new ArrayAdapter<Product>
 (this, android.R.layout.simple_list_item_1, arrProduct);
 lvproduct.setAdapter(adapter);

 Intent in=getIntent();
 cateId= in.getStringExtra("cateid");
 }
 @Override
 protected void onResume() {
 // TODO Auto-generated method stub
 super.onResume();
 doGetListProduct();
 }
 public void doGetListProduct()
 {
 try{
 final String NAMESPACE="http://tranduythanh.com/";
 final String METHOD_NAME="getListProductByCatalogId";
 final String SOAP_ACTION=NAMESPACE+METHOD_NAME;
 SoapObject request=new SoapObject(NAMESPACE, METHOD_NAME);
 request.addProperty("id", cateId);
 SoapSerializationEnvelope envelope=
 new SoapSerializationEnvelope(SoapEnvelope.VER11);
 envelope.dotNet=true;
 envelope.setOutputSoapObject(request);
 MarshalFloat marshal=new MarshalFloat();
 marshal.register(envelope);
 HttpTransportSE androidHttpTransport=
 new HttpTransportSE(URL);
 androidHttpTransport.call(SOAP_ACTION, envelope);

 //Get Array Catalog into soapArray
 SoapObject soapArray=(SoapObject) envelope.getResponse();
 arrProduct.clear();
 //soapArray.getPropertyCount() return number of
 //element in soapArray
 //vòng lặp duyệt qua từng dòng dữ liệu
 for(int i=0; i<soapArray.getPropertyCount(); i++)
 {
 //(SoapObject) soapArray.getProperty(i) get item at position i
 SoapObject soapItem =(SoapObject) soapArray.getProperty(i);
 //phải mapp đúng tên cột:
 String productId=soapItem.getProperty("ProductId").toString();
 String productName=soapItem.getProperty("ProductName").toString();
 String squantity=soapItem.getProperty("Quantity").toString();
 String sunitPrice=soapItem.getProperty("UnitPrice").toString();
 String stotalMoney=soapItem.getProperty("TotalMoney").toString();
 int quantity=Integer.parseInt(squantity);
 double unitPrice=Double.parseDouble(sunitPrice);
 double totalMoney=Double.parseDouble(stotalMoney);
 //đẩy vào array
 Product p=new Product(productId, productName, quantity, unitPrice, totalMoney);
 arrProduct.add(p);
 }
 //xác nhận cập nhật giao diện
 adapter.notifyDataSetChanged();
 }
 catch(Exception e) {}
 }
 @Override
 public boolean onCreateOptionsMenu(Menu menu) {
 // Inflate the menu; this adds items to the action bar if it is present.
 getMenuInflater().inflate(R.menu.list_product_by_catalog, menu);
 return true;
 }

}

– Quan sát dòng 55-56 đó là cách truyền Primivte data từ Android lên Webservice.

– Ta nên để trong OnReSume để đảm bảo rằng mọi thứ được sẵn sàng. Trong này sẽ lọc toàn bộ sản phẩm theo danh mục.

– Source code phần 3 ở đây: http://www.mediafire.com/download/3qyns57lzd2jjss/LearnWebservice_AddParameter_Primitive.rar

Các bạn chú ý phải làm lại nhiều lần bài 3 này vì nó khó và hay!

4) Cách truyền Object data từ Android tới .net web service

– Đây là phần cuối cùng Tui muốn hướng dẫn các bạn cách truyền Object Data từ Client Android lên Server thông qua Webservice.

– Ở bài tập 4 này bạn bổ sung thêm 1 hàm InsertCatalog vào Webservice, với đối số truyền vào là đối tượng Catalog:


//10 - thêm 1 catalog vào CSDL
 [WebMethod]
 public int insertCatalog(Catalog cate)
 {
 try
 {
 cate.Products.Clear();
 db.Catalogs.InsertOnSubmit(cate);
 db.SubmitChanges();
 }
 catch
 {
 return -1;
 }
 return 1;
 }

– Tui có giao diện đơn giản để demo cho phần này như sau:

2h46_9

– Khi nhấn nút “Show List Catalog”: Chương trình sẽ triệu gọi Webservice để hiển thị danh mục sản phẩm vào ListView bên dưới.

– Khi nhấn nút “Insert Cate”: Chương trình sẽ truyền đối tượng Catalog từ client lên Server thông qua Webservice. Ở đây Tui dùng cách truyền Properties cho tiện. Bạn chú ý phải quan sát kỹ Service Description của nó để truyền cho đúng Parameter:

2h46_9 2h46_10

– Tương tự như cho các hàm mà có truyền tham số khác cũng vậy, phải đặt đúng tên trong Service Descripton.

– Ta có XML Layout của ứng dụng như sau:


<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
 xmlns:tools="http://schemas.android.com/tools"
 android:id="@+id/LinearLayout1"
 android:layout_width="match_parent"
 android:layout_height="match_parent"
 android:orientation="vertical"
 tools:context=".MainActivity" >

<TextView
 android:id="@+id/textView2"
 android:layout_width="match_parent"
 android:layout_height="wrap_content"
 android:background="#FFFF80"
 android:text="Input Catalog:"
 android:textSize="20sp" />

<TableLayout
 android:layout_width="match_parent"
 android:layout_height="wrap_content" >

<TableRow
 android:id="@+id/tableRow1"
 android:layout_width="wrap_content"
 android:layout_height="wrap_content" >

<TextView
 android:id="@+id/textView1"
 android:layout_width="wrap_content"
 android:layout_height="wrap_content"
 android:background="#F0E7B3"
 android:text="Cate Id:" />

<EditText
 android:id="@+id/editcateid"
 android:layout_width="wrap_content"
 android:layout_height="wrap_content"
 android:ems="10"
 android:inputType="text" >

<requestFocus />
 </EditText>
 </TableRow>

<TableRow
 android:id="@+id/tableRow2"
 android:layout_width="wrap_content"
 android:layout_height="wrap_content" >

<TextView
 android:id="@+id/textView2"
 android:layout_width="wrap_content"
 android:layout_height="wrap_content"
 android:background="#F0E7B3"
 android:text="Cate Name:" />

<EditText
 android:id="@+id/editcatename"
 android:layout_width="wrap_content"
 android:layout_height="wrap_content"
 android:ems="10"
 android:inputType="text" />
 </TableRow>

<TableRow
 android:id="@+id/tableRow4"
 android:layout_width="wrap_content"
 android:layout_height="wrap_content" >

<Button
 android:id="@+id/btninsertcate"
 android:layout_width="wrap_content"
 android:layout_height="wrap_content"
 android:layout_column="1"
 android:text="Insert Cate" />
 </TableRow>
 </TableLayout>

<TextView
 android:id="@+id/textView3"
 android:layout_width="match_parent"
 android:layout_height="wrap_content"
 android:background="#FF80FF"
 android:text="Show List Catalog" />

<Button
 android:id="@+id/btnshowlist"
 android:layout_width="match_parent"
 android:layout_height="wrap_content"
 android:text="Show List Catalog" />

<ListView
 android:id="@+id/lvcatalog"
 android:layout_width="match_parent"
 android:layout_height="fill_parent" >
 </ListView>

</LinearLayout>

– Xử lý coding cho MainActivity như sau:


package tranduythanh.com;

import java.util.ArrayList;

import org.ksoap2.SoapEnvelope;
import org.ksoap2.serialization.MarshalFloat;
import org.ksoap2.serialization.SoapObject;
import org.ksoap2.serialization.SoapPrimitive;
import org.ksoap2.serialization.SoapSerializationEnvelope;
import org.ksoap2.transport.HttpTransportSE;

import android.os.Bundle;
import android.os.StrictMode;
import android.renderscript.Mesh.Primitive;
import android.app.Activity;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.Toast;

public class MainActivity extends Activity
 implements OnClickListener{
 EditText txtcateid,txtcatename;
 Button btninsertcate,btnlistcate;
 ListView lvlistcatalog;
 final String NAMESPACE="http://tranduythanh.com/";
 final String URL="http://testdrthanh.somee.com/mywebservice.asmx?WSDL";
 ArrayList<String> arrCate=new ArrayList<String>();
 ArrayAdapter<String>adapter=null;
 @Override
 protected void onCreate(Bundle savedInstanceState) {
 super.onCreate(savedInstanceState);
 setContentView(R.layout.activity_main);

StrictMode.ThreadPolicy policy = new
 StrictMode.ThreadPolicy.Builder()
 .permitAll().build();
 StrictMode.setThreadPolicy(policy);

txtcateid=(EditText) findViewById(R.id.editcateid);
 txtcatename=(EditText) findViewById(R.id.editcatename);
 btninsertcate=(Button) findViewById(R.id.btninsertcate);
 btnlistcate=(Button) findViewById(R.id.btnshowlist);
 btninsertcate.setOnClickListener(this);
 btnlistcate.setOnClickListener(this);
 lvlistcatalog=(ListView) findViewById(R.id.lvcatalog);

adapter=new ArrayAdapter<String>
 (this, android.R.layout.simple_list_item_1, arrCate);
 lvlistcatalog.setAdapter(adapter);
 }

@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;
 }

@Override
 public void onClick(View v) {
 if(v==btnlistcate)
 {
 showlistcate();
 }
 else if(v==btninsertcate)
 {
 insertcate1();
 }
 }
 public void insertcate1()
 {
 try
 {
 final String METHOD_NAME="insertCatalog";
 final String SOAP_ACTION=NAMESPACE+METHOD_NAME;

 SoapObject request=new SoapObject
 (NAMESPACE, METHOD_NAME);
 //tạo đối tượng SoapObject với tên cate như parameter trong service description
 SoapObject newCate=new
 SoapObject(NAMESPACE, "cate");
 //truyền giá trị cho các đối số (properties) như service desctiption
 newCate.addProperty("CateId",
 txtcateid.getText()+"");

 newCate.addProperty("CateName",
 txtcatename.getText()+"");
 request.addSoapObject(newCate);

 SoapSerializationEnvelope envelope=
 new SoapSerializationEnvelope(SoapEnvelope.VER11);
 envelope.dotNet=true;
 envelope.setOutputSoapObject(request);

 HttpTransportSE androidHttpTransport=
 new HttpTransportSE(URL);
 androidHttpTransport.call(SOAP_ACTION, envelope);
 //vì hàm insertCatalog trả về kiểu int
 SoapPrimitive soapPrimitive= (SoapPrimitive)
 envelope.getResponse();
 //chuyển về int để kiểm tra insert thành công hay thất bại
 int ret=Integer.parseInt(soapPrimitive.toString());

 String msg="Insert Cate Successful";
 if(ret<=0)
 msg="Insert Cate Failed";
 Toast.makeText(this, msg, Toast.LENGTH_LONG).show();
 }
 catch(Exception e)
 {

}
 }//end insert cate
 public void showlistcate() {
 try
 {
 final String METHOD_NAME="getListCatalog";
 final String SOAP_ACTION=NAMESPACE+METHOD_NAME;
 SoapObject request=new SoapObject(NAMESPACE, METHOD_NAME);
 SoapSerializationEnvelope envelope=
 new SoapSerializationEnvelope(SoapEnvelope.VER11);
 envelope.dotNet=true;
 envelope.setOutputSoapObject(request);
 MarshalFloat marshal=new MarshalFloat();
 marshal.register(envelope);
 HttpTransportSE androidHttpTransport=
 new HttpTransportSE(URL);
 androidHttpTransport.call(SOAP_ACTION, envelope);
 //Get Array Catalog into soapArray
 SoapObject soapArray=(SoapObject) envelope.getResponse();
 arrCate.clear();
 //soapArray.getPropertyCount() return number of
 //element in soapArray
 for(int i=0; i<soapArray.getPropertyCount(); i++)
 {
 //(SoapObject) soapArray.getProperty(i) get item at position i
 SoapObject soapItem =(SoapObject) soapArray.getProperty(i);
 //soapItem.getProperty("CateId") get value of CateId property
 String cateId=soapItem.getProperty("CateId").toString();
 String cateName=soapItem.getProperty("CateName").toString();
 arrCate.add(cateId+" - "+cateName);
 }
 arrCate.add(soapArray.getPropertyCount()+" -- cate");
 adapter.notifyDataSetChanged();
 }
 catch(Exception e)
 {

}
 }
}

– Bạn có thể tải source code mẫu ở đây: http://www.mediafire.com/download/pvp59a21hc5fjhn/LearnWebservice_AddParameter_ObjectData.rar

– Như vậy Tui đã hướng dẫn đầy đủ 4 trường hợp thường gặp phải khi các bạn lập trình Android với .Net Webservice. Các bạn cần chú tâm nghiên cứu, ngoài ra cần tự học thêm JSON (JavaScript Object Notation) cho đủ bộ.

– Chúc các bạn thành công!

43 responses

  1. chờ ví dụ mãi từ chiều T__T

    1. Thầy ơi thầy có thể hướng dẫn một bài nho nhỏ cách gọi Web service .net mà trả về Json được không thầy hoặc thầy làm một cái demo cũng được em cám ơn thầy

  2. […] SMS cho các Trường Đại Học) Tui đã cung cấp hàng loạt các bài 40, 41, 44, 45, 46, 47 các bạn cần đọc kỹ lại những bài tập này trước khi bắt tay vào làm […]

  3. mình bị lỗi đoạn SoapObject soapItem =(SoapObject) soapArray.getProperty(i);
    “org.ksoap2.serialization.SoapPrimitive cannot be cast to org.ksoap2.serialization.SoapObject”

    thử thay = SoapObject soapItem = (SoapObject)envelope.bodyIn; thì hết lỗi nhưng dữ liệu trả về null

    1. à dc rùi :3

    2. thầy ợ cho em hỏi em phải add ksoap vào dự án như thế nào, có bạn nào biets bảo mình với

  4. thầy có thể hướng dẫn cách search thông tin bằng cách truyền số liệu lên service,so sánh, sau đó lấy dữ liệu về android được không !

  5. Khi em thao tác với CSDL có nhiều trường hơn, thì nó bị lỗi này, : Grow heap (frag case) to ..mb for …byte allocation.
    thầy có thể khắc phục giúp em với,tks thầy!

  6. thầy cho em hỏi, sao em dung mấy cau này lại bị lỗi vậy ạh

    String quant=item.getProperty(“Quanlity”).toString();
    String unitprice=item.getProperty(“Unitprice”).toString();
    String totalmoney= item.getProperty(“totalmoney”).toString();

    1. nhầm, lỗi chỗ get cateID la khoa ngoai trong product
      String cateid=item.getProperty(“CateID”).toString();
      toàn chạy không được

  7. Nguyen Anh Minh | Reply

    Cam on thay da huong dan tan tinh

  8. cho e hỏi là: trong ví dụ trên có truyền object lên webservice, vậy có cách nào truyền 1 list của 1 object lên trong 1 lần gọi service không?

  9. ở ví dụ 3, code thầy đưa hình như có vấn đề, sao khi click vào item trong catalog, nó không trả về được list product??

    1. mình cũng bị y chang

    2. Phải đăng ký các Activity trong Manifest

  10. Lê Quốc Ân | Reply

    Thầy ơi cho em hỏi là em lấy ví dụ của thầy về em chạy thử chỉ chạy được activity đầu. còn khi em nhấn nút thì báo như hình. em không biết có phải chưa viết Thread mà nó bị lỗi không? thầy cho em ý kiến với.[URL=http://up.ssc.vn/view.php?filename=910Untitled.png][img]http://up.ssc.vn/images/910Untitled_tn.jpg[/img][/URL]

  11. thầy ơi có em muốn đưa a lên webservice mà không biết cách nào cho lên được . thầy và các bạn biết cách chirh giúp với

  12. thầy ơi. cho e hỏi .e đọc đi đọc lại nhưng vẫn không thể làm được đăng ký học phần cho trường. mấy bài gần đây thầy đưa, e đọc đi đọc lại thì thấy đây là tạo 1 csdl riêng không liên quan gì đến csdl của trường cả. thầy giải thích rõ hơn được không ạ.

  13. thầy ơi cho em hỏi em phải add ksoap vào dự án như thế nào, có bạn nào biết bảo mình với

  14. Thầy cho em hỏi, trường hợp database quá lớn, load về như vậy thì bộ nhớ trên thiết bị không đủ. Vậy làm thế nào để tối ưu việc load dữ liệu lớn ạ? Em cám ơn

  15. thầy và các bạn cho mình hỏi với, ảnh được lưu trong web sevice thì ứng dụng adroid lấy anh xuống như thế nào\

  16. bạn nào có thể giúp mình cách delete, Update dữ liệu trên Webservicce từ Android như thế nào (ý mình là Code trong Android)
    ở vd trên đã chỉ rõ cách lấy dữ liệu xuống và insert lên CSDL trên WebService

  17. Cảm ơn thầy DrThanh nhiều !!!

  18. […] cho các Trường Đại Học) Tui đã cung cấp hàng loạt các bài 40, 41, 44, 45, 46, 47 các bạn cần đọc kỹ lại những bài tập này trước khi bắt tay vào làm […]

  19. chào thầy hiện em dang theo dõi các bài về lập trình android trên web của thầy em thấy hiện nay để hiển thị layout mới chúng ta có thể dùng fragment nó sẽ giúp họat động nhanh và đỡ tốn tài nguyên hơn em cũng đang tìm hiểu nhưng chưa được nhiểu cho lắm. Thầy có thể bổ sung thêm phần này trên androi được không

  20. Lượng Đức Tín | Reply

    Thầy ơi,bài của thầy hay lắm,thầy có thể nào thêm chức năng xóa và sửa cho em tham khảo được không thầy,em đã thử làm rồi,mà mãi không xong

  21. […] CSDL tạo ở trên (bạn nào không rõ thì xem lại các bài trước (bài 43, 44, 45, 46), Tui không muốn nói lại vì mất thời gian), sau khi cấu hình và kéo thả xong ta […]

  22. Em cảm ơn thầy rất nhiều, thầy cố gắng tiếp tục viết các bài giảng android nâng cao nữa thầy nhé !

  23. Dịch vụ thẻ mua thẻ online , thẻ game , thẻ điện thoại – Bắn tiền nạp tiền điện thoại game auto 24/7 với giá cực tốt tại hệ thống http://muathe365.com/
    Cam kết giao dịch hoàn toàn tự động nhanh gọn trong 30s –>

  24. Thầy và các bạn cho mình hỏi, mình thực hiện việc deleteCatalog, xóa được nhưng lại bị crash app. mong mọi người giúp đỡ

    ———————————————————
    public int doDelete(String id) {

    final String METHOD_NAME=”deleteCatalog”;
    final String SOAP_ACTION=NAMESPACE+METHOD_NAME;

    SoapObject request = new SoapObject(NAMESPACE, METHOD_NAME);
    SoapObject newCate = new SoapObject(NAMESPACE, “id”);
    newCate.addProperty(“CateId”, id + “”);
    request.addSoapObject(newCate);
    SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapSerializationEnvelope.VER11);
    envelope.dotNet = true;
    envelope.setOutputSoapObject(request);

    HttpTransportSE port = new HttpTransportSE(URL);
    try {
    port.call(SOAP_ACTION, envelope);

    SoapPrimitive soap = (SoapPrimitive)envelope.getResponse();
    int result = Integer.parseInt(soap.toString());
    return result;
    } catch (IOException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    return 0;
    } catch (XmlPullParserException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    return 0;
    }

  25. […] CSDL tạo ở trên (bạn nào không rõ thì xem lại các bài trước (bài 43,44, 45, 46), Tui không muốn nói lại vì mất thời gian), sau khi cấu hình và kéo thả xong ta […]

  26. Các file hình không xem được rồi thầy ơi!

  27. tại sao lại không dùng webservice viet bàng java mà lại sủ dụng >net?

    1. Em có thể dùng bất kỳ ngôn ngữ có hỗ trợ phía Server bất kỳ để viết Webservice.

  28. Thầy có cách nào dùng anroid làm webservice giống như ứng dụng SHAREIT không Thầy. Nếu Thầy có thời gian làm thêm cái đó đi Thầy.

    Cảm ơn Thầy

  29. Thầy cho em hỏi, em code trên Android Studio thì khi add thư viện Ksoap vào có phải thay đổi thứ tự tham chiếu gì không ạ?

    1. Không cần em, chỉ cần add vào là chạy

  30. Thầy ơi sao em lấy code phần 2: Cách lấy dữ liệu Complex Data từ .net webservice xuống Android.Nhưng chạy bấm vào button không hiện kết quả.Bài em viết bằng webservice của em cũng vậy.

  31. Đình Thái Nguyễn | Reply

    Hàm insertCatalog luôn trả về -1 nhưng vẫn insert thành công là sao vậy ạ.

    1. Chắc là sai chỗ nào đó á Em. check bên Server xem Em, coi chừng sai.

  32. […] (bạn nào không rõ thì xem lại các bài trước (bài 43, 44, 45, 46), Tui không muốn nói lại vì mất thời gian), sau khi cấu hình và kéo thả xong ta […]

  33. […] CSDL tạo ở trên (bạn nào không rõ thì xem lại các bài trước (bài 43, 44, 45, 46), Tôi không muốn nói lại vì mất thời gian), sau khi cấu hình và kéo thả xong ta […]

Leave a comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.