Frank Ableson, 软件设计师

简介: Android 是面向应用程序开发的丰富平台,它提供一套出色的用户界面元素和数据管理功能。它还为开发连接到真实世界的应用程序提供了出色的网络选项。您希望连接到哪 里?也许您希望告诉全世界您正在使用 Twitter。或者希望收到有关在本地洗衣店或熟食店的排号。如果希望将 Android 连接到您所生活的世界,那么请阅读本文。

本文的标签:  社交网络

发布日期: 2009 年 6 月 29 日

简介

本文建立在 “使用 Eclipse 开发 Android 应用程序” 一文的基础之上,探究了 Android 的网络功能。了解如何利用 Android 的网络选项来实现有趣、有用的东西。Android 平台非常适合 Java™ 开发人员:他们可以使用已有的技能将网络连接带到一个移动或 “嵌入式” 平台中。

在本文中,了解用于 Android 应用程序的网络选项以及基本的 Android 联网技巧。本文研究一个真实的应用程序,它在结合使用环境监视系统时需要具备联网功能。这类系统为什么如此重要?原因之一是:如果您的朋友需要外出几个星 期,在他离开后,他打电话给我,让我从他家里找到某样东西并邮寄给他。我来到他的家里,发现供暖设备已经被切断并且水管已经冻裂 — 场面非常混乱。如果备有一个温度监控系统,那么就可以避免出现这类事故。本文将探查 Android 在这类监控系统中扮演的角色。

回页首

Android 联网功能

Android 基于 Linux® 内核,包含一组优秀的联网功能。如果尚未安装 Android SDK,那么需要 下载 它才能实践本文的示例。

表 1 展示了 Android SDK 中一些与网络有关的包。

表 1. Android SDK 网络包

描述
java.net 提供与联网有关的类,包括流和数据包(datagram)sockets、Internet 协议和常见 HTTP 处理。该包是一个多功能网络资源。有经验的 Java 开发人员可以立即使用这个熟悉的包创建应用程序。
java.io 虽然没有提供显式的联网功能,但是仍然非常重要。该包中的类由其他 Java 包中提供的 socket 和连接使用。它们还用于与本地文件(在与网络进行交互时会经常出现)的交互。
java.nio 包含表示特定数据类型的缓冲区的类。适合用于两个基于 Java 语言的端点之间的通信。
org.apache.* 表示许多为 HTTP 通信提供精确控制和功能的包。可以将 Apache 视为流行的开源 Web 服务器。
android.net 除核心 java.net.* 类以外,包含额外的网络访问 socket。该包包括 URI 类,后者频繁用于 Android 应用程序开发,而不仅仅是传统的联网方面。
android.net.http 包含处理 SSL 证书的类。
android.net.wifi 包含在 Android 平台上管理有关 WiFi(802.11 无线 Ethernet)所有方面的类。并不是所有设备都配备了 WiFi 功能,特别是 Android 在 Motorola 和 LG 等手机制造商的 “翻盖手机” 领域获得了成功。
android.telephony.gsm 包含用于管理和发送 SMS(文本)消息的类。一段时间后,可能会引入额外的包来来为非 GSM 网络提供类似的功能,比如 CDMA 或 android.telephony.cdma 等网络。

上表并没有列出所有包,但是可以让您清楚地意识到该平台的强大功能。下一小节将介绍一些简单的网络示例。

回页首

简单的网络示例

为了演示将 Android 连接到一个网络有多么简单,这个示例将展示如何从 Web 页面发送文本。可以 下载 本例的源代码。图 1 展示了应用程序的实际使用。

图 1. 从 Web 页面获取文本

本节提供了构建示例应用程序所需的代码。我们将首先查看 UI 部分,然后介绍与网络有关的代码。

