於Android智慧型手機以近場通訊啟用藍芽資料傳輸之研究
全文
(2)
(3) 摘 要 於 Android 智慧型手機以近場通訊啟用藍芽資料傳輸之研究 余瀧濱 藍芽技術從 1999 年推出後,雖有短距離高速資料傳輸的功能,但其設 定步驟之繁複,儘管智慧型手機配備了藍芽技術,但仍使許多不黯科技產品 的使用者仍視為畏途。自從 2010 年 Google 推出首支內建近場通訊(NFC)的 Android 智慧型手機 Nexus S 後,其簡單與易用特性,使近場通訊的應用與相 關的研究如雨後春筍般地被推出。近場通訊技術除了資料傳輸之外,也可以 透過控制指令的傳送來取代藍芽技術的前置動作,降低操作的複雜度,藉以 增加該通訊技術的使用性。如何利用 NFC 來擴充與改善藍芽的技術應用為重 要課題。 本研究提出以近場通訊的點對點模式,啟用藍芽的連線與資料傳輸,可 節省設定時間,且使用者不必具有連線先備知識。因應官方 SDK 無提供藍 芽傳輸檔案的狀況,本研究發展出文字基底的傳輸檔案模組,進一步比較點 對點模式與藍芽傳輸檔案的時間,結果顯示,在小於 4KB 時,使用點對點模 式較省時,成為兩種技術的分水嶺。我們依據所發展出來的模組,開發出三 項應用:孩童走失警示、繪圖接龍、翻牌遊戲。孩童走失警示系統可以偵測 小孩是否距離超過藍芽連線距離,超出則響鈴提醒。繪圖接龍為兩人開啟藍 芽連線,用接力的方式完成圖畫和紙筆遊戲,翻牌遊戲則是玩法類似記憶遊 戲,並利用藍芽即時同步遊戲的狀態。. 關鍵字:Android、NFC、藍芽、近場通訊. i.
(4) ABSTRACT A study on NFC-activated Bluetooth data transmission over Android smart phones. by. Long - Bin Yu Bluetooth technology was proposed in 1999. Although it can transmit in high speed within short range, nevertheless the setting procedure is complicated for users. Since Google launched the first near-field-communication (NFC) smartphones on the Android platform, the simplicity and friendly design of its user-interface makes related applications sprang up like mushrooms. NFC provides data transmission between smartphones. Beside. data transmission,. NFC. also. can. activate. Bluetooth. communication between two smartphones by tapping the back of these two smartphones, which can reduce the complexity of Bluetooth setting procedure. In this thesis, we develop a system which can set up Bluetooth transition automatically by using NFC P2P mode. To cope with the problem that official SDK doesn’t provide the method of transfer files by Bluetooth, we design a text-based file transfer module. Further, we compare our module with NFC P2P mode, the result shows that 4 KB is a crossover point between NFC and Bluetooth. If file size of the data transmission is less than 4KB, then NFC provides better performance; if file size is greater than 4KB, then Bluetooth provides better performance. We also developed three applications which are based on our NFC activated transmission modules, they are “Child Guard”, “Draw Together”, and “NFC memory game”. “Child Guard” is a Bluetooth-based parent assisted software which can warn parents when their child stays in the distance more than Bluetooth reachable distance. “Draw Together” provide two users take turns to draw pictures on their smartphones. “NFC memory game” is the same as classic poker game, which matches colors in the poker cards, but the game state is synchronous using Bluetooth communication. Keywords:Android、Bluetooth、Near-field-communication、NFC. ii.
(5) 誌. 謝. 時間過得很快,研究所的生活即將結束,很感謝葉耀明老師對我一直以來的 提攜,讓我參與了許多計畫,接觸了許多面向,累積豐富的實務經驗,並且在課 業上有困擾時都給予許多的協助,進實驗室後,學長們也不吝給予指導,讓我們 能盡快步上軌道,感謝欣培、謹至、冠廷、培然、名鈺、建廷、國隆、尚儒、威 傑、汝怡學長姐們。在課業上,同學們的幫忙不可或缺,常常一起討論、寫程式, 在有困難時也都及時伸手幫忙,感謝冠緯、惠迪、孝倫、慶瑞、芝華、永倫、明 憲、韋德同學們。最後是實驗室的新星們,感謝有你們的加入,讓 XML 實驗室 能永續傳承,感謝皓中、志忠、昱賢、隘同、文寬、哲維、書銘、禮衛。 研究所的這段時間,父母讓我衣食無憂,可以專心完成學業,對你們的感謝, 千言萬語也說不盡,並且也感謝我的好朋友們,當我面對困難時,給予支持和鼓 勵,使我堅持下去。另外,相當感謝東華大學蔡正雄和黃振榮教授,因你們的教 導,讓我熱愛這門學科,奠定了基礎實力,也順利推甄上研究所,繼續深造,尤 其是蔡正雄教授,您在課堂上所說過的話,給予我很大的啟發。. 余瀧濱 謹誌 國立台灣師範大學 資訊工程研究所 民國 101 年 6 月. iii.
(6) 目 錄 附圖目錄 附表目錄 程式碼目錄. vii viii ix. 第1章 1.1 1.2 1.3 第2章. 緒論............................................................................................................. 1 研究背景及動機......................................................................................... 1 研究目的..................................................................................................... 2 論文架構..................................................................................................... 3 文獻探討..................................................................................................... 4. 2.1 2.2. 近場通訊(Near Field Communication,NFC) .......................................... 4 Android 作業系統 ...................................................................................... 5 2.2.1 Android 系統架構 .............................................................................. 5. 2.2.2 四大組件............................................................................................. 6 2.3 藍芽(Bluetooth) .......................................................................................... 7 2.3.1 網路架構............................................................................................. 8 2.3.2 藍芽的連接狀態............................................................................... 10 2.3.3 跳頻展頻(frequency-hopping spread spectrum, FHSS) ................... 11 2.3.4 藍芽與近場通訊的比較................................................................... 12 第3章 系統規劃................................................................................................... 14 3.1 3.2 3.3 3.4 3.5 3.6 3.7 第4章. 系統架構................................................................................................... 15 藍芽連線實作與比較............................................................................... 17 藍芽傳輸文字實作部分........................................................................... 23 藍芽檔案傳輸實作部分........................................................................... 24 藍芽檔案傳輸測試部分........................................................................... 31 NFC P2P 傳輸模式 .................................................................................. 34 NFC 與藍芽傳輸的比較 .......................................................................... 36 系統應用................................................................................................... 38. 4.1 4.2 4.3. Child Guard ............................................................................................... 38 Draw Together........................................................................................... 40 翻牌遊戲................................................................................................... 44. 4.4 模組整合說明........................................................................................... 45 第5章 結論與未來發展....................................................................................... 49 5.1 結論........................................................................................................... 49 5.2 未來發展................................................................................................... 50 參考著作....................................................................................................................... 51 附錄............................................................................................................................... 53 iv.
(7) 附錄 A.. 系統第一層與第二層 class diagram ................................................ 53. 附錄 B. 附錄 C. 附錄 D.. 系統係二層與第三層 class diagram〈一〉 .................................... 54 系統第二層與第三層 class diagram〈二〉 .................................... 55 連線程式 nfc_btActivity.java ........................................................... 56. v.
(8) 附圖目錄 圖 圖 圖 圖 圖 圖 圖 圖 圖. 2.1 ANDROID 作業系統結構圖(圖片來源 ANDROID DEVELOPERS) ......................... 6 2.2 微網 ..................................................................................................................... 9 2.3 散網 ..................................................................................................................... 9 2.4 跳頻示意圖 ....................................................................................................... 11 3.1 傳統藍芽連線方式,CLIENT 端 ...................................................................... 14 3.2 傳統藍芽連線方式,SERVER 端 ...................................................................... 14 3.3 簡化後的藍芽連線方式 ................................................................................... 14 3.4 系統架構圖 ....................................................................................................... 16 3.5 要求開啟藍芽 ................................................................................................... 17. 圖 圖 圖 圖 圖 圖 圖 圖 圖 圖. 3.6 首先開啟選單,接著 SERVER 端要讓自己可被偵測 ..................................... 20 3.7CLIENT 端需要先瀏覽以配對的裝置,若無,則搜尋裝置 ........................... 21 3.8 點擊裝置後連線完成 ....................................................................................... 21 3.9 提示使用者動作,接觸後顯示連線中的訊息,其中 CLIENT 會跳出 SATE_CONNECTING,SERVER 則是 STATE_LISTEN ................................... 22 3.10 連線完成後,藍芽部分的功能才會顯示出來 ............................................. 22 3.11 藍芽聊天介面 ................................................................................................. 24 3.12 STRING 型態與 STRINGBUFFER 型態的比較 .................................................. 26 3.13 檔案傳送流程 ................................................................................................. 29 3.14 藍芽檔案傳輸介面(1) .................................................................................... 30 3.15 藍芽檔案傳輸介面(2) .................................................................................... 30. 圖 圖 圖 圖 圖 圖 圖 圖 圖 圖. 3.16 10KB 以下檔案傳輸 ....................................................................................... 32 3.17 25~500KB 檔案傳輸 ...................................................................................... 32 3.18 500KB~2MB 檔案傳輸 .................................................................................. 33 3.19 依照使用者經驗所繪製的圖表 ..................................................................... 34 3.20 NFC P2P 模式檔案傳輸介面─接收端 ......................................................... 35 3.21 NFC P2P 模式檔案傳輸介面─傳送端 ......................................................... 35 3.22 NFC P2P 傳輸測試 ......................................................................................... 36 3.23 NFC P2P 與藍芽實際時間比較 ..................................................................... 37 4.1 CHILD GUARD 程式介面.................................................................................... 39 4.2 DRAW TOGETHER 程式介面............................................................................... 41. 圖 4.3 使用 NFC 標籤所構成的遊戲平台 ................................................................. 44 圖 4.4 翻牌遊戲介面 ................................................................................................... 45. vi.
(9) 附表目錄 表 表 表 表. 2.1 跳頻表,記錄著每個頻帶的使用狀態、頻帶編號和封包丟失機率 ........... 12 2.2 藍芽與近場通訊比較表 ................................................................................... 13 3.1 連線時間分佈表 ............................................................................................... 20 3.2 各類型標頭及旗標格式 ................................................................................... 25. vii.
(10) 程式碼目錄 程式碼 程式碼 程式碼 程式碼 程式碼 程式碼 程式碼 程式碼. 3.1 將本機藍芽 MAC 以 NFC P2P 傳輸 ....................................................... 18 3.2 決定 SERVER 端 ......................................................................................... 19 3.3 針對不同腳色連線 ................................................................................... 19 3.4 從緩衝區中接收到資料時,便發送通知給第二層 ............................... 23 3.5 傳送資料時,也會發送通知給第二層 ................................................... 24 3.6 傳送檔案時,先將檔案編碼,並發送 FILE_START 訊息 ....................... 26 3.7 傳送端根據不同的 ACK 訊息的對應動作............................................. 27 3.8 接收端的對應動作 ................................................................................... 29. 程式碼 程式碼 程式碼 程式碼 程式碼 程式碼. 4.1 在斷線即呼叫時播放音效 ....................................................................... 40 4.2 先判斷本機是否為 SERVER,若是則允許編輯...................................... 41 4.3 換人的按鈕功能實作 ............................................................................... 42 4.4 等待方接收到檔案後的動作 ................................................................... 42 4.5 移動時,使用矩形繪畫軌跡 ................................................................... 43 4.6 選擇顏色按鈕功能實作 ........................................................................... 44. viii.
(11) 第1章. 緒論. 1.1 研究背景及動機 在智慧型手機普及的現代,人們的生活因為手機而比以往更加方便,手機的 功能越來越多樣化,配合無線網路與 3G 網路的使用,讓手機隨時可以存取網際 網路,結合了更多的雲端服務,然而隨著手機功能日漸多樣化,不同手機軟體的 選擇步驟也變得複雜,受限於手機先天的介面限制,在操作某些設定時並不順手, 同時也耗費時間。在 2010 年 Google 推出第一款包含近場通訊(Near Field Communication,NFC)的智慧型手機 Nexus S 後,藉由 NFC 的技術,不只能讓手 機存取 RFID 標籤與 NFC 標籤,還能進一步地互相傳送簡單的資料,不需要繁複 的設定,只需要輕輕的接觸即可,融合智慧型手機與無線網路的功能,讓手機擁 有更多的可能。 由於目前智慧型手機大多已同時具有多種通訊技術,像是藍芽、Wi-Fi…等, 因此若是結合近場通訊技術,能簡化設定其他長距離通訊技術的過程,在 NFC Forum 所出版的白皮書 ECMA International NFC White Paper 中,提到使用近場通 訊去啟用其他長距離的通訊技術的概念[1],另外亦有人提出近場通訊配合智慧型 手機取得遠端資料與控制遠端裝置的概念[2]。 目前在 Android 上的藍芽應用如下: . 將官方的 Bluetooth Chat 範例修改為一對多的聊天室[3]. . 用藍芽來傳輸感應器的資料,可讓 A 手機上的感應器資料顯示在 B 手機. 1.
(12) 或平板上[4] . 智慧計步器,目標達到時以藍芽傳到耳機提醒[5]. . 居家安全,透過藍芽開鎖門,檢查開鎖狀態[6]. . 雙人遊戲,藉由藍芽來連線進行[7]. 但連線方式都還是使用傳統的步驟,並無結合其他或改良。在藍芽與 NFC 結合的部分,都是以硬體為主,藉由藍芽連線輔助沒有 NFC 的手機,像是 NFC 藍牙橋接器系統[8],讓舊型 j2me 平台手機可以使用 NFC 功能,中華電信也在 2010 年 10 月推出“花珀”[9],可讓無 NFC 的 Android 手機透過該 Dongle 讀取花博會 場的 NFC 標籤。. 1.2 研究目的 本研究提出一種藉由近場通訊技術去快速啟用並且設定好藍芽的服務,傳統 的設定方式常讓使用者困擾和費時,並且這些設定會因為對象不同而需要重新設 定,讓藍芽的使用率不高。因此若能藉由近場通訊的 Peer-to-Peer 方式,快速幫 使用者設定好藍芽的連線,不僅能減少許多時間,也讓不清楚連線流程的使用者 操作簡單許多。 另外也在允許快速連線的情況下,提供一些以藍芽為基礎的互動應用,讓使 用者能夠真正享受藍芽所帶來的便利與樂趣。進一步發展出可以讓其他開發者使 用的 NFC 藍芽連線模組,推廣 NFC 的簡單易用性。. 2.
(13) 1.3 論文架構 本論文一共分為五個章節,各章節內容描述如下: 第一章. 緒論 介紹研究背景和動機、研究目的和論文架構. 第二章. 文獻探討 介紹使用到的技術,包含近場通訊、Android、藍芽。. 第三章. 系統架構 介紹本文系統如何運作,與說明其原理。. 第四章. 系統應用 根據所發展出來的系統,做出相對應的應用。. 第五章. 結論與未來發展 介紹本研究的結論,並進一步討論未來可以發展的空間與方向。. 3.
(14) 第2章. 文獻探討. 2.1 近場通訊(Near Field Communication,NFC) 現在手機的普及程度已經相當的高,因此如果讓手機不只是用來打電話,而 能更進一步的使用日常生活的服務,利用近場通訊取代目前使用的許多卡片,例 如:信用卡、集點卡、悠遊卡等等,亦能讓手機與手機互相傳輸資料,和隨時從 路邊的海報取得更多相關資訊,其應用分為以下五種類型[10]:(1)接觸通過(2) 接觸支付(3)接觸連接(4)接觸瀏覽(5)下載接觸,這些對使用者都有很大 的吸引力,而近場通訊讓這一切都成為可能。 近場通訊的目標並非取代其他的通訊技術,而是要在不同的場合和領域做到 互補的作用。近場通訊是基於 RFID,距離短的高頻無線通訊技術,用 13.56MHz 的頻率在 20 公分內運行,其傳輸速度有三種,分別是 106Kbit/s、212Kbit/s、 424Kbit/s,允許非接觸式的傳輸資料,距離約 10 公分(3.9 英吋內),其通訊模式 分為以下三種: 1.卡片模式(card emulation):在此模式中,手機會被當作是一般的 RFID 技術 的卡片,可以替代目前使用的信用卡、門禁管制卡、車票、門票等等,並且在此 模式下,因為是被動的被讀取,因此不需要耗費手機的電量,即使在沒電狀態下 也可以使用。 2.點對點模式(P2P):此模式時紅外線傳輸類似,除了用於資料傳輸交換,建 立傳輸上有速度快,功耗低的優點,也可用於傳輸圖片、音樂、同步聯絡人等資. 4.
(15) 訊,另外也可以用來建立不同裝置間的連線的小動作(micro-interaction)[11]。 3.讀卡器模式(Reader/writer mode):作為讀卡器使用,可以讀寫 NFC 標籤。. 2.2 Android 作業系統 2007 年 11 月,Google 與許多軟硬體供應商、手機晶片供應商、電信業者 聯合組成開放手持裝置聯盟(Open Handset Alliance),發佈了名為「Android」的 開放手機軟硬體平台,參與開放手持裝置聯盟的這些廠商,台灣也有 ACER、 ASUS、HTC 與 Garmin 等公司加入其中,它們都會基於 Android 平台,來開發 新的手機業務。 Android 是完全免費的手機作業系統,其競爭對手為 Nokia 的 Symbian OS、 蘋果電腦的 iOS、微軟的 Windows Phone 及 RIM 使用的 BlackBerry OS 等手機作 業系統,它的特點如下: . 完整的 Eclipse 開發環境,包括模擬器、除錯工具. . 整合 WebKit,並且可以支援 Flash,於 4.0 版更完整支援 HTML5. . 內置 SQLite 關聯式資料庫. . 應用程式的框架提供了類似 MVC 架構的分層,有利於重複使用開發元 件. . 硬體支援相關的包含相機、GPS、電子羅盤與三軸加速器. . 多媒體支援包含 MPEG4、H.264、MP3、AAC、AMR、JPG、PNG、 GIF 等眾多格式. . 通訊技術的支援包含 GSM/EDGE、IDEN、CDMA、EV-DO、UMTS、 Bluetooth、Wi-Fi、LTE、NFC 和 WiMAX. 2.2.1. Android 系統架構. Android 架構是由應用程式(Application)、應用程式框架(Application. 5.
(16) Framework)、函式庫(Libraries)、Android 執行作業環境(Android Runtime)與 Linux 核心(Linux Kernel)所組成的,結構如圖 2.1,藍色部分為應用程式,綠色及黃色 部分為中介軟體,紅色部分為操作系统。. 圖 2.1 Android 作業系統結構圖(圖片來源 Android Developers) Android 有以下優點[12][13][14]: . 高系統開放性:Android 是基於 Linux 的作業系統,Linux 的特性就是 高度的開放性。. . 跨平台和可移植性:Android 是使用 java 語言來撰寫的,java 具有高度 的可移植性,讓 Android 在不同平台中皆可執行。. 2.2.2 . 四大組件 機動程式(Activity) 讓使用者與應用程式互動的介面,當用戶切換到其他 Activity 時,. 原本的 Activity 會進入暫停狀態,其生命週期有 onCreate、onStart、. 6.
(17) onResume、onPause、onStop、onDestroy、onRestart。 . 服務程式(Service) 在後台運行的程式,並沒有介面,若沒有被關閉,可以長時間運 行,相當於後台的服務,Activity 可以 bind 服務程式,調用服務程式的 函式,並且當 Activity 暫停時,服務程式仍會繼續進行,例如撥放音樂。. . 廣播接收(Broadcast Receivers) Broadcast 是不同應用程式傳輸訊息的方式,Broadcast Receivers 可 以用來接收 Broadcast,並且根據不同的事件執行不同的處理,或是通 知使用者一些訊息。. . 資料內容提供(Content Providers) 用來提取資料,也可以透過他來將自己的資料給外部調用,給第三 方應用提供存取資料的頁面,Android 為常見的資料類型訂定了不同的 Content Providers,取得權限後,可以在自行開發的程式中使用這些 Content Providers。. 2.3 藍芽(Bluetooth) 藍芽為一種低功耗的無線個人區域網路,使用 2.4GHz 的頻寬,用來連接不 同功能的設備所設計,例如:筆記型電腦、相機、印表機、耳機、電話…等等, 最初為 Ericsson 公司的一項專案計畫,於 1999 年由 Intel、Nokia、Toshiba 等公 司組成「特別興趣小組」(Special Internet Group, SIG),使藍芽成為業界的共同標. 7.
(18) 準。他的應用範圍如下: . 行動電話與免持裝置之間的無線通訊. . 特定距離內電腦間的無線網路. . 電腦與其他周邊設備的通訊,例如:滑鼠、耳麥、印表機等. . 藍芽設備之間的文件資料傳輸. . 傳統有線設備無線化. . 異質網路之間的橋樑. 2.3.1. 網路架構. 藍芽有兩種網路類型,分別是微網(piconet)與散網(scatternet),微網有以下特 點: . 1 個 server,其他為 client,最多可有 7 個 client. . 所有 client 的時鐘和跳躍序列和 server 同步. 除了 7 個 client,還可以另外有 8 個處於停放狀態的裝置,他們與 server 同步, 但不參與通訊,見圖 2.2。. 8.
(19) 圖 2.2 微網 而散網則是由微網組成,微網的 client 可以進一步成為另一個微網的 server, 將兩個微網連繫起來,使兩個微得以互相通訊,如圖 2.3。. 圖 2.3 散網. 9.
(20) 藍芽的連接狀態. 2.3.2. 藍芽在不同的連線情況下,會有不同的狀態去對應,以節省耗設備的電量, 共有 Active、Sniff、Hold、Park 四種狀態,以下介紹每種狀態的特性,並依照 消耗功率的高低作排序[15]。 a.. Active 當藍芽設備相互通訊時,便是在此狀態,會持續與其他藍芽設備傳送查 詢(Inquiry)和呼叫(Paging)的訊號。在微網(Piconet)中可容納 7 個 Active 的 Slave 與 256 個 Park 狀態的藍芽裝置。. b.. Sniff 與 Active 狀態類似,但在此狀態,藍芽為了節省耗電量會延長訊號發 送的間隔時間並且在 Slave 時,會延長跳頻序列上的間隔來接收 Master 的訊號。. c.. Hold 進入此狀態後,會暫時停止(Hold)支援 ACL 連線,但仍可以進行 SOC 連線。所以不會占用到實體通道的時槽,能提高藍芽網路運行的效率。. d.. Park. 當 Slave 不用傳輸資料時,就會進入 Park 狀態,等待 Master 傳送喚醒的訊 號時便會回到 Active 狀態。Master 會有周期性的廣播訊號,而當 PM-ADDR 位 址指定某 Park 狀態的 Slave 時,該 Slave 便轉換到 Active 狀態。 10.
(21) 2.3.3. 跳頻展頻(frequency-hopping spread spectrum,. FHSS) 藍芽為了避免與其他網路的干擾,尤其是同為 2.4GHz 頻帶的,例如:WiFi, 所以在每秒改變頻率 1600 次,並記錄每個頻率的狀態(見圖 2.4、表 2.1),將頻 帶分成數 79 段,每個頻帶為 1MHz,2402~2480MHz,每次以虛構隨機樹決定跳躍 頻道順序,這樣做相當的有效,大大的減少了網路的延遲[16],除了對抗干擾, 同時也增加了竊聽的困難度,進而更有安全性。. 圖 2.4 跳頻示意圖. 11.
(22) 表 2.1 跳頻表,記錄著每個頻帶的使用狀態、頻帶編號和封包丟失機率 Status. Frequency Offset. Pr[PLoss]. good. 0. 10−3. good. 1. 10−4. good. 2. 10−3. …. 2.3.4. bad. 76. 1. bad. 77. 0.5. bad. 78. 0.85. 藍芽與近場通訊的比較. 表 2.2 為藍芽與近場通訊的比較,兩者主要的差異有,前者為一對多的個人 區域網路,後者則為點對點的網路,距離上也有顯著的 10 公尺與 20 公分的差別, 速率上亦有所不同,相差近 4 倍。 最後則是本研究所討論的重點,設定程式的時間,雖然表上列出小於 6 秒, 但實際上使用者的操作常會遠大於此時間,相對於近場通訊小於 0.1 秒,有相當 的落差。. 12.
(23) 表 2.2 藍芽與近場通訊比較表 NFC. Bluetooth. 標準. ISO 13157. IEEE 802.15.1. 網路類型. Point-to-point. Wireless Personal Area Network. 範圍. <0.2m. ~10m. 頻率. 13.56MHz. 2.4-2.5GHz. Bit rate. 424 kbit/s. 2.1Mbit/s. 設定程序. <0.1s. <6s. 13.
(24) 第3章. 系統規劃. 藍芽功能已經是手機之間必備的傳輸工具,本論文利用 NFC 技術將藍芽連 線的初始化部分加以簡化,傳統藍芽的連線流程如圖 3.1、圖 3.2 所示,而使用 本論文所提出的方法後,將連線流程簡化為圖 3.3。在連線之後,提供使用者進 行聊天的功能,並且更進一步提供用戶分享圖片、音樂、文件的檔案傳輸功能。. 搜尋裝置. 發現裝置. 配對. 建立連線. 圖 3.1 傳統藍芽連線方式,Client 端. 可被偵測. 被偵測到. 配對. 建立連線. 圖 3.2 傳統藍芽連線方式,Server 端. NFC P2P傳送連線必要資訊. 自動建立藍芽連線. 圖 3.3 簡化後的藍芽連線方式 本文系統的開發使用的智慧型手機為 Samsung Google Nexus S,其規格為 如下: . 作業系統: Android OS 2.3 Gingerbread. . 中央處理器: ARM Cortex A8 1GHz. . 記憶體: 512MB. . 容量: 16GB. 14.
(25) . 解析度: 480 x 800. . 藍芽: 2.1+EDR. 3.1 系統架構 本系統分為兩大部分,一為 NFC 與藍芽結合,而後以藍芽傳輸為主,另一 部分以 NFC P2P 模式為主,前者架構主要分為三層,最底層的 BlueToothTool 為 一類別,修改自 Android SDK[17]的 BlueTooth Chat 範例程式,主要功能為建立 與管理藍芽連線,僅支援文字傳輸,第二層 BlueTooothTransmissionService,將 第一層的類別實體化,藉由不同的執行緒,接收當下的連線狀態,並且以文字傳 輸為基礎,實作檔案傳輸與即時狀況的反應,檔案傳輸的方式主要使用 Base64 來編碼成字串,再配合自訂簡易協定,來實現基於文字的傳輸方式。 由於 Android 的 Activity 並無法將連線狀態相互傳遞,因此第二層部分寫成 Android 的 Service 程式,其目的是可在背景執行,不受使用者當前畫面執行其他 程式影響,例如: 使用者從網路下載東西,切換到其他程式時,會立即中斷程式 並斷線,而使用 Service 程式的話,下載仍會繼續,並可設定下載完成後通知使 用者。 第三層就是各種的應用,藉由第二層所提供的功能,與狀態的即時回饋,便 可發展出許多應用,像是藍芽聊天程式、藍芽檔案傳輸、小孩距離看守、共享畫 板等等,而 nfv_btAcitivity 為本系統的首頁,在此頁使用 NFC 進行藍芽連線, 在連線後,顯示功能選單。. 15.
(26) 其中,第二層與第三層的通訊,分為兩種,一種是使用 ServiceConnection, 可以取得目前第二層的執行狀態與執行函式,但是並不是即時的,若要即時的話, 則要用另一種,第二層發出 Broadcast,第三層使用 BroadcastReceiver 接收 Broadcast,如此當第二層有狀態變化或事件時,可即時的讓第三層知道,並在介 面上做顯示。 除了藍芽以外,系統還有第二部份,主要是 NFC Peer-to-Peer 模式,實作用 P2P 來傳送檔案,因為 P2P 模式也是使用文字傳輸,所以也是使用 Base64 的方 式對檔案編碼,傳送後再解碼。. 圖 3.4 系統架構圖. 16.
(27) 3.2 藍芽連線實作與比較 進入本系統時,會在第三層預先檢查手機藍芽功能是否開啟,如圖 3.5,若 否則跳出開啟對話窗,之後取得將本機的藍芽 MAC,將其包裝成 NDEF[18]資料 格式,並指定其類別為 RTD[19]中的 text 格式,之後便啟用前景偵測模式,系統 隨時偵測對方是否靠近感應,若偵測到便將本機的藍芽 MAC address 傳送給對方, 用以進行連線(程式碼 3.1)。. 圖 3.5 要求開啟藍芽 if(mBluetoothAdapter.isEnabled()) { //push nfc message NfcManager manager = (NfcManager) getSystemService(NFC_SERVICE); //抓取藍芽的 MAC Address String btMac = mBluetoothAdapter.getAddress(); //包裝成 NDEF 格式與選擇類型 NdefRecord rec = new NdefRecord(NdefRecord.TNF_WELL_KNOWN, 17.
(28) NdefRecord.RTD_TEXT , new byte[0],btMac.getBytes()); /*要支援 push, 只需要在 onResume 時使用 enableForegroundNdefPush 就可 以了*/ manager.getDefaultAdapter().enableForegroundNdefPush(this, new NdefMessage(new NdefRecord[]{rec})); //get nfc message IntentFilter ndef = new IntentFilter(NfcAdapter.ACTION_NDEF_DISCOVERED); try { ndef.addDataType("*/*"); } catch (MalformedMimeTypeException e) { throw new RuntimeException("fail", e); } manager.getDefaultAdapter().enableForegroundDispatch(this, PendingIntent.getActivity(this, 0,new Intent(this, getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), 0), new IntentFilter[] {ndef, }, new String[][] { new String[] { NfcF.class.getName() } }); } 程式碼 3.1 將本機藍芽 MAC 以 NFC P2P 傳輸 在獲得對方的 MAC address 後,必須要有統一的機制來決定 Server 與 Client, 在此把資訊傳到第一層,會比較十六進位 MAC address 的大小,較小者為 Server, 另一端則為 Client(見程式碼 3.2),Server 端啟動一執行緒聽是否有裝置連入,而 Client 則直接對 Server 的 address 進行連線,都是在第一層的部分處理,決定好 各自的角色後,便會自動開始連線(見程式碼 3.3),不需要使用者作其他操作, 連線後會將資訊存在第一層,彼此都知道 client 與 server 的資訊。 /*比較出何者為 SERVER 另一個為 CLIENT*/ public void decideServer(String _device_1, String _device_2) { String device_1 = mac2string(_device_1); String device_2 = mac2string(_device_2); 18.
(29) long d_1; d_1 = Long.parseLong(device_1, 16); long d_2; d_2 = Long.parseLong(device_2, 16); if(d_1<d_2) { serverMac = _device_1; clientMac = _device_2; } else { serverMac = _device_2; clientMac = _device_1; } } 程式碼 3.2 決定 Server 端 /*連線*/ public void setDevice(String _device_1, String _device_2) { decideServer(_device_1,_device_2); if(personalMac == clientMac) { mDevice = mAdapter.getRemoteDevice(serverMac); this.connect(mDevice); } else { this.start(); } } 程式碼 3.3 針對不同腳色連線 在了解連線方式後,本文試著與傳統的連線方式比較,傳統的方式不但步驟 較瑣碎,同時使用者也必須具備對於藍芽連線的知識,例如未配對與已配對的差. 19.
(30) 別,為什麼一邊要讓自己可被偵測,而另一邊要發現對方裝置等等,本文所提出 的方式,以簡單的說明,引導使用者動作,亦不需要任何藍芽連線的先備知識, 傳統連線操作上隨著熟悉度的不同,造成連線的時間有所差異,我們與兩個擁有 藍芽先備知識的同學經過測試時間平均為 11.4 秒,每次掃描裝置時間長短不一 操作步驟也較多,如圖 3.6、圖 3.7、圖 3.8,而本文的方式,經過測試平均為 5.4 秒,其時間區段見表 2.1,操作步驟如圖 3.9、圖 3.10,由此可得,使用本 研究連線方法可節省 52%的時間。 表 3.1 連線時間分佈表 NFC P2P 傳送 MAC. 與 Service 程式連接. 建立藍芽連線. 1.5 秒左右. 1秒. ~3 秒. 傳統的方法(以 Bluetooth Chat 為例):. 圖 3.6 首先開啟選單,接著 Server 端要讓自己可被偵測 20.
(31) 圖 3.7Client 端需要先瀏覽以配對的裝置,若無,則搜尋裝置. 圖 3.8 點擊裝置後連線完成 接著是本文所提出的以 NFC 來進行藍芽連線:. 21.
(32) 圖 3.9 提示使用者動作,接觸後顯示連線中的訊息,其中 Client 會跳出 SATE_CONNECTING,Server 則是 STATE_LISTEN. 圖 3.10 連線完成後,藍芽部分的功能才會顯示出來 22.
(33) 由以上步驟,可以看出本文所提供的方法相當方便使用,只要互相將手機背 部的 NFC 晶片靠近即可,即使是不善於操作手機的人都可以輕鬆了解,經過實 測本文連線所需時間平均 5.4 秒,考慮到使用 NFC 時可能不方便看到螢幕所顯 示的訊息,因此在連線完成後播放音效以提醒使用者。. 3.3 藍芽傳輸文字實作部分 在第一層的 BlueToothTool 類別裡,有定義了 send 函式,用於傳輸文字給對 方,其輸入型態為 byte 陣列,主要是呼叫類別中的 ConnectedThread 執行緒,該 執行緒負責管理連線後的情況,持續的從 socket 取得串流資料,再將資料放入緩 衝區中,再監聽是否有訊息進來緩衝區(程式碼 3.4),以及傳送訊息到到緩衝區 中,在有資料進出時,第一層會藉由 Handler 傳送一個 Message 給第二層,即時 反應狀態(程式碼 3.5),程式介面見圖 3.11。 //持續聽 Inputstream 裡面的資料 while(true) { try{ bytes = mmInStream.read(buffer); mHandler.obtainMessage(MESSAGE_READ, bytes, -1, buffer).sendToTarget(); }catch(IOException e){ Log.e(TAG, "disconnected", e); connectionLost(); break; } } 程式碼 3.4 從緩衝區中接收到資料時,便發送通知給第二層 /*送出資料到 buffer 內*/ public void send(byte[] buffer) 23.
(34) { try{ mmOutStream.write(buffer); //發送通知給 Service 程式 mHandler.obtainMessage(MESSAGE_WRITE, -1, -1, buffer).sendToTarget(); }catch(IOException e){ Log.e(TAG, "Exception during write", e); } } 程式碼 3.5 傳送資料時,也會發送通知給第二層. 圖 3.11 藍芽聊天介面. 3.4 藍芽檔案傳輸實作部分 由於官方 Android SDK 在藍芽的部分只有提供文字傳輸的功能,因此本論文 提供基於文字的傳輸方式,包含傳輸檔案。首先,先測試一次傳輸所能容納的容 量為多少,經多次測試後,最大值為 1014 位元組,因此,扣掉自訂的標頭部分, 每份資料字串長度為 1001 位元組,若大於此值,接收方會在一開始接收時出現 24.
(35) 錯誤,或者接收到一半時錯誤。 為了識別不同類型的內容,所以訂定了簡單的標頭,共分為三種類型,為訊 息、微小檔案(小於 1001 位元組,可一次傳輸)、一般檔案,其中一般檔案因為 較複雜,所以又訂了不同的旗標,分別有檔案開始、檔案傳輸、檔案結束、檔案 開始收到確認、檔案傳輸收到確認,格式說明見表 3.2。 表 3.2 各類型標頭及旗標格式 類型. 內文格式. 訊息. 1,內文. 微小檔案. 2,檔名,資料. 一般檔案(file start). 3,1,檔名,檔案段數. 一般檔案(middle). 3,2,檔案段號,資料. 一般檔案(ack for middle). 3,3. 一般檔案(ack for start). 4,4. 一般檔案(over). 4,5. 小孩呼叫. 5. 當傳送端選定檔案後,便會先將檔案編碼為 base64[20]字串,若長度小於一 次傳輸限制時,便直接連同檔名與編碼字串傳送過去,若大於限制,再按照限制 長度去做切割,並發送一個 file_start 訊息給接收方(見程式碼 3.6),告知接收端 檔名與檔案切割的總段數,接收端收到後會宣告出對應長度的 StringBuffer 變數, 再回傳一個 ACK 給傳送端。 case HEAD_BIG_FILE:////這邊只負責傳出 START 訊號,其餘在接收端進行 // 檔案將轉出的碼按長度切斷 message_peice = splitByLength(getPicBASE64(filePath), fileLimitSize); filePeiceNumber = message_peice.length; sendMessage = Integer 25.
(36) .toString(HEAD_BIG_FILE) + "," + Integer.toString(FLAG_START) + "," + fileName + "," + filePeiceNumber; mBlueToothTool.send(sendMessage.getBytes()); mOutStringBuffer.setLength(0); break; 程式碼 3.6 傳送檔案時,先將檔案編碼,並發送 file_start 訊息 使用 StringBuffer 型態的原因,是因為在後續組合檔案時,必須要把字串全 部串在一起,若使 String 型態,每一次的增加字串都需要重新要求記憶體,增加 處理時間,而使用 StringBuffer 在一開始就先指定好長度,之後不斷將字串加入 時,不需耗費太多時間(見圖 3.12) ,片段接收完畢時即可馬上的組合出檔案。. 圖 3.12 String 型態與 StringBuffer 型態的比較 傳送端收到 ACK_START 後,便會接續的傳送檔案片段,接收端在接受到 該片段後,會先判斷是否回最後一個片段,若否,則回傳一個 ACK_MIDDLE,. 26.
(37) 如此重複進行,直到最後一段時,接收端便回傳 ACK_OVER 告知結束,並且組 合檔案(見程式碼 3.7、程式碼 3.8),完整的流程在圖 3.13 中說明。 case FLAG_ACK_START: //接收到開始訊號確認後,開始傳送第一個檔案片段 nowSendFilePeiceNumber = 0; sendMessage =getSendString(HEAD_BIG_FILE,FLAG_MIDDLE,nowSendFilePeiceNumber); mBlueToothTool.send(sendMessage.getBytes()); mOutStringBuffer.setLength(0); break; case FLAG_ACK_MIDDLE: //接收到檔案確認訊號以後,持續傳送後續檔案 nowSendFilePeiceNumber++; sendMessage =getSendString(HEAD_BIG_FILE,FLAG_MIDDLE,nowSendFilePeiceNumber); mBlueToothTool.send(sendMessage.getBytes()); mOutStringBuffer.setLength(0); break; case FLAG_ACK_OVER: message_peice = null; sendBroadcast(setIntent(ACTION, MESSAGE_CONTENT, "傳送完成")); break; 程式碼 3.7 傳送端根據不同的 ACK 訊息的對應動作 case FLAG_START: ackMessage = Integer.toString(HEAD_BIG_FILE_ACK) + ","+ Integer.toString(FLAG_ACK_START); rFileName = message_packet[2]; rFilePeiceNumber = Integer.valueOf(message_packet[3]); totalData = new StringBuffer(rFilePeiceNumber*fileLimitSize); mBlueToothTool.send(ackMessage.getBytes()); mOutStringBuffer.setLength(0); //計時開始 sendBroadcast(setIntent(ACTION, 27.
(38) MESSAGE_TIMER, Integer.toString(0))); sendBroadcast(setIntent(ACTION, MESSAGE_TIMER, Integer.toString(1))); break; case FLAG_MIDDLE: //設定當前接收的檔案片段編號,並存入變數 setNowFilePeice(Integer.valueOf(message_packet[2])); totalData.append(message_packet[3]); //設定進度條,以當前片段數與總數計算百分比 int progress = getNowFilePeice()*100/rFilePeiceNumber; sendBroadcast(setIntent(ACTION, MESSAGE_BAR, Integer.toString(progress))); //以片段編號來判斷是否接收完畢 if(getNowFilePeice() != (rFilePeiceNumber-1)) { ackMessage = Integer .toString(HEAD_BIG_FILE_ACK)+ "," +Integer.toString(FLAG_ACK_MIDDLE); mBlueToothTool.send(ackMessage.getBytes()); mOutStringBuffer.setLength(0); } else { ackMessage = Integer.toString(HEAD_BIG_FILE_ACK)+ "," +Integer.toString(FLAG_ACK_OVER); mBlueToothTool.send(ackMessage.getBytes()); mOutStringBuffer.setLength(0); //將字串轉回檔案 getPicFormatBASE64(totalData.toString(), SD_PATH+"/"+rFileName); //計時結束 sendBroadcast(setIntent(ACTION, MESSAGE_TIMER, Integer.toString(2))); //發送傳送檔案結束通知 sendBroadcast(setIntent(ACTION, MESSAGE_FILE_END, rFileName)); //將進度條歸零並隱藏 sendBroadcast(setIntent(ACTION,MESSAGE_BAR,"0")); 28.
(39) //將接收的變數清除 totalData.delete(0, totalData.length()); } break; 程式碼 3.8 接收端的對應動作. 圖 3.13 檔案傳送流程. 29.
(40) 圖 3.14 藍芽檔案傳輸介面(1). 圖 3.15 藍芽檔案傳輸介面(2) 30.
(41) 3.5 藍芽檔案傳輸測試部分 本節討論以文字為基底的藍芽傳輸效率測試,由於前面已提到每一次的傳輸 容量約 1KB,因此每秒內的傳輸次數將是決定傳輸速率的關鍵,測試的方法為, 傳送各種容量大小的檔案,分為兩個類別,一為 10KB 內的檔案測試,二為 10KB 以上至 2MB 的檔案,分別有 1KB、2KB~10KB,以及 25KB、50KB、100KB、 150KB、200KB、250KB、300KB、400KB、500KB、750KB、1MB、1.5MB、2MB。 每個檔案接傳送 5 次,並且由程式計時,在接收到 file_start 資訊時開始計時, 當接收到最後一個編碼片段時停止,取到 0.1 秒,最後將 5 次結果取平均,而得 出結果。經過測試後,發現傳輸速率約為 16KB/s 左右,圖 3.16 為 10KB 內檔案 傳輸的結果,因為檔案都非常的小,所以時間都小於 1s,而曲線的斜率並不是 很平穩,這與測試精準度有關,因為時間太快所以誤差很大,圖 3.17 為 25~500KB 的時間都在 30 秒左右內,並且速度趨於穩定,時間拉長所以誤差變小,所以速 度很明確,再更大容量的部分(圖 3.18)速度也沒有太大的變動,時間與檔案大小 成正比。. 31.
(42) 圖 3.16 10KB 以下檔案傳輸. 圖 3.17 25~500KB 檔案傳輸. 32.
(43) 圖 3.18 500KB~2MB 檔案傳輸 除了從技術面來看測試的結果以外,也試著從使用者的角度去看,傳輸各種 類型的文件、音樂、影片等等的感覺,從圖 3.19 中可以看到本系統由於傳輸速 率的限制,在影片的部分需要使用者等待較久的時間,但是在一般文件或者手機 相機所拍照的照片,時間上還算可以接受。. 33.
(44) 圖 3.19 依照使用者經驗所繪製的圖表. 3.6 NFC P2P 傳輸模式 前面我們有測試了藍芽的傳輸檔案速度,但是若檔案不大的話,是否也可用 NFC 的 P2P 模式來傳輸呢?P2P 模式的傳輸量經過測試,理論上是可以無上限 的,因為系統會自動將其切割並連續傳送,只是所需要的時間會隨著傳輸量呈正 相關,因此我們做出了測試表(圖 3.22),可以看到 P2P 的傳輸並不是很穩定,每 一次靠近到開始傳輸的時間不一定,才會造成速度並不穩定,由於程式無法得知 何時開始傳輸所以無法從程式來計時,只好以人工計時從放上去開始到傳輸完成 播放音效,每種容量各五次取平均。. 34.
(45) 圖 3.20 NFC P2P 模式檔案傳輸介面─接收端. 圖 3.21 NFC P2P 模式檔案傳輸介面─傳送端 35.
(46) 圖 3.22 NFC P2P 傳輸測試. 3.7 NFC 與藍芽傳輸的比較 雖然藍芽的傳輸速度遠高於 NFC P2P 傳輸,不過藍芽實際上所花費的時間 卻必須加上建立連線的時間,在 3.2 節有提到本文所提供的藍芽建立時間平均為 5.4 秒,因此可以畫出一個時間比較的圖,見圖 3.23。. 36.
(47) 圖 3.23 NFC P2P 與藍芽實際時間比較 由圖 3.23 可以看出,當檔案為 4KB 時,NFC 傳輸時間正好與藍芽連線時間 交會,若是要傳輸小於 4KB 檔案的話,直接使用 NFC 傳輸會比較快速,這個傳 輸量算是一個使用 NFC 或者是藍芽的分水嶺,當某些應用是兩者皆可以使用時, 便可以此為依據,來決定較有效率的做法。. 37.
(48) 第4章. 系統應用. 在有了簡易連線與傳輸檔案的藍芽連線模組後,我們也試著開發一些藍芽上 的應用,少了以往繁複的連線流程,相信使用者接受度會更高,更能享受智慧型 手機所帶來的便利。. 4.1 Child Guard 傳統上這類的產品都是小孩與父母兩邊各配戴一個發射器與接收器,並且在 一定的距離外,會發出警告聲,不過會有電池的問題,時常會忘記更換,若電壓 不足,也會影響產品使用的效果。 現在智慧型手機的普遍,並且幾乎都建有藍芽晶片,配合藍芽的傳輸範圍約 10 公尺左右,距離都在可視範圍內,因此非常適合應用在這個部分,在使用本 文的方法建立藍芽連線後,畫面上面會有一個 Call 的圖示,點擊時另一方的手 機會發出聲響,以提醒所在位置,如果因為距離過遠,造成藍芽連線中斷時,此 時兩方的手機也都會響起,以提醒家長及時找尋小孩的位置。 由於本文的連線方式相當簡易,所以即使是不熟悉操作的家長或小孩也能輕 易地使用,並且因為已採用 Service 程式關係,同時也可以執行其他軟體而不會 因為切換畫面造成藍芽連線中斷。. 38.
(49) 圖 4.1 Child Guard 程式介面 程式實作部分,因為即時的狀態通知是由第二層發出 Broadcast 給第三層, 因此第三層要使用 BroadcastReceiver 來接收,並且定義許多事件,來處理不同的 狀況,本程式用到的有斷線時的事件,還有呼叫對方響鈴的事件,分別是 MESSAGE_LOST 與 MESSAGE_CHILD_CALL,在這兩個事件發生時,皆會播 放警告聲響來提醒使用者,詳細定義可參考程式碼 4.1。 case BlueToothTransmissionService.MESSAGE_LOST: //連線中斷時,播放警鈴 mp.start(); break; case BlueToothTransmissionService.MESSAGE_CHILD_CALL: //收到呼叫時,播放警鈴 mp.start(); Toast.makeText(getApplicationContext(), "call", Toast.LENGTH_SHORT).show(); 39.
(50) break; 程式碼 4.1 在斷線即呼叫時播放音效. 4.2 Draw Together 藍芽是一種個人的區域網路,不需要借助其他的媒介,因此用在人與人的互 動時非常適合,不需要額外的無線網路或者 3G 網路,只要兩人都有智慧型手機 便可進行互動,藉由這樣的特性,我們開發出一個取代紙張的應用,顧名思義, 本應用是可以讓兩個人一起在手機上畫畫,並把畫面傳送到對方的手機上,能夠 讓使用者用接力的方式畫出一些東西或是玩一些傳統的紙上遊戲例如圈圈叉叉 等等。 在連線後,進入畫布共享的程式,會先判斷誰為 Server (程式碼 4.2),由 Server 先對畫布做編輯,之後再換對方,程式上共有四個按鈕,分別是清除畫面、 換顏色、存檔、換對方,而第四個按鈕只有編輯的那方會出現,另一方會隱藏, 並且無法對畫布做編輯,在輪到自己時,對方的畫布會同步在本機上,如此一來 一往的進行。 if(blueToothTransmissionService.getState() == BlueToothTool.STATE_CONNECTED) { if(blueToothTransmissionService.getPersonalMac() == blueToothTransmissionService.getServer()) { drawView.setIsCapturing(true); change_button.setVisibility(View.VISIBLE); setTitle("輪到你畫囉"); Toast.makeText(getApplicationContext(), "輪到你畫囉", Toast.LENGTH_SHORT).show(); } 40.
(51) } 程式碼 4.2 先判斷本機是否為 Server,若是則允許編輯. 圖 4.2 Draw Together 程式介面 程式實作部分使用到了檔案傳送的功能,在換人的時候將本機畫布轉存 jpg 檔,並把按鈕隱藏與畫布鎖住,傳送到對方後,對方接收完成時,便把對方的圖 片設為畫布的背景,由於目前傳送的速率並不夠快速,所以設定 jpg 的壓縮品質 較差,以減少使用者等待的時間,詳細部分見程式碼 4.3、程式碼 4.4。 change_button = (ImageButton)findViewById(R.id.imageButton3); change_button.setOnClickListener(new OnClickListener() { public void onClick(View view) { //將畫面鎖住 drawView.setIsCapturing(false); setTitle("等對方畫完吧"); 41.
(52) Toast.makeText(getApplicationContext(), "等對方畫完吧", Toast.LENGTH_SHORT).show(); change_button.setVisibility(View.INVISIBLE); //JPEG 品質範圍 0-100 byte[] drawData = drawView.getSignatureJPEG(30); SaveData(drawData,draw.this,true,".jpg"); File f = new File(SD_PATH+"/paint/temp.jpg"); long fileSize = f.length(); blueToothTransmissionService.sendMessage("none", blueToothTransmissionService.HEAD_BIG_FILE, "temp.jpg",fileSize,SD_PATH+"/paint/temp.jpg"); } }); 程式碼 4.3 換人的按鈕功能實作 case BlueToothTransmissionService.MESSAGE_FILE_END: //接收到對方傳來的圖片後,設為背景,並切換可畫圖 drawView.clear(); drawView.setSignatureBitmap (BitmapFactory.decodeFile(SD_PATH+"/temp.jpg")); drawView.setIsCapturing(true); setTitle("輪到你畫囉"); Toast.makeText(getApplicationContext(), "輪到你畫囉", Toast.LENGTH_SHORT).show(); //刪除暫存檔 File f = new File(SD_PATH+"temp.jpg"); if(f.exists()) {f.delete();} change_button.setVisibility(View.VISIBLE); break; 程式碼 4.4 等待方接收到檔案後的動作 另外,Android 並未提供現成的觸控畫布,因此必須先偵測螢幕上的觸控行 為,再將軌跡畫在畫布上,觸控行為共分為三種: ACTION_DOWN、 ACTION_MOVE、ACTION_UP,而繪圖的部分主要在 ACTION_MOVE 時執行, 也因此使用者如果只是觸碰再拿開,並不會有任何軌跡在畫布上。 42.
(53) 當在 ACTION_MOVE 時,程式會不斷地取得當前座標的 X 與 Y 值,並且 在上個座標和此次座標取中間點,然後以中間點為中心繪製矩形,四個點即為中 間點上下左右,距離根據想要的粗細決定(程式碼 4.5)。 //線條的粗細 final int border = mInvalidateExtraBorder; //繪製矩形,上下左右加上粗細的值 areaToRefresh.set((int) mCurveEndX - border, (int) mCurveEndY - border, (int) mCurveEndX + border, (int) mCurveEndY + border); //計算這次與上次的中心點,給予下一次呼叫此函式時使用 float cX = mCurveEndX = (x + previousX) / 2; float cY = mCurveEndY = (y + previousY) / 2; 程式碼 4.5 移動時,使用矩形繪畫軌跡 可以依照觸碰軌跡繪畫後,接著便是希望可以變換顏色,因為畫上去的軌跡 顏色,都是由 paint 物件管理,所以修改後,會造成所有的軌跡都變換顏色,為 了解決這個問題,在變換顏色時,將當下的畫布儲存成圖片,再把畫布清空後, 將圖片當成背景,如此每一次的軌跡都能夠有不同的顏色(程式碼 4.6)。 colors_button = (ImageButton)findViewById(R.id.imageButton4); colors_button.setOnClickListener(new OnClickListener() { public void onClick(View view) { //先將原本的圖存成背景,不然所有的線都會變色 //JPEG 品質範圍 0-100 byte[] drawData = drawView.getSignatureJPEG(100); SaveData(drawData,draw.this,true,".jpg"); //清除原本的畫布 drawView.clear(); //載入之前存的圖片當背景 drawView.setSignatureBitmap(BitmapFactory .decodeFile(SD_PATH+"/paint/temp.jpg")); //顯示顏色選擇對話框 new ColorPickerDialog(draw.this, draw.this, 43.
(54) drawView.getSignatureColor()).show(); } }); 程式碼 4.6 選擇顏色按鈕功能實作. 4.3 翻牌遊戲 藍芽的普遍性與區網特性,也很適合用在遊戲上,讓兩人可以透過手機來對 戰,因此藉由本文的 NFC 藍芽連線模組,與同一個實驗室的莊惠迪同學所做的 NFC 翻牌遊戲結合,使其具有連線同步遊戲狀態的功能。 遊戲首先需要一個由許多 NFC 標籤構成的平面,每一個標籤內有著符號資 訊,見圖 4.3,遊戲一開始會先使用本文的方式建立藍芽連線,然後開始對戰, 讀取到某個標籤的時候,手機會顯示出該符號的圖案,如圖 4.4,找到一樣的符 號就可以得分,玩法與記憶遊戲相同,在遊戲時,敵人的分數會顯示在左上角, 讓雙方都清楚對方的分數,以增加氣氛的緊張度。. 圖 4.3 使用 NFC 標籤所構成的遊戲平台 44.
(55) 圖 4.4 翻牌遊戲介面. 4.4 模組整合說明 前一節所介紹的遊戲,可以說明本研究所開發的模組是可以輕易整合進其他 應用的,本節將說明整合的方式與步驟。首先要先必須要先取得近場通訊、藍芽 和存取 SD 卡的權限,因此必須修改專案中的 AndroidManifest.xml,新增 <user-permission>元素。 <uses-sdk android:minSdkVersion="10" /> <uses-permission android:name="android.permission.NFC"/> <uses-permission android:name="android.permission.BLUETOOTH"/> <uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> 接著,因為 SDK 到版本 10 才支援 NFC,所以要將最低 SDK 版本設為 10。 <uses-sdk android:minSdkVersion="10" /> 設定應用程式只會出現在具備近場通訊的 Android 手持裝置上。 45.
(56) <uses-feature android:name="android.hardware.nfc" android:required="true" /> 由於會使用到 Service 程式,所以也需要增加宣告,鍵入程式的名稱。 <service android:enabled="true" android:name=".BlueToothTransmissionService" /> 最後新增連線的 Activity 程式,設為進去的第一個頁面,還有鎖定螢幕為垂 直即可,AndroidManifest.xml 的設定便到此完成,而該 Activity 程式為 nfc_btActivity.java,可參考附錄 D 修改為個人想要的功能。 <activity android:label="@string/app_name" android:name=".nfc_btActivity" android:screenOrientation="portrait"> </activity> 連線後即可跳轉到自己的 Activity 程式,在需要藍芽的 Activity 上,僅需要 加上幾行與 Service 程式建立溝通的程式碼即可,首先是定義自己的 BroadcastReceiver 類別,有許多的即時狀態可讓開發者自行定義動作,也可自行 在 Service 程式新增動作或參數。 //定義 BroadcastReceiver 類別 BlueToothTransmissionReceiver 廣播接收程式 private class BlueToothTransmissionReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent){ Bundle extra = intent.getExtras(); switch(extra.getInt(BlueToothTransmissionService.TYPE)){ case BlueToothTransmissionService.MESSAGE_STATE_CHANGE: switch(extra.getInt(BlueToothTransmissionService.CONTENT)){ case BlueToothTool.STATE_CONNECTED: Toast.makeText(getApplicationContext(), "STATE_CONNECTED", Toast.LENGTH_SHORT).show; break; case BlueToothTool.STATE_CONNECTING: 46.
(57) Toast.makeText(getApplicationContext(), "STATE_CONNECTING", Toast.LENGTH_SHORT).show(); break; case BlueToothTool.STATE_LISTEN: Toast.makeText(getApplicationContext(), "STATE_LISTEN", Toast.LENGTH_SHORT).show(); break; case BlueToothTool.STATE_NONE: Toast.makeText(getApplicationContext(), "STATE_NONE", Toast.LENGTH_SHORT).show(); break; } break; case BlueToothTransmissionService.MESSAGE_READ: break; case BlueToothTransmissionService.MESSAGE_LOST: break; case BlueToothTransmissionService.MESSAGE_WRITE: break; case BlueToothTransmissionService.MESSAGE_CONTENT: break; default: break; } } } 接下來則是宣告 Service 程式相關變數,註冊 BroadcastReceiver 以及啟用 Service 程式和綁定(Bind),啟用的部分已經寫入 setup 函式,在 onCreate 啟用即 可,需要注意的是,Service 在 Bind 後,需要約 1 秒鐘才能使用,否則會有錯誤, 所以若有要及時使用 Server 的部分需要延遲 1 秒後再執行,最後只要將相關檔 案複製進要整合的專案內便可完成。. 47.
(58) //宣告 Service 程式 private BlueToothTransmissionService blueToothTransmissionService = null; //宣告 BroadcastReceiver 程式 receiver private final BlueToothTransmissionReceiver receiver = new BlueToothTransmissionReceiver(); //宣告 ServiceConnection 程式 serviceConnection private ServiceConnection serviceConnection = new ServiceConnection() { public void onServiceConnected(ComponentName className, IBinder service) { blueToothTransmissionService = ((BlueToothTransmissionService.BlueToothTransmissionBinder)service).getService() ; } public void onServiceDisconnected(ComponentName className) { blueToothTransmissionService = null; } }; public void setup(){ //服動服務程式 KitchenTimerService intent = new Intent(this, BlueToothTransmissionService.class); startService(intent); //註冊廣播接收 receiver filter = new IntentFilter(BlueToothTransmissionService.ACTION); registerReceiver(receiver, filter); //綁縛(Bind)服務程式 KitchenTimerService bindService(intent, serviceConnection, Context.BIND_AUTO_CREATE); }. 48.
(59) 第5章. 結論與未來發展. 5.1 結論 本研究提出使用 NFC Peer to Peer 模式來建立藍芽連線的方法,讓使用者可 以在不需要了解藍芽連線先備知識的前提下,輕鬆地建立藍芽連線,較傳統方式 節省 52%連線時間,並且發展出一個簡單的方法透過藍芽來傳輸檔案,可以暫時 解決官方 SDK 無提供檔案傳輸方式的問題,測試結果其速度約 16KB/秒,以及 測試 NFC P2P 的傳輸速率並與本文的藍芽傳輸速率做比較,了解到在傳輸量小 於 4KB 時,使用 NFC P2P 傳輸的實際花費時間比使用藍芽還要少,較輕量的文 件皆能使用 NFC P2P 傳送即可,而需要長時間連續通訊的部分則是使用藍芽。 再提出連線方法後,本研究也提出兩個簡單的應用,和一個與其它應用結合 的例子,分別是 Child Guard、Draw Together 和翻牌遊戲,第一個應用是在建立 藍芽連線後,將手機放在小孩身上,倘若小孩的距離超過藍芽的連線範圍,約 10 公尺,便會發出警告聲以提醒家長,途中若家長看不見小孩,亦可按下呼叫 鍵來讓小孩的手機發出警告聲,顯示其位置。第二個應用是讓兩個使用者可以共 同使用同一個畫布繪畫,在一方畫完後,按下換人紐,會將畫布以藍芽傳送到對 方的手機上,可以用此來接力畫畫或者完基本的紙上遊戲。第三個例子是與實驗 室同學莊惠迪所做的 NFC 翻牌遊戲結合,讓遊戲的即時狀況可以同步顯示在使 用者們的遊戲畫面上,來增加遊戲的氣氛和緊張度。. 49.
(60) 5.2 未來發展 雖然結合了 NFC 來使藍芽的連線更為簡便,可是連線速度卻因為 Android 官方的 SDK 沒有提供,無法使用原生的藍芽協定傳輸檔案,造成傳輸速率不高 的問題,也間接地限制了應用的發展,不過,目前已有發現 Google Play 上的藍 芽傳檔軟體,Bluetooth File Transfer,能夠支援原生協定,並且能與電腦建立連 線,檔案傳輸速率達到約 120KB/秒,若能了解其實作方式,便能發揮藍芽應有 的效能,也可以進一步擴充到與桌上型或筆記型電腦上的應用。 另外,NFC Forum 並未訂出統一的編號來表示 NFC 對應的不同動作,各家 都是自己使用自己的編號,所以有人提出自己的服務框架[21],但是都仍然無法 相容使用,若 NFC Forum 有訂出相關的標準,Android 作業系統將可以自行對應 到不同的動作,而支援度也會比較好。 儘管藍芽提供 1 對 7 的連線,但 SDK 同樣也未說明相關的部分,若能使用 多人連線,便能開發出更多互動的應用,與社群方面的應用,真正實踐個人區域 網路的功能。 目前市面上的 NFC 手機並不多,因此普遍性並不高,以至於即使開發出許 多 NFC 的應用,仍舊沒有可以使用的環境,所以若能將本文的連線方式,運用 二維條碼的方式,由一端產生出二維條碼,並將連線資訊放入其中,而另一端讀 取後,自動開始建立連線,同樣可以使沒有 NFC 手機的人一樣享受到藍芽的便 利。. 50.
(61) 參考著作 [1]. ECMA International NFC White Paper http://www.ecma-international.org/activities/Communications/tc32-tg19-2005-01 2.pdf [2]. Charl A. Opperman, Gerhard P. Hancke, “Using NFC-enabled Phones for Remote Data Acquisition and Digital Control”, “AFRICON, 2011”, Sept 2011 [3]. Weihua Pan, Fucai Luo, Lei Xu, “Reserch and design of chatting room system based on Android Bluetooth”, “Consumer Electronics, Communications and Networks (CECNet), 2012 2nd International Conference on”, April 2012. [4]. Chiu-Chiao Chung, Ching Yuan Huang, Shiau-Chin Wang, Cheng-Min Lin, ” Bluetooth-based Android Interactive Applications for Smart Living”, “Innovations in Bio-inspired Computing and Applications (IBICA), 2011 Second International Conference on”, Dec 2011 [5]. Wu, Shyi-Shiou, Wu, Hsin-Yi, “The Design of an Intelligent Pedometer using Android”, “Innovations in Bio-inspired Computing and Applications (IBICA), 2011 Second International Conference on”, Dec 2011 [6]. Josh Potts, Somsak Sukittanon, “Exploiting Bluetooth on Android Mobile Devices for Home Security Application”, “Southeastcon, 2012 Proceedings of IEEE”, March 2012 [7]. Brad Boone, Chris Hayes, Corey Darr, Dale Musser, “Using Bluetooth on Android Devices to Implement Real-Time Multiplayer Games”, “http://people.cs.missouri.edu/~reu/REU11/adhocgaming/”, July 2011 [8]. Leong, C.Y., Ong, K.C., Tan, K.K., Gan, O.P., “Near Field Communication and Bluetooth Bridge System”, “Industrial Informatics, 2006 IEEE International Conference on”, Aug 2006 [9]. 花珀 Dongle, http://flower.emome.net/product-dongle.html [10]. Burden, M., “Near Field Communications in Public Transport”, “RFID and Electronic Vehicle Identification in Road Transport, 2006. The Instititon of Engineering and Technology Seminar on”, Nov 2006. [11]. Ben Dodson Monica S. Lam., “P2P Micro-Interactions with NFC-enabled Mobile Phones”, “MobiCASE 2011”, Oct 2011 [12]. Cihan KURNAZ, “ADD-ON APPLICATIONS FOR ANDROID”, “Ayça SANİN”, June 2008 [13]. Benjamin Speckmann, “The Android mobile platform”, Apr 2008 [14]. Frank Ableson, “Unlocking Android”, Apr 2009 51.
(62) [15]. Yun-Cheng Chen, “Mobile Navigation Service by Bluetooth Protocol”, July 2005 [16]. N. Golmie, “Bluetooth Dynamic Scheduling and Interference Mitigation”, “Journal Mobile Networks and Applications”, Feb 2004. [17]. Android Developers. (2011, Feb.). Android 2.3.3 platform (rev. 1). [Online]. Available: http://developer.android.com/sdk/android-2.3.3.html [18]. NFC Forum, “NFC Data Exchange Format”, http://www.maintag.fr/fichiers/pdf-fr/nfcforum-ts-ndef-1-0.pdf [19]. NFC Forum, “NFC Record Type Definition”, https://engineering.purdue.edu/477grp14/Specs/NFC/NFCRTD.pdf [20]. Apache Base64 encoding and decoding: http://commons.apache.org/codec/apidocs/org/apache/commons/codec/binary/Ba se64.html [21]. 陳宏志,近場通訊之萬用服務框架, 2009 年 6 月 [22]. Behrouz A. Forouzan, “Data Communications and Networking, 4e”. 52.
(63) 附錄 附錄A. 系統第一層與第二層 class diagram. 53.
(64) 附錄B. 系統係二層與第三層 class diagram〈一〉. 54.
(65) 附錄C.系統第二層與第三層 class diagram〈二〉. 55.
(66) 附錄D.連線程式 nfc_btActivity.java package xml_lab.sample.nfc_bt; import android.app.Activity; import android.app.PendingIntent; import android.bluetooth.BluetoothAdapter; import android.content.BroadcastReceiver; import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.content.IntentFilter.MalformedMimeTypeException; import android.content.ServiceConnection; import android.content.pm.ActivityInfo; import android.media.MediaPlayer; import android.nfc.NdefMessage; import android.nfc.NdefRecord; import android.nfc.NfcAdapter; import android.nfc.NfcManager; import android.nfc.tech.NfcF; import android.os.Bundle; import android.os.CountDownTimer; import android.os.IBinder; import android.os.Parcelable; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.ImageView; import android.widget.TextView; import android.widget.Toast; public class nfc_btActivity extends Activity { private String text = ""; private String target = ""; private BluetoothAdapter mBluetoothAdapter = null; private TextView mText; 56.
(67) private Bundle extras; private Intent intent; private IntentFilter filter; private Button trans_file_button,message_button,childCare,trans_file_NFC_button,draw_button; private ImageView img; private static final int REQUEST_ENABLE_BT = 1; private MediaPlayer mp; //定義 BroadcastReceiver 類別 BlueToothTransmissionReceiver 廣播接收程式 private class BlueToothTransmissionReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent){ Bundle extra = intent.getExtras(); switch(extra.getInt(BlueToothTransmissionService.TYPE)){ case BlueToothTransmissionService.MESSAGE_STATE_CHANGE: switch(extra.getInt(BlueToothTransmissionService.CONTENT)){ case BlueToothTool.STATE_CONNECTED: Toast.makeText(getApplicationContext(), "STATE_CONNECTED", Toast.LENGTH_SHORT).show(); message_button.setVisibility(View.VISIBLE); childCare.setVisibility(View.VISIBLE); trans_file_button.setVisibility(View.VISIBLE); trans_file_NFC_button.setVisibility(View.VISIBLE); draw_button.setVisibility(View.VISIBLE); mText.setText("已連線"); break; case BlueToothTool.STATE_CONNECTING: Toast.makeText(getApplicationContext(), "STATE_CONNECTING", Toast.LENGTH_SHORT).show(); break; case BlueToothTool.STATE_LISTEN: Toast.makeText(getApplicationContext(), "STATE_LISTEN", Toast.LENGTH_SHORT).show(); break; case BlueToothTool.STATE_NONE: 57.
(68) break; } break; case BlueToothTransmissionService.MESSAGE_READ: break; case BlueToothTransmissionService.MESSAGE_LOST: Toast.makeText(getApplicationContext(), extra.getCharSequence(BlueToothTransmissionService.CONTENT), Toast.LENGTH_SHORT).show(); break; case BlueToothTransmissionService.MESSAGE_WRITE: break; case BlueToothTransmissionService.MESSAGE_CONTENT: Toast.makeText(getApplicationContext(), extra.getCharSequence(BlueToothTransmissionService.CONTENT), Toast.LENGTH_SHORT).show(); break; default: break; } } } //宣告 Service 程式 private BlueToothTransmissionService blueToothTransmissionService = null; //宣告 BroadcastReceiver 程式 receiver private final BlueToothTransmissionReceiver receiver = new BlueToothTransmissionReceiver(); //宣告 ServiceConnection 程式 serviceConnection private ServiceConnection serviceConnection = new ServiceConnection() { public void onServiceConnected(ComponentName className, IBinder service) { blueToothTransmissionService = ((BlueToothTransmissionService.BlueToothTransmissionBinder)service).getService() ; } public void onServiceDisconnected(ComponentName className) { blueToothTransmissionService = null; } 58.
(69) }; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);//取 消旋轉 mText = (TextView) findViewById(R.id.textView1); mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); extras = getIntent().getExtras(); trans_file_button = (Button)findViewById(R.id.button2); trans_file_button.setOnClickListener(new OnClickListener() { public void onClick(View view) { startActivity(new Intent(nfc_btActivity.this, transFileBT.class)); } }); trans_file_NFC_button = (Button)findViewById(R.id.button1); trans_file_NFC_button.setOnClickListener(new OnClickListener() { public void onClick(View view) { startActivity(new Intent(nfc_btActivity.this, transFileNFC.class)); } }); message_button = (Button)findViewById(R.id.button4); message_button.setOnClickListener(new OnClickListener() { public void onClick(View view) { startActivity(new Intent(nfc_btActivity.this, message.class)); } }); childCare = (Button)findViewById(R.id.button5); childCare.setOnClickListener(new OnClickListener() { public void onClick(View view) { startActivity(new Intent(nfc_btActivity.this, childCare.class)); } }); draw_button = (Button)findViewById(R.id.button3); 59.
(70) draw_button.setOnClickListener(new OnClickListener() { public void onClick(View view) { startActivity(new Intent(nfc_btActivity.this, draw.class)); } }); mp = MediaPlayer.create(getBaseContext(), R.raw.ok); img=(ImageView)findViewById(R.id.imageView1); } @Override public void onStart() { super.onStart(); if (!mBluetoothAdapter.isEnabled()) { Intent enableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE); startActivityForResult(enableIntent, REQUEST_ENABLE_BT); } else {checkHaveNfcData();} } @Override public void onResume() { super.onResume(); if(mBluetoothAdapter.isEnabled()) { //push nfc message NfcManager manager = (NfcManager) getSystemService(NFC_SERVICE); /*必須要一個 Activity 來支援 URL 的發送, 這個 URL 要包裝成 NdefMessage*/ String btMac = mBluetoothAdapter.getAddress(); NdefRecord rec = new NdefRecord(NdefRecord.TNF_WELL_KNOWN, NdefRecord.RTD_TEXT , new byte[0],btMac.getBytes()); /*要支援 push, 只需要在 onResume 時使用 enableForegroundNdefPush 就可以了*/ manager.getDefaultAdapter().enableForegroundNdefPush(this, new NdefMessage(new NdefRecord[]{rec})); 60.
(71) //get nfc message IntentFilter ndef = new IntentFilter(NfcAdapter.ACTION_NDEF_DISCOVERED); try { ndef.addDataType("*/*"); } catch (MalformedMimeTypeException e) { throw new RuntimeException("fail", e); } manager.getDefaultAdapter().enableForegroundDispatch(this, PendingIntent.getActivity(this, 0,new Intent(this, getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), 0), new IntentFilter[] {ndef, }, new String[][] { new String[] { NfcF.class.getName() } }); } } @Override public void onNewIntent(Intent intent) { //此處處理接收到 NFC 資料後的動作 Parcelable[] rawMsgs = intent.getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES); NdefMessage enemymsgs = (NdefMessage) rawMsgs[0];//get enemy message String enemyText = new String(enemymsgs.getRecords()[0].getPayload()); //因為會跳出,所以設定跳到本身 acticity Intent intent1 = new Intent(nfc_btActivity.this,nfc_btActivity.class); intent1.putExtra("BTmac", enemyText); startActivity(intent1); } @Override public void onPause() { super.onPause(); /*onPause 記得把它 disable (沒 disable 會怎樣? 我碰到狀況是, 沒 disable, 可能連之後讀取似乎都有問題)*/ NfcManager manager = (NfcManager) getSystemService(NFC_SERVICE); manager.getDefaultAdapter().disableForegroundNdefPush(this); manager.getDefaultAdapter().disableForegroundDispatch(this); } 61.
(72) //結束時要交還資訊,Unbind Service, Unregister Receiver, Stop Service @Override public void onDestroy() { super.onDestroy(); if(blueToothTransmissionService != null) { unbindService(serviceConnection); //Unbind service unregisterReceiver(receiver); //Unregister Receiver blueToothTransmissionService.stopSelf(); //Stop Service } } public void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); switch (requestCode) { case REQUEST_ENABLE_BT: // When the request to enable Bluetooth returns if (resultCode == Activity.RESULT_OK) { // Bluetooth is now enabled, so set up a chat session checkHaveNfcData(); } else { // User did not enable Bluetooth or an error occurred Toast.makeText(getApplicationContext(), R.string.bt_not_enabled_leaving, Toast.LENGTH_SHORT).show(); finish(); } break; } } private void checkHaveNfcData() { setup(); if(extras != null) { /*因為 service 沒辦法馬上使用,所以延遲一秒*/ new CountDownTimer(1000, 1000) { public void onTick(long millisUntilFinished) {} public void onFinish() { 62.
(73) if(blueToothTransmissionService.getState() != BlueToothTool.STATE_CONNECTED) { mp.start(); text = extras.getString("BTmac"); target = text; blueToothTransmissionService.setDevice(blueToothTransmissionService.getPers onalMac(), target); } } }.start(); } else { text="請接觸對方手機,聽到聲音即可分開"; mText.setText(text); img.setVisibility(View.VISIBLE); } } public void setup(){ //啟動服務程式 KitchenTimerService intent = new Intent(this, BlueToothTransmissionService.class); startService(intent); //註冊廣播接收 receiver filter = new IntentFilter(BlueToothTransmissionService.ACTION); registerReceiver(receiver, filter); //綁縛(Bind)服務程式 KitchenTimerService bindService(intent, serviceConnection, Context.BIND_AUTO_CREATE); } }. 63.
(74)
Outline
相關文件
The majority (4,075 units valued at MOP9.2 billion) of these transactions were residential units that accounted for 55.5% of the total number of building units; besides, there were
Among these units, 37.4% (749 units valued at MOP1.53 billion) were new units e that were within the property tax exemption period. b In the analysis, the term “Real Estate”
Private consumption expenditure in the fourth quarter rose by 1.9% over the preceding quarter; meanwhile, private domestic investment dropped significantly from a 5.0% growth in
command line, he specifies an arbitrary (but specific; in this case, 9989) local port that ssh should forward through the secure tunnel to the remote Windows ma- chine’s port
command line, he specifies an arbitrary (but specific; in this case, 9989) local port that ssh should forward through the secure tunnel to the remote Windows ma- chine’s port
The engineering team shall complete the ventilation assessment report in a specified form in Appendix 1 [Please refer to Annex III of EDB’s letter to private schools dated 1
Private Sub Form_Click() MsgBox Combo1.ListCount MsgBox Combo1.ListIndex..
Private Sub Dir1_change() File1.Path = Dir1.Path updatePath.