之前我们探讨了Tomcat 搭建 HTTP 服务器,这节我们探讨一下Android 与 服务器的通信。

Android HTTP请求可以通过以下两种方式实现:

1. 使用JDK中HttpURLConnection访问网络资源(POST, GET)

2.使用Apache的HttpClient访问网络资源(POST, GET)

今天主要探讨第一种:


S0 安卓环境搭建


这是准备工作,不再累述。


http://jingyan.baidu.com/article/f0062228f0b18afbd2f0c871.html


S1 新建一个安卓工程

android 发送邮件intent 安卓发送http_java

用 MyEclipse (或 Eclipse) 新建一个安卓程序并命名为 AndroidHTTPDemo。

创建好空工程,点击运行,结果如截图所示:( HelloWorld 程序 )

android 发送邮件intent 安卓发送http_IP_02

S2 简单设计安卓界面,在原来基础上增加一个Button即可。

<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"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context=".MainActivity" >

    <TextView
        android:id="@+id/Infotv"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/hello_world" />

    <Button
        android:id="@+id/ShowBtn"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignLeft="@+id/textView1"
        android:layout_below="@+id/textView1"
        android:layout_marginTop="82dp"
        android:text="Show" />

</RelativeLayout>

SS1 GET 方法

S3 新建一个WebService类,在com.rxz.web包下,编写安卓的通信程序:

package com.rxz.web;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;

public class WebService {
	// IP地址
	private static String IP = "10.0.2.2:8080";

	/**
	 * 通过Get方式获取HTTP服务器数据
	 * @return
	 */
	public static String executeHttpGet() {
		
		HttpURLConnection conn = null;
		InputStream is = null;
		
        try {
        	// URL 地址
        	String path = "http://" + IP + "/HelloWeb/servlet/MyServlet";
        	
        	conn = (HttpURLConnection) new URL(path).openConnection();
    		conn.setConnectTimeout(5000); // 设置超时时间
    		conn.setRequestMethod("GET"); // 设置获取信息方式
    		conn.setRequestProperty("Charset", "UTF-8"); // 设置接收数据编码格式

    		if(conn.getResponseCode() == 200){
    			is = conn.getInputStream();
    			return parseInfo(is);
    		}

    		return null;
    		
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
        	// 意外退出时进行连接关闭保护
            if (conn != null) {
                conn.disconnect();
            }
            if (is != null) {
                try {
                    is.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
 
        }
        return null;
    }
	
	/**
	 * 将输入流转化为 String 型
	 * @param inStream
	 * @return
	 * @throws Exception
	 */
	private static String parseInfo(InputStream inStream) throws Exception{
		byte[] data = read(inStream);
		//转化为字符串
		return new String(data, "UTF-8");
	}
	
	/**
	 * 将输入流转化为byte型
	 * @param inStream
	 * @return
	 * @throws Exception
	 */
	public static byte[] read(InputStream inStream) throws Exception{
		ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
		byte[] buffer = new byte[1024];
		int len = 0;
		while((len = inStream.read(buffer)) != -1){
			outputStream.write(buffer,0,len);
		}
		inStream.close();
		return outputStream.toByteArray();
	}
}

S4 修改MainActivity界面类,获取Button,并响应按钮点击事件:

package com.rxz.androidhttpdemo;

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

import com.rxz.web.WebService;

public class MainActivity extends Activity implements OnClickListener {
	
	// 显示按钮
	private Button showbtn = null;
	// 显示文本区域
	private TextView infotv = null;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		
		// 获取控件
		showbtn = (Button) findViewById(R.id.ShowBtn);
		infotv = (TextView) findViewById(R.id.Infotv);
		
		// 设置按钮监听器
		showbtn.setOnClickListener(this);	
	}

	@Override
	public void onClick(View v) {
		// TODO Auto-generated method stub
		switch(v.getId())
		{
		// 显示按钮点击事件
		case R.id.ShowBtn:
			String info = WebService.executeHttpGet();
			infotv.setText(info);
			break;
		}
	}
}

S5 切记:增加安卓联网权限!!!在AndroidManifest.xml文件里面:

<!-- 联网权限 -->
    <uses-permission android:name="android.permission.INTERNET" />

S6 先运行01节博客所讲的HTTP 服务器,然后运行安卓程序,按下按钮,效果如下,表明成功。




android 发送邮件intent 安卓发送http_android 发送邮件intent_03



SS2 POST方法


S7 新建一个WebServicePost类,在com.rxz.web包下,编写安卓的通信程序:

package com.rxz.web;

import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;

public class WebServicePost {
	