共有三个 UI 元素:

  • EditText 让用户能够进入一个 Web 页面(图 1 和 清单 2 所示的 http://developer.android.com)。
  • 使用一个按钮告诉程序取回 Web 页面文本。
  • 检索回数据后,它将显示在 TextView 中。

清单 1 展示了 main.xml 文件,这是该应用程序的完整 UI 布局。

清单 1. main.xml

                <?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"     > <EditText  android:layout_height="wrap_content" android:id="@+id/address" android:layout_width="fill_parent" android:text="http://google.com" > </EditText> <Button  android:id="@+id/ButtonGo"   android:layout_width="wrap_content"   android:layout_height="wrap_content"  android:text="go!"  > </Button> <TextView       android:layout_width="fill_parent"      android:layout_height="fill_parent"      android:background="#ffffff"     android:textColor="#000000"   android:id="@+id/pagetext"     /> </LinearLayout> 

清单 2 展示了本示例使用的 Java 代码。

清单 2. GetWebPage.java

                 package com.msi.getwebpage;  import android.app.Activity; import android.os.Bundle; // used for interacting with user interface import android.widget.Button; import android.widget.TextView; import android.widget.EditText; import android.view.View; // used for passing data  import android.os.Handler; import android.os.Message; // used for connectivity import java.io.BufferedReader; import java.io.InputStreamReader; import java.net.URL; import java.net.URLConnection;   public class GetWebPage extends Activity {     /** Called when the activity is first created. */      Handler h;       @Override     public void onCreate(Bundle savedInstanceState) {         super.onCreate(savedInstanceState);         setContentView(R.layout.main);                  final EditText eText = (EditText) findViewById(R.id.address);         final TextView tView = (TextView) findViewById(R.id.pagetext);                  this.h = new Handler() {              @Override             public void handleMessage(Message msg) {                 // process incoming messages here                 switch (msg.what) {                     case 0:                       tView.append((String) msg.obj);                         break;                 }                 super.handleMessage(msg);             }         };         final Button button = (Button) findViewById(R.id.ButtonGo);         button.setOnClickListener(new Button.OnClickListener() {             public void onClick(View v) {                 try {                   tView.setText("");                 // Perform action on click                     URL url = new URL(eText.getText().toString());                     URLConnection conn = url.openConnection();                     // Get the response                     BufferedReader rd = new BufferedReader(new  InputStreamReader(conn.getInputStream()));                     String line = "";                     while ((line = rd.readLine()) != null) {                         Message lmsg;                         lmsg = new Message();                         lmsg.obj = line;                         lmsg.what = 0;                         GetWebPage.this.h.sendMessage(lmsg);                     }               }               catch (Exception e) {               }             }         });             } } 

这些代码可以分解成一些常见的部分。这里使用一些重要(必需)的导入语句来恰当地引用 UI、数据传递以及应用程序中使用的与网络有关的类。所有与网络相关的代码出现在 OnClickListenerOnClick 方法中。在选择 图 1 所示的标签为 go! 的按钮之后调用这些代码。

URLURLConnection 类共同提供与用户所选的 Web 站点的连接。BufferedReader 的一个实例负责从 Web 站点连接中读取传入的数据。每读取一行代码,文本就被附加到一个 TextView。数据并没有直接指定给 TextView(但是在本例中可以)。我们引入了一种设计模式,即创建一个消息对象并将该对象发送到一个处理程序的实例。这是更新 UI 的一种比较可取的方法,对可能需要同时运行多个线程的应用程序而言尤其如此。

在示例中,Android 应用程序与 HTTP Web 服务器进行通信,比如 Apache 或 Internet Information Server(IIS 位于 Microsoft® 服务器上)。如果应用程序直接与 TCP socket 对话,那么您将以不同的方式实现应用程序。清单 3 所示的代码片段展示了另一种与远程服务器交互的方式。这个清单被实现为一个单独的线程。

清单 3. Daytime 客户机

                   public class Requester extends Thread {         Socket requestSocket;         String message;         StringBuilder returnStringBuffer = new StringBuilder();         Message lmsg;         int ch;         @Override         public void run() {             try {                 this.requestSocket = new Socket("remote.servername.com", 13);                 InputStreamReader isr = new InputStreamReader(this.requestSocket. getInputStream(), "ISO-8859-1");                 while ((this.ch = isr.read()) != -1) {                     this.returnStringBuffer.append((char) this.ch);                 }                 this.message = this.returnStringBuffer.toString();                 this.lmsg = new Message();                 this.lmsg.obj = this.message;                 this.lmsg.what = 0;                 h.sendMessage(this.lmsg);                 this.requestSocket.close();             } catch (Exception ee) {                 Log.d("sample application", "failed to read data" + ee.getMessage());             }         }     } 

与前面的示例类似,上面的代码使用消息和处理程序方法来将数据发送给调用者,调用者将更新 UI 并执行后续处理。与 清单 1 不同,这个例子并没有与 HTTP 服务器通信,因此没有使用 URLConnection 类。相反,使用了较低级的 Socket 类在端口 13 打开与远程服务器的基于流的 socket 连接。端口 13 是典型的 “Daytime Server” 应用程序。

Daytime Server 接受传入的 socket 连接并以文本的形式将日期和时间发送给调用 socket。一旦发送完数据,服务器将关闭 socket。示例也展示了 InputStreamReader 的使用和一个特定字符编码。

发送文本消息是您需要使用 Android 完成的另一项任务。清单 4 展示了一个示例。

清单 4. 发送一条文本消息

                void sendMessage(String recipient,String myMessage) {  SmsManager sm = SmsManager.getDefault();  sm.sendTextMessage("destination number",null,"hello there",null,null); } 

发送文本消息非常简单。首先,使用静态方法 getDefault() 获取对 SmsManager 的引用。然后调用 sendTextMessage 方法。参数为:

接收者的手机号
包括区号。
服务中心电话号码
使用 null 值表示您同意使用默认服务中心来处理消息。除了非常特殊的应用程序外,几乎所有应用程序都对这个参数使用 null 值。
消息的实际内容
将消息长度保持在 160 字节以内,除非您可以接受将数据分为多个消息发送。
未收到消息 intent
如果消息被发送或出现了错误,那么将开始一个可选的 intent。如果不需要这类通知,那么可以为此参数传递一个 null 值。(参见 参考资料 了解有关 intent 和 Android 基本原理的更多信息)。
收到消息 intent
当收到发送确认后,将开始一个可选的 Intent。如果发送通知不重要的话,那么可以为这个参数传递一个 null 值。

不管是连接到 Web 页面还是连接到定制 TCP 应用程序,Android 平台都可以立即反应并且能够提供帮助。如 清单 4 所示,发送文本消息非常简单。通过使用可选的 intent 参数,甚至可以在消息被发送并交付后采取操作。这是其他移动平台所不具备的强大特性。

下一节将快速浏览一个真实的应用程序设计。

回页首

环境监控系统

在这个场景中,我们假设您是企业所在的若干办公场所的资产管理员。管理资产与管理数据中心没有太大的差别 — 一般情况下都很枯燥,只有出现紧急的情况下工作才会比较有意思。几天前,一台使用了 10 年的热水器突然漏水,渗到一个装满老式 PC 和培训手册的存储柜,您必须检查一下清理情况。幸运的是,您当时没有外出。如果您在旅途中的话,那么情形将非常糟糕。此类灾难性事故促使我们考虑使用 Android 来帮助监视资产的维护情况。图 2 展示了此类系统的一个高级方框图。

图 2. 监控系统的高级方框图

此架构是一种比较传统的方法,使用一个微控制器与一些简单场景进行交互以收集数据。数据随后通过一个串行通信协议(比如 RS232 或 RS485)发送到控制器。控制器可以是一个 PC 或类似的机器。随后可以穿过防火墙通过 Internet 访问数据。Android 电话(比如 TMobile G1)之间使用的协议可以是 HTTP 或私有协定。

在控制器和配备 Android 的设备之间发送的数据将是表示以下内容的基本数据:

  • 出现漏水
  • 当前温度
  • 消耗的功率
  • 可能包含一些通用的类似数据和数字值

为什么需要关注消耗的功率?一个可能的原因就是有些人忘记关闭机器,因此电费单上的数字会一直增长。第二个理由有些复杂:假设您有一台非常大 的冰箱,并且电源可能已被关闭。那么情况就复杂了,而且处理起来也需要很高的代价。或者,空调设备的断路器出现故障,因此机房无法保持恒定的温度。

基本的设计看上去是可行的。如果使用的是 Android,那么可以使用任何移动平台来替换 图 2 中的 Android。但如果使用配备了 Android 的设备替换微控制器,那应该怎么做呢?下一节将讨论对这个应用程序的扩展以及通过使用 Android 而启用的特性。

回页首

扩展应用程序

本文的第一个架构以一个微控制器为中心。微控制器可分为不同的外形和大小,从 Microchip 的 6 pin “10F” 到添加了外围设备、pin 和代码空间的 32 位大型微控制器。如果使用 Android 取代传统的微控制器放到设备中,会怎么样?对于某些应用程序而言,在成本方面是不可取的,但是根据图 3 的判断,这种方法也是可行的。

图 3. 在设备中使用 Android 的可能架构

使用嵌入式的方式部署 Android 为您提供了更加丰富的编程环境。您可以和以前一样继续监视湿度、温度和功率消耗特征,同时还可以观察到记录音频、视频和振动。您将拥有一个微报警、访问控 制系统,以及一个环节监控工具。由于 Android 已经可以实现联网,您不需要使用控制器 PC 就可以实现监控并与网络直接对话。

这种方法还为现场更新软件提供了额外的好处。假设您希望为监控软件添加新的特性(或修复 bug)。如果使用传统的微控制器方法,那么任务执行起来将十分繁琐并且代价昂贵,甚至根本不可能实现。而对于 Android 而言,您可以获得更整洁的部署模型并拥有更好的灵活性。

Android 如今主要运行在移动手机中,但是它已经被移植到 NetBooks 和其他平台上。希望本文为您提供了一些好的思考内容。我现在该去运行我的系统了。您永远也不会知道下一次热水器漏水会在什么时候发生。

回页首

结束语

在本文中,我们大体介绍了 Android 的联网功能。您了解了一些自己可以创建的样例应用程序,包括与 Web 服务器交互和发送文本消息。您看到了如何将 Android 连接到一个真实的环境监控系统。通过代码示例,您了解到应该在什么时候将 Android 扩展到一些特殊应用程序中,比如嵌入式控制器。

请继续关注我的下一篇文章,它将介绍如何使用基于 Android 的电话构建一个婴儿监控系统。

回页首

下载

描述 名字 大小 下载方法
GetWebPage 源代码 os-android-networking_GetWebPage.zip 14KB HTTP

关于下载方法的信息

参考资料

学习

  • 阅读 “用 Eclipse 开发 Android 应用程序”。
  • Android developers 站点 提供文档、下载、博客等众多内容。
  • 了解 Android 的赞助商 Open Handset Alliance,它是由 47 家技术和移动公司组成的组织,致力于加速移动平台的创新,并为客户提供丰富的、廉价的、出色的移动体验。
  • 深入 分析 Unlocking Android。
  • 进一步了解 Dalvik Virtual Machine。
  • 查看 YouTube 上面的 教程,它们讨论了 Dalvik VM 的内部细节。
  • Unlocking Android: A Developer's Guide 提供关于 Android 操作系统和开发工具的简要动手指导。
  • 要收听针对软件开发人员的有趣访谈和讨论,请查看 developerWorks podcasts。
  • 随时关注 developerWorks 技术活动和网络广播。
  • 查阅最近将在全球举办的面向 IBM 开放源码开发人员的研讨会、交易展览、网络广播和其他 活动。
  • 访问 developerWorks Open source 专区,获得丰富的 how-to 信息、工具和项目更新,帮助您用开放源码技术进行开发,并与 IBM 产品结合使用。
  • 查看免费的 developerWorks 演示中心,观看并了解 IBM 及开源技术和产品功能。

获得产品和技术

  • 下载 Android SDK。
  • 下载 最新的 Eclipse IDE。
  • 使用 IBM 试用软件 改进您的下一个开发项目,这些软件可以通过下载获得。
  • 下载 IBM 产品评估试用软件 或 IBM SOA Sandbox for Reuse,并开始使用来自 DB2®、Lotus®、Rational®、Tivoli® 和 WebSphere® 的应用程序开发工具和中间件产品。

讨论

  • 参与 developerWorks blogs 并加入 developerWorks 社区。

关于作者

Frank Ableson 是新泽西州北部的一名企业家和软件开发人员,擅长开发移动和嵌入式应用程序软件。他目前正在为 Manning Publications 撰写一本关于 Android 应用程序开发的图书。他感兴趣的专业领域包括嵌入式系统、无线通信和汽车电子。他最大的支持者就是他的妻子 Nikki 和他们的孩子。

转载于:https://www.cnblogs.com/shihao/archive/2012/01/05/2313360.html

使用 Android 实现联网相关推荐

  1. Android 获取联网的IP地址

    这个方法需要先判断当前应用是否联网 联网判断的方法,请查看 首先你需要确保配置文件应添加了联网的权限 如果没有下面的直接的赋值过去即可 <uses-permission android:name ...

  2. android之联网Nohttp

    使用场景: 联网 在App的build.gradle中添加引用: //网络框架 compile 'com.yanzhenjie.nohttp:nohttp:1.1.1' 在application中重写 ...

  3. qt android程序联网死机,Qt for Android(九) ——APP 崩溃卡死拉起保活实战

    这篇文章要基于前面的基础,我们才能继续下面的内容,建议阅读. 背景 首先,本文的案例环境基于一些特殊的 android 设备,比如瑞星微的RK系列,在该设备上不会熄屏,没有锁屏键,运行的应用也仅限于几 ...

  4. qt android程序联网死机,qt android开发出现致命错误

    启动远端进程.D/dalvikvm( 1387): Late-enabling CheckJNI D/dalvikvm( 1387): GC_CONCURRENT freed 256K, 10% fr ...

  5. 树莓派4B与Android之缘——树莓派下LineageOS(Android 9)系统开机联网与远程控制

    一.树莓派连接屏幕 1.找到树莓派的micro hdmi口,是视频图像的输出口,见下图中的MICRO HDMI PORTS 2.连接屏幕 (1)如果显示屏输入端口是HDMI,就用micro HDMI到 ...

  6. Eclipse安装Android开发环境

    1.安装JDK6和Eclipse3.6: 2.下载Android SDK并安装:http://developer.android.com/sdk/index.html 3.Eclipse上部署Andr ...

  7. Android杂谈--通过DDMS实现电脑与Android设备(如手机,平板)的网络连接、截图...

    我们可以通过DDMS来截取通过USB数据线连接到电脑上的Android设备图片,因为Android设备联网也是有一个ip的,所以可以通过wifi来实现电脑和Andorid 设备的联通. 需要将Andr ...

  8. android 各类demo链接

    http://gundumw100.iteye.com/blog/940084 带磁性的悬浮窗体,类似于360绿色小人  主要实现的是:  1.悬浮所有窗体之上  2.有吸引力,吸附于屏幕边上  3. ...

  9. android代码精华 各路大神写的代码精华,大家一起分享

    http://blog.csdn.net/kan1kan5/article/details/41960259 http://gundumw100.iteye.com/blog/940084 带磁性的悬 ...

最新文章

  1. 收藏版超全机器学习资料合集
  2. mysql 必须安装php_非root模式下安装mysql php小记
  3. Unity镜子效果的实现(无需镜子Shader)
  4. Nginx开启gzip压缩解决react打包文件过大
  5. js中document.getElementById(ID)与document.getElementsByName(Name)的区别
  6. 多云世界中的SD-WAN—Vecloud
  7. SAP gateway standard mode和compatible mode的区别
  8. linux目录操作函数
  9. python后端开发web_最简易的python web框架的后端实现
  10. Linux vector最大存储数量,C++ STL vector容量(capacity)和大小(size)的区别
  11. 3月第1周网络安全报告:发现放马站点域名仍为162个
  12. 蚂蚁集团SOFAStack:新一代分布式云PaaS平台,打造企业上云新体验
  13. 未来已来!分布式数据库的“星辰大海”绝不仅限于替换!
  14. split函数python 未定义_实现python 的split函数
  15. 台湾省谷歌高清卫星地图下载
  16. 自动量化炒股软件是什么?
  17. tomcat启动过程报the JDBC Driver has been forcibly unregistered问题的修复的一种方法
  18. wifi共享代码实践java_笔记本实现共享wifi上网
  19. 元白:欲买桂花同载酒,终不似,少年游。
  20. python版本回退

热门文章

  1. 「基本功」不可不说的Java“锁”事
  2. 自学架构设计的一个好方法
  3. 罗辑思维首席架构师:Go微服务改造实践
  4. 干货 | 解决分布式场景下数据一致性问题,我有办法!
  5. 工作是属于公司的,而职业生涯却是属于你自己的
  6. 从Java视角理解CPU上下文切换(Context Switch)
  7. Shell 变量的作用域
  8. 自定义注解和拦截器,实现接口限流防刷
  9. 25.C++:最通俗的讲解,什么是面向过程?什么是面向对象?
  10. 菲律宾达沃照明和电力公司的数据中心发生火灾