|
Android 联网功能
Android 基于 Linux? 内核,包含一组优秀的联网功能。如果尚未安装 Android SDK,那么需要 下载 它才能实践本文的示例。
表展示了 Android SDK 中一些与网络有关的包。
表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 页面发送文本。可以 下载 本例的源代码。图展示了应用程序的实际使用。
共有三个 UI 元素:
EditText 让用户能够进入一个 Web 页面。
使用一个按钮告诉程序取回 Web 页面文本。
检索回数据后,它将显示在 TextView 中。
java代码:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
androidrientation="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>
清单GetWebPage.java
java代码: package eoe.demo;
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、数据传递以及应用程序中使用的与网络有关的类。所有与网络相关的代码出现在 OnClickListener 的 OnClick 方法中。在选择图所示的标签为 go! 的按钮之后调用这些代码。
URL 和 URLConnection 类共同提供与用户所选的 Web 站点的连接。BufferedReader 的一个实例负责从 Web 站点连接中读取传入的数据。每读取一行代码,文本就被附加到一个 TextView。数据并没有直接指定给 TextView。我们引入了一种设计模式,即创建一个消息对象并将该对象发送到一个处理程序的实例。这是更新 UI 的一种比较可取的方法,对可能需要同时运行多个线程的应用程序而言尤其如此。
在示例中,Android 应用程序与 HTTP Web 服务器进行通信,比如 Apache 或 Internet Information Server(IIS 位于 Microsoft? 服务器上)。如果应用程序直接与 TCP socket 对话,那么您将以不同的方式实现应用程序。清单所示的代码片段展示了另一种与远程服务器交互的方式。这个清单被实现为一个单独的线程。
清单Daytime 客户机
java代码:
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 并执行后续处理。与 清单不同,这个例子并没有与 HTTP 服务器通信,因此没有使用 URLConnection 类。相反,使用了较低级的 Socket 类在端口 13 打开与远程服务器的基于流的 socket 连接。端口 13 是典型的 “Daytime Server” 应用程序。
Daytime Server 接受传入的 socket 连接并以文本的形式将日期和时间发送给调用 socket。一旦发送完数据,服务器将关闭 socket。示例也展示了 InputStreamReader 的使用和一个特定字符编码。
清单发送一条文本消息
java代码:
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 值。 |
|