	// IP地址
	private static String IP = "10.0.2.2:8080";
	
	/**
	 * 通过 POST 方式获取HTTP服务器数据
	 * @param infor
	 * @param credit
	 * @return
	 * @throws Exception
	 */
	public static String executeHttpPost(String infor,String credit){
		
		try {
			String path = "http://" + IP + "/HelloWeb/servlet/MyServlet";
			
			// 发送指令和信息
			Map<String,String> params = new HashMap<String,String>();
			params.put("infor", infor);
			params.put("state", credit);
			
			return sendPOSTRequest(path, params, "UTF-8");
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} 
		
		return null;
	}
	
	/**
	 * 处理发送数据请求
	 * @param path
	 * @param params
	 * @param encoding
	 * @return
	 * @throws Exception
	 */
	private static String sendPOSTRequest(String path,
			Map<String, String> params, String encoding) throws Exception {
		// TODO Auto-generated method stub
		List<NameValuePair> pairs = new ArrayList<NameValuePair>();
		if(params != null && !params.isEmpty()){
			for(Map.Entry<String, String> entry : params.entrySet()){
				pairs.add(new BasicNameValuePair(entry.getKey(),entry.getValue()));
			}
		}
		
		UrlEncodedFormEntity entity = new UrlEncodedFormEntity(pairs,encoding);
		
		HttpPost post = new HttpPost(path);
		post.setEntity(entity);
		DefaultHttpClient client = new DefaultHttpClient();
		HttpResponse response = client.execute(post);
		
		// 判断是否成功收取信息
		if(response.getStatusLine().getStatusCode() == 200){
			return getInfo(response);
		}
		
		// 未成功收取信息,返回空指针
		return null;
	}
	
	/**
	 * 收取数据
	 * @param response
	 * @return
	 * @throws Exception
	 */
	private static String getInfo(HttpResponse response) throws Exception{
		
	    HttpEntity entity =	response.getEntity();
	    InputStream is = entity.getContent();
		//将输入流转化为byte型
		byte[] data = WebService.read(is);
		//转化为字符串
		return new String(data, "UTF-8");
	}
	
}

S8 修改MainActivity界面类,获取Button,并响应按钮点击事件:

@Override
	public void onClick(View v) {
		// TODO Auto-generated method stub
		switch(v.getId())
		{
		// 显示按钮点击事件
		case R.id.ShowBtn:
			//String info = WebService.executeHttpGet();
			//infotv.setText(info);
			String info = WebServicePost.executeHttpPost("MyCommand", "This is My Info");
			infotv.setText(info);
			break;
		}
	}

S9 修改服务器MyServlet类的doPost方法,实现获取用户传递信息并反馈信息的功能:


/**
	 * The doPost method of the servlet. <br>
	 *
	 * This method is called when a form has its tag value method equals to post.
	 * 
	 * @param request the request send by the client to the server
	 * @param response the response send by the server to the client
	 * @throws ServletException if an error occurred
	 * @throws IOException if an error occurred
	 */
	public void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		
		System.out.println("************   POST正在接收请求      *************");
		
		// 设置编码方式
		request.setCharacterEncoding("UTF-8");
		// 获取到 命令信息
		String infor = request.getParameter("infor");
		// 获取到 参数信息
		String credit = request.getParameter("state");
		
		System.out.println("收到的客户端的信息为:" + infor);
		System.out.println("    收到客户端的命令:" + credit);
		
		
		System.out.println("************   正在发送信息      *************");
		
		// 发送信息
		response.setCharacterEncoding("UTF-8");
		response.setContentType("text/html");
		PrintWriter out = response.getWriter();
		out.println("回馈信息" + infor + ":" + credit);
		
		out.flush();
		out.close();
		
	}

S10 重新运行HTTP 服务器,然后运行安卓程序,按下按钮,效果如下,表明成功。


android 发送邮件intent 安卓发送http_java_04



PS: 关键点:


注意:因为是通过android模拟器访问本地pc服务端,所以不能使用localhost和127.0.0.1,使用127.0.0.1会访问模拟器自身。


Android系统为实现通信将PC的IP设置为10.0.2.2