文档章节

Android访问互联网

 晨风浅逝
发布于 2016/10/15 02:06
字数 2950
阅读 9
收藏 0

        大家知道Google支持和发布的Android移动操作系统,主要是为了使其迅速占领移动互联网的市场份额,所谓移动互联网当然也是互联网了,凡是涉及互联网的任何软件任何程序都少不了联网模块的开发,诚然Android联网开发也是我们开发中至关重要的一部分,那么Android是怎么样进行联网操作的呢?这篇博客就简单的介绍一下Android常用的联网方式,包括JDK支持的HttpUrlConnection,Apache支持的HttpClient,以及开源的一些联网框架(譬如AsyncHttpClient)的介绍。本篇博客只讲实现过程和方式,不讲解原理,否则原理用文字很难以讲清,其实我们知道怎么去用,就可以解决一些基本开发需要了。

        绝大多数的Android应用联网都是基于Http协议的,也有很少是基于Socket的,我们这里主要讲解基于Http协议的联网方式。讲解实例是建立在一个模拟的登录小模块中进行,登录请求数据仅仅只有username和password两个简单字段。

 

HttpUrlConnection

HttpUrlConnection是JDK里提供的联网API,我们知道Android SDK是基于Java的,所以当然优先考虑HttpUrlConnection这种最原始最基本的API,其实大多数开源的联网框架基本上也是基于JDK的HttpUrlConnection进行的封装罢了,掌握HttpUrlConnection需要以下几个步骤:

1    将访问的路径转换成URL

 

URL url = new URL(path);

 

2,通过URL获取连接。

 

HttpURLConnection conn = (HttpURLConnection) url.openConnection();

 

3,设置请求方式

 

conn.setRequestMethod(GET);

 

4,设置连接超时时间。

 

conn.setConnectTimeout(5000);

 

5,设置请求头的信息。

 

