使用 Android 实现联网
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、數據傳遞以及應用程序中使用的與網絡有關的類。所有與網絡相關的代碼出現在 OnClickListener 的 OnClick 方法中。在選擇 圖 1 所示的標簽為 go! 的按鈕之后調用這些代碼。
URL 和 URLConnection 類共同提供與用戶所選的 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 方法。參數為:
接收者的手機號不管是連接到 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 实现联网的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: js代码收集(1)_隐藏div、tabl
- 下一篇: Android的Menu状态动态设置方法