分类: 软件开发 |
Source code:
a. Web API: https://github.com/tonglanli/WebAPIForAndroidSample/ (Open with visual studio 2013)
b. Android Calling Web API: https://github.com/tonglanli/AndroidCallingWebApiSample (Open with Eclipse ADT)
Summary:
1. Publish Web API in your local (the project use VS2013)
2. Change the web API Url of the Android Calling Web API Project to your local address:
Be attention, the localhost should be set as 10.0.2.2.
public class ServiceUrl { public static final String REST_SERVICE_URL = "http://10.0.2.2:10081/api/"; public static final String PRODUCT = REST_SERVICE_URL + "products"; } |
External JARs:
Gson (https://code.google.com/p/google-gson/) can convert Json string to Class object automatically.
new GsonBuilder().create().fromJson(resultString, objectClass); |
WebAPI JSon data:
http://localhost:10081/api/products
[{"Id":1,"Name":"Tomato Soup","Category":"Groceries","Price":1.0},{"Id":2,"Name":"Yo-yo","Category":"Toys","Price":3.75},{"Id":3,"Name":"Hammer","Category":"Hardware","Price":16.99}]
Android window:
Reference:
How to call .NET Web Api from Android App:
http://www.youtube.com/watch?v=aQ8Mu7-s_Xk
How to call ASP.Net Web API service from Android?:
http://hintdesk.com/how-to-call-asp-net-web-api-service-from-android/
Getting Started with ASP.NET Web API 2 (C#):
http://www.asp.net/web-api/overview/getting-started-with-aspnet-web-api/tutorial-your-first-web-api
Steps:
Create Web API:
1. Set config to use Jason:
a. Global.asax.cs:
protected void Application_Start() { GlobalConfiguration.Configure(WebApiConfig.Register); ConfigureApi(GlobalConfiguration.Configuration); }
void ConfigureApi(HttpConfiguration config) { // Remove the JSON formatter //config.Formatters.Remove(config.Formatters.JsonFormatter);
// or
// Remove the XML formatter config.Formatters.Remove(config.Formatters.XmlFormatter); } |
The Setup Steps for Android calling Web Api (JSon):
1. Create an Android Application.
2. Add ListView to layout view.
|
3. Create productrow.xml in layout view.
android:paddingLeft="4dp" android:layout_width="wrap_content" android:layout_height="wrap_content">
android:id="@+id/product_id" android:layout_alignParentLeft="true" android:src="@drawable/blank" android:layout_centerVertical="true">
android:layout_width="wrap_content" android:layout_height="wrap_content" android:textStyle="bold" android:textColor="#777777" android:shadowColor="@color/black" android:shadowRadius="0.5" android:shadowDx="0" android:shadowDy="0" android:layout_toRightOf="@+id/product_id" android:layout_marginLeft="4dip">
android:layout_height="wrap_content" android:layout_toRightOf="@+id/product_id" android:layout_below="@id/product_name">
|
4. Create ProductRowHolder in MainActivity:
public static class ProductRowHolder { public TextView productId, productName, productPrice; } |
5. Create JSONHttpClient.java:
combine Gson (https://code.google.com/p/google-gson/) with generic class to build a .net equivalent HttpClient for Android.
public class JSONHttpClient { public T PostObject(final String url, final T object, final Class objectClass) { DefaultHttpClient defaultHttpClient = new DefaultHttpClient(); HttpPost httpPost = new HttpPost(url); try {
StringEntity stringEntity = new StringEntity(new GsonBuilder().create().toJson(object)); httpPost.setEntity(stringEntity); httpPost.setHeader("Accept", "application/json"); httpPost.setHeader("Content-type", "application/json"); httpPost.setHeader("Accept-Encoding", "gzip");
HttpResponse httpResponse = defaultHttpClient.execute(httpPost); HttpEntity httpEntity = httpResponse.getEntity(); if (httpEntity != null) { InputStream inputStream = httpEntity.getContent(); Header contentEncoding = httpResponse.getFirstHeader("Content-Encoding"); if (contentEncoding != null && contentEncoding.getValue().equalsIgnoreCase("gzip")) { inputStream = new GZIPInputStream(inputStream); }
String resultString = convertStreamToString(inputStream); inputStream.close(); return new GsonBuilder().create().fromJson(resultString, objectClass);
}
} catch (UnsupportedEncodingException e) { e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates. } catch (ClientProtocolException e) { e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates. } catch (IOException e) { e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates. } return null; }
public T PostParams(String url, final List params, final Class objectClass) { String paramString = URLEncodedUtils.format(params, "utf-8"); url += "?" + paramString; return PostObject(url, null, objectClass); }
private String convertStreamToString(InputStream inputStream) { BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream)); StringBuilder stringBuilder = new StringBuilder(); String line = null; try { while ((line = bufferedReader.readLine()) != null) { stringBuilder.append(line + "\n"); } } catch (IOException e) { e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates. } finally { try { inputStream.close(); } catch (IOException e) { e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates. } }
return stringBuilder.toString(); }
public T Get(String url, List params, final Class objectClass) { DefaultHttpClient defaultHttpClient = new DefaultHttpClient(); String paramString = URLEncodedUtils.format(params, "utf-8"); url += "?" + paramString; HttpGet httpGet = new HttpGet(url); try {
httpGet.setHeader("Accept", "application/json"); httpGet.setHeader("Accept-Encoding", "gzip");
HttpResponse httpResponse = defaultHttpClient.execute(httpGet); HttpEntity httpEntity = httpResponse.getEntity(); if (httpEntity != null) { InputStream inputStream = httpEntity.getContent(); Header contentEncoding = httpResponse.getFirstHeader("Content-Encoding"); if (contentEncoding != null && contentEncoding.getValue().equalsIgnoreCase("gzip")) { inputStream = new GZIPInputStream(inputStream); }
String resultString = convertStreamToString(inputStream); inputStream.close(); return new GsonBuilder().create().fromJson(resultString, objectClass);
}
} catch (UnsupportedEncodingException e) { e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates. } catch (ClientProtocolException e) { e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates. } catch (IOException e) { e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates. } return null; }
public boolean Delete(String url, final List params) { DefaultHttpClient defaultHttpClient = new DefaultHttpClient(); String paramString = URLEncodedUtils.format(params, "utf-8"); url += "?" + paramString; HttpDelete httpDelete = new HttpDelete(url);
HttpResponse httpResponse = null; try { httpResponse = defaultHttpClient.execute(httpDelete); return httpResponse.getStatusLine().getStatusCode() == HttpStatus.SC_NO_CONTENT; } catch (IOException e) { e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates. }
return false; } } |
6. Create LoadAllProductsTask.java
package com.example.androidcallingwebapi.tasks;
import java.util.ArrayList; import java.util.List;
import org.apache.http.NameValuePair;
import com.example.androidcallingwebapi.JSONHttpClient; import com.example.androidcallingwebapi.models.Product; import com.example.androidcallingwebapi.util.ServiceUrl;
import android.app.ProgressDialog; import android.content.Context; import android.os.AsyncTask;
public class LoadAllProductsTask extends AsyncTask {
public Context context; private ProgressDialog progressDialog;
public LoadAllProductsTask(Context context) { super(); this.context = context; }
@Override protected Product[] doInBackground(String... params) { List nameValuePairs = new ArrayList(); JSONHttpClient jsonHttpClient = new JSONHttpClient(); Product[] products = jsonHttpClient.Get(ServiceUrl.PRODUCT, nameValuePairs, Product[].class);
return products; }
@Override protected void onPreExecute() { super.onPreExecute(); //To change body of overridden methods use File | Settings | File Templates. progressDialog = new ProgressDialog(context); progressDialog.setMessage("Loading products. Please wait..."); progressDialog.show(); }
}
|
7. Create ProductAdapter.java:
package com.example.androidcallingwebapi.adapters;
import com.example.androidcallingwebapi.MainActivity; import com.example.androidcallingwebapi.MainActivity.ProductRowHolder; import com.example.androidcallingwebapi.models.Product;
import com.example.androidcallingwebapi.R; import android.view.LayoutInflater; import android.view.View; import android.view.View.OnClickListener; import android.view.ViewGroup; import android.widget.BaseAdapter; import android.widget.TextView;
public class ProductAdapter extends BaseAdapter implements OnClickListener {
private LayoutInflater layoutInflater; private Product[] products;
public ProductAdapter (MainActivity a, LayoutInflater l, Product[] data) { this.layoutInflater = l; this.products = data; }
@Override public int getCount() { return this.products.length; }
@Override public Object getItem(int position) { return null; }
@Override public long getItemId(int position) { // TODO Auto-generated method stub return 0; }
@Override public View getView(int pos, View convertView, ViewGroup parent) { ProductRowHolder holder;
if (convertView == null) { convertView = layoutInflater.inflate(R.layout.productrow, parent, false); holder = new ProductRowHolder(); holder.productId = (TextView) convertView.findViewById(R.id.product_id); holder.productName = (TextView) convertView.findViewById(R.id.product_name); holder.productPrice = (TextView) convertView.findViewById(R.id.product_price); convertView.setTag(holder); } else { holder = (ProductRowHolder) convertView.getTag(); }
convertView.setOnClickListener(this);
Product product = products[pos]; holder.product = product; holder.productId.setText(product.getId()); holder.productName.setText(product.getName()); holder.productPrice.setText(product.getPrice() + "");
return convertView; }
@Override public void onClick(View v) { // TODO Auto-generated method stub
}
} |
8. Load Data in Main:
package com.example.androidcallingwebapi;
import java.util.concurrent.ExecutionException;
import com.example.androidcallingwebapi.adapters.ProductAdapter; import com.example.androidcallingwebapi.models.Product; import com.example.androidcallingwebapi.tasks.LoadAllProductsTask;
import android.os.Bundle; import android.app.Activity; import android.view.LayoutInflater; import android.view.Menu; import android.widget.ListView; import android.widget.TextView;
public class MainActivity extends Activity {
private ListView productList; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); this.productList = (ListView) findViewById(R.id.product_list); LoadAllProductsTask loadAllProductsTask = new LoadAllProductsTask(MainActivity.this.getApplicationContext()); Product[] products = null; try { loadAllProductsTask.execute(); } catch (Exception e) { loadAllProductsTask.cancel(true); //alert (getResources().getString(R.string.no_products)); } try { products = loadAllProductsTask.get(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (ExecutionException e) { // TODO Auto-generated catch block e.printStackTrace(); } if(products != null) { this.productList.setAdapter(new ProductAdapter(this,LayoutInflater.from(this), products)); } }
@Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.main, menu); return true; }
public static class ProductRowHolder { public TextView productId, productName, productPrice; public Product product; } }
|
9. Add config into AndroidManifest.xml for access internet:
|
10. Create ServiceUrl:
Be attention, the localhost should be set as 10.0.2.2.
public class ServiceUrl { public static final String REST_SERVICE_URL = "http://10.0.2.2:10081/api/"; public static final String PRODUCT = REST_SERVICE_URL + "products"; } |