conn.setRequestProperty(User-Agent, Mozilla/5.0 (compatible; MSIE 9.0; Windows

6,获取响应码

 

?

1

int code = conn.getResponseCode();

 

7,针对不同的响应码,做不同的操作

7.1,请求码200,表明请求成功,获取返回内容的输入流

 

?

1

InputStream is = conn.getInputStream();

 

7.2,将输入流转换成字符串信息

 

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

public class StreamTools {

    /**

     * 将输入流转换成字符串

     *

     * @param is

     *            从网络获取的输入流

     * @return

     */

    public static String streamToString(InputStream is) {

        try {

            ByteArrayOutputStream baos = new ByteArrayOutputStream();

            byte[] buffer = new byte[1024];

            int len = 0;

            while ((len = is.read(buffer)) != -1) {

                baos.write(buffer, 0, len);

            }

            baos.close();

            is.close();

            byte[] byteArray = baos.toByteArray();

            return new String(byteArray);

        } catch (Exception e) {

            Log.e(tag, e.toString());

            return null;

        }

    }

}

 

7.3,若返回值400,则是返回网络异常,做出响应的处理。

HttpUrlConnection发送GET请求

 

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

/**

     * 通过HttpUrlConnection发送GET请求

     *

     * @param username

     * @param password

     * @return

     */

    public static String loginByGet(String username, String password) {

        String path = http://192.168.0.107:8080/WebTest/LoginServerlet?username= + username + &password= + password;

        try {

            URL url = new URL(path);

            HttpURLConnection conn = (HttpURLConnection) url.openConnection();

            conn.setConnectTimeout(5000);

            conn.setRequestMethod(GET);

            int code = conn.getResponseCode();

            if (code == 200) {

                InputStream is = conn.getInputStream(); // 字节流转换成字符串

                return StreamTools.streamToString(is);

            } else {

                return 网络访问失败;

            }

        } catch (Exception e) {

            e.printStackTrace();

            return 网络访问失败;

        }

    }

 

HttpUrlConnection发送POST请求

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

/**

     * 通过HttpUrlConnection发送POST请求

     *

     * @param username

     * @param password

     * @return

     */

    public static String loginByPost(String username, String password) {

        String path = http://192.168.0.107:8080/WebTest/LoginServerlet;

        try {

            URL url = new URL(path);

            HttpURLConnection conn = (HttpURLConnection) url.openConnection();

            conn.setConnectTimeout(5000);

            conn.setRequestMethod(POST);

            conn.setRequestProperty(Content-Type, application/x-www-form-urlencoded);

            String data = username= + username + &password= + password;

            conn.setRequestProperty(Content-Length, data.length() + );

            // POST方式,其实就是浏览器把数据写给服务器

            conn.setDoOutput(true); // 设置可输出流

            OutputStream os = conn.getOutputStream(); // 获取输出流

            os.write(data.getBytes()); // 将数据写给服务器

            int code = conn.getResponseCode();

            if (code == 200) {

                InputStream is = conn.getInputStream();

                return StreamTools.streamToString(is);

            } else {

                return 网络访问失败;

            }

        } catch (Exception e) {

            e.printStackTrace();

            return 网络访问失败;

        }

    }

 

HttpClient

HttpClient是开源组织Apache提供的Java请求网络框架,其最早是为了方便Java服务器开发而诞生的,是对JDK中的HttpUrlConnection各API进行了封装和简化,提高了性能并且降低了调用API的繁琐,Android因此也引进了这个联网框架,我们再不需要导入任何jar或者类库就可以直接使用,值得注意的是Android官方已经宣布不建议使用HttpClient了,我们再开发的时候尽量少用吧,但是用了也无妨!

HttpClient发送GET请求

1, 创建HttpClient对象

2,创建HttpGet对象,指定请求地址(带参数)

3,使用HttpClient的execute(),方法执行HttpGet请求,得到HttpResponse对象

4,调用HttpResponse的getStatusLine().getStatusCode()方法得到响应码

5,调用的HttpResponse的getEntity().getContent()得到输入流,获取服务端写回的数据

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

/**

     * 通过HttpClient发送GET请求

     *

     * @param username

     * @param password

     * @return

     */

    public static String loginByHttpClientGet(String username, String password) {

        String path = http://192.168.0.107:8080/WebTest/LoginServerlet?username=

                + username + &password= + password;

        HttpClient client = new DefaultHttpClient(); // 开启网络访问客户端

        HttpGet httpGet = new HttpGet(path); // 包装一个GET请求

        try {

            HttpResponse response = client.execute(httpGet); // 客户端执行请求

            int code = response.getStatusLine().getStatusCode(); // 获取响应码

            if (code == 200) {

                InputStream is = response.getEntity().getContent(); // 获取实体内容

                String result = StreamTools.streamToString(is); // 字节流转字符串

                return result;

            } else {

                return 网络访问失败;

            }

        } catch (Exception e) {

            e.printStackTrace();

            return 网络访问失败;

        }

    }

 

HttpClient发送POST请求

1,创建HttpClient对象

2,创建HttpPost对象,指定请求地址

3,创建List,用来装载参数

4,调用HttpPost对象的setEntity()方法,装入一个UrlEncodedFormEntity对象,携带之前封装好的参数

5,使用HttpClient的execute()方法执行HttpPost请求,得到HttpResponse对象

6, 调用HttpResponse的getStatusLine().getStatusCode()方法得到响应码

7, 调用的HttpResponse的getEntity().getContent()得到输入流,获取服务端写回的数据

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

/**

     * 通过HttpClient发送POST请求

     *

     * @param username

     * @param password

     * @return

     */

    public static String loginByHttpClientPOST(String username, String password) {

        String path = http://192.168.0.107:8080/WebTest/LoginServerlet;

        try {

            HttpClient client = new DefaultHttpClient(); // 建立一个客户端

            HttpPost httpPost = new HttpPost(path); // 包装POST请求

            // 设置发送的实体参数

            List<namevaluepair> parameters = new ArrayList<namevaluepair>();

            parameters.add(new BasicNameValuePair(username, username));

            parameters.add(new BasicNameValuePair(password, password));

            httpPost.setEntity(new UrlEncodedFormEntity(parameters, UTF-8));

            HttpResponse response = client.execute(httpPost); // 执行POST请求

            int code = response.getStatusLine().getStatusCode();

            if (code == 200) {

                InputStream is = response.getEntity().getContent();

                String result = StreamTools.streamToString(is);

                return result;

            } else {

                return 网络访问失败;

            }

        } catch (Exception e) {

            e.printStackTrace();

            return 访问网络失败;

        }

    }</namevaluepair></namevaluepair>

 

其他开源联网框架

AsyncHttpClient

除了上述Android官方推荐的联网框架以外,在开源世界里关于联网框架真是太多太多了,例如afinal,xutils等等,都是一些开源大牛自己封装的联网框架,并且在GitHub开源社区中可以下载到,其实类似的开源联网框架基本上也是基于HttpUrlConnection的进一步封装,大大提高了性能,同时更加简化了使用方法,这里使用AsyncHttpClient作为案例,其他的联网框架大家可以去网上找,下载使用试试便可。 AsyncHttpClient是一个非常优秀的联网框架,不仅支持所有Http请求的方式,而且还支持文件的上传和下载,要知道用HttpUrlConnection写一个文件上传和下载健全功能是很需要花费一定时间和精力的,因为请求头实在是太多了,稍有不慎就会写错。但是AsyncHttpClient已经封装好了这些“麻烦”,我们只需要下载到AsyncHttpClient的jar包或者源码导入项目中,Http,上传,下载等等,只需要几个简单的api即可搞定。 AsyncHttpClient的GitHub主页:https://github.com/AsyncHttpClient/async-http-client/

AsyncHttpClient发送GET请求

1,将下载好的源码拷贝到src目录下

2,创建一个AsyncHttpClient的对象

3,调用该类的get方法发送GET请求,传入请求资源地址URL,创建AsyncHttpResponseHandler对象

4,重写AsyncHttpResponseHandler下的两个方法,onSuccess和onFailure方法

 

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

/**

     * 通过AsyncHttpClient发送GET请求

     */

    public void loginByAsyncHttpGet() {

        String path = http://192.168.0.107:8080/WebTest/LoginServerlet?username=zhangsan&password=123;

        AsyncHttpClient client = new AsyncHttpClient();

        client.get(path, new AsyncHttpResponseHandler() {

 

            @Override

            public void onFailure(int arg0, Header[] arg1, byte[] arg2,

                    Throwable arg3) {

                // TODO Auto-generated method stub

                Log.i(TAG, 请求失败: + new String(arg2));

            }

 

            @Override

            public void onSuccess(int arg0, Header[] arg1, byte[] arg2) {

                // TODO Auto-generated method stub

                Log.i(TAG, 请求成功: + new String(arg2));

            }

        });

    }

 

AsyncHttpClient发送POST请求

1,将下载好的源码拷贝到src目录下

2,创建一个AsyncHttpClient的对象

3,创建请求参数,RequestParams对象

4,调用该类的post方法发POST,传入请求资源地址URL,请求参数RequestParams,创建AsyncHttpResponseHandler对象

5,重写AsyncHttpResponseHandler下的两个方法,onSuccess和onFailure方法

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

/**

     * 通过AsyncHttpClient发送POST请求

     */

    public void loginByAsyncHttpPost() {

        String path = http://192.168.0.107:8080/WebTest/LoginServerlet;

        AsyncHttpClient client = new AsyncHttpClient();

        RequestParams params = new RequestParams();

        params.put(username, zhangsan);

        params.put(password, 123);

        client.post(path, params, new AsyncHttpResponseHandler() {

 

            @Override

            public void onFailure(int arg0, Header[] arg1, byte[] arg2,

                    Throwable arg3) {

                // TODO Auto-generated method stub

                Log.i(TAG, 请求失败: + new String(arg2));

            }

 

            @Override

            public void onSuccess(int arg0, Header[] arg1, byte[] arg2) {

                // TODO Auto-generated method stub

                Log.i(TAG, 请求成功: + new String(arg2));

            }

        });

    }

AsyncHttpClient上传文件

1,将下载好的源码拷贝到src目录下

2,创建一个AsyncHttpClient的对象

3,创建请求参数,RequestParams对象,请求参数仅仅包含文件对象即可,例如:

 

?

1

params.put(profile_picture, new File(/sdcard/pictures/pic.jpg));

 

4,调用该类的post方法发POST,传入请求资源地址URL,请求参数RequestParams,创建AsyncHttpResponseHandler对象

5,重写AsyncHttpResponseHandler下的两个方法,onSuccess和onFailure方法

 

判断网络连接状态

很多时候对于手机或者平板电脑这样的手持设备,我们是不知道它们的网络连接状态的,在联网的时候我们必须得保证设备的网路是否正常,是否可以连接上互联网,或者我们在进行大量数据上传或者下载,例如下载网路视频,看网路电视等等,我们必须得为用户省钱,这样大数据的传输显然是不能使用用户昂贵的数据流量的,而是判断当前网络是不是在wifi下,使用WiFi来进行大数据的传输,会给用户更好的体验,那么下面这个工具类就是用来判断设备网络连接状态的,不仅判断了当前设置手机网络下还是WiFi环境下,而且如果手机网络下还需要设置运营商的代理IP和端口。

 

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

/**

 * 判断网络状态的工具类

 *

 */

public class NetworkUtil {

 

    /* 代码IP */

    private static String PROXY_IP = null;

    /* 代理端口 */

    private static int PROXY_PORT = 0;

    /**

     * 判断当前是否有网络连接

     *

     * @param context

     * @return

     */

    public static boolean isNetwork(Context context) {

        boolean network = isWifi(context);

        boolean mobilework = isMobile(context);

        if (!network && !mobilework) { // 无网络连接

            Log.i(NetworkUtil, 无网路链接!);

            return false;

        } else if (network == true && mobilework == false) { // wifi连接

            Log.i(NetworkUtil, wifi连接!);

        } else { // 网络连接

            Log.i(NetworkUtil, 手机网路连接,读取代理信息!);

            readProxy(context); // 读取代理信息

            return true;

        }

        return true;

    }

 

    /**

     * 读取网络代理

     *

     * @param context

     */

    private static void readProxy(Context context) {

        Uri uri = Uri.parse(content://telephony/carriers/preferapn);

        ContentResolver resolver = context.getContentResolver();

        Cursor cursor = resolver.query(uri, null, null, null, null);

        if (cursor != null && cursor.moveToFirst()) {

            PROXY_IP = cursor.getString(cursor.getColumnIndex(proxy));

            PROXY_PORT = cursor.getInt(cursor.getColumnIndex(port));

        }

        cursor.close();

    }

 

    /**

     * 判断当前网络是否是wifi局域网

     *

     * @param context

     * @return

     */

    public static boolean isWifi(Context context) {

        ConnectivityManager manager = (ConnectivityManager) context

                .getSystemService(Context.CONNECTIVITY_SERVICE);

        NetworkInfo info = manager

                .getNetworkInfo(ConnectivityManager.TYPE_WIFI);

        if (info != null) {

            return info.isConnected(); // 返回网络连接状态

        }

        return false;

    }

 

    /**

     * 判断当前网络是否是手机网络

     *

     * @param context

     * @return

     */

    public static boolean isMobile(Context context) {

        ConnectivityManager manager = (ConnectivityManager) context

                .getSystemService(Context.CONNECTIVITY_SERVICE);

        NetworkInfo info = manager

                .getNetworkInfo(ConnectivityManager.TYPE_MOBILE);

        if (info != null) {

            return info.isConnected(); // 返回网络连接状态

        }

        return false;

    }

}

 

© 著作权归作者所有

粉丝 0
博文 1
码字总数 2950
作品 0
武汉
程序员
私信 提问
关于蓝牙设备之间共享网络的问题(android4.2)

前言:如果要共享蓝牙设备A的的网络,设备B只需要配对好设备A,并勾选”互联网访问”,如下图所示: 项目:android设备通过蓝牙配对ubuntu设备,ubuntu设备可以访问互联网并且提供网络共享给...

种豆南山下920
2016/08/01
413
0
中国 Android 应用开发者发起 Android 绿色应用公约

众所周知,中国的 Android 应用有两大现象:索要过多的权限,一个扫雷游戏都想要能记录音频和视频的访问权限;后台活跃,即使在应用彻底关闭的情况下它也会主动唤醒自己,比如中国著名互联网...

局长
2017/05/15
5.9K
70
(转)Android拍摄的视频无法在IOS播放

https://blog.csdn.net/u012992171/article/details/50673305 公司最近的项目需要上线一个视频功能,在临近尾声的时候出现了一个比较坑爹的BUG,那就是开发Android的同事拍摄的视频上传到服务...

小曼Study
2018/08/08
0
0
Firefox for Android 正式支持安卓平板

  【IT168资讯】重新设计的Firefox for Android新增对安卓平板电脑的支持,目前已经在Google Play商店中提供下载。据了解,该版本具有与手机版Firefox for Android同样的强大性能提升,无论...

作者:厂商投稿
2012/08/29
0
0
Android 面试的时候简历如何写

  还是那句老生常谈的话,如今面试已经不是多年以前了,准备过程中一定要准备回答各种深入的理解、扩展。   只要你简历上写到的技术,你最起码要准备好回答:   该技术原理是?   做...

Android群英传
08/26
0
0

没有更多内容

加载失败,请刷新页面

加载更多

PhotoShop 高级应用:USM锐化/S锐化/防抖

、 高反差锐化+混合模式:叠加模式 【将更多的边缘细节添加到图像中】

东方墨天
24分钟前
6
0
Python数据可视化之matplotlib

常用模块导入 import numpy as npimport matplotlibimport matplotlib.mlab as mlabimport matplotlib.pyplot as pltimport matplotlib.font_manager as fmfrom mpl_toolkits.mplot3d i......

松鼠大帝
昨天
5
0
我用Bash编写了一个扫雷游戏

我在编程教学方面不是专家,但当我想更好掌握某一样东西时,会试着找出让自己乐在其中的方法。比方说,当我想在 shell 编程方面更进一步时,我决定用 Bash 编写一个扫雷游戏来加以练习。 我在...

老孟的Linux私房菜
昨天
7
0
Go语言Hello world(GOPATH和Go Module版)

本文是「vangoleo的Go语言学习笔记」系列文章之一。 官网: http://www.vangoleo.com/go/go-hello-world-02/ 往期回顾: Go语言入门-你好,Go语言 Go语言入门-Hello World(Go Playground版) 上...

vangoleo
昨天
9
0
C++虚函数以及虚函数表

在了解虚函数之前先了解下对象模型: 对象模型: 在C++中,有两种数据成员(class data members):static 和nonstatic,以及三种类成员函数(class member functions):static、nonstatic和v...

黑白双键
昨天
9
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部