第一篇:基于Android的通訊錄開發(fā)教學(xué)視頻 Android開發(fā)教程
基于Android的通訊錄開發(fā)教學(xué)視頻 Android開發(fā)教程
Android是基于Linux內(nèi)核的操作系統(tǒng),是Google公司在2007年11月5日公布的手機(jī)操作系統(tǒng),早期由Google開發(fā),后由開放手持設(shè)備聯(lián)盟(Open Handset Alliance)開發(fā)。它采用了軟件堆層(software stack,又名以軟件迭層)的架構(gòu),主要分為三部分。底層Linux內(nèi)核只提供基本功能;其他的應(yīng)用軟件則由各公司自行開發(fā),部分程序以Java編寫。
2010年末數(shù)據(jù)顯示,僅正式推出兩年的操作系統(tǒng)Android已經(jīng)超越稱霸十年的諾基亞(Nokia)Symbian OS系統(tǒng),采用Android系統(tǒng)主要手機(jī)廠商包括宏達(dá)電子(HTC)、三星(SAMSUNG)、摩托羅拉(MOTOROLA)、LG、Sony Ericsson、魅族M9等,使之躍居全球最受歡迎的智能手機(jī)平臺,Android系統(tǒng)不但應(yīng)用于智能手機(jī),也在平板電腦市場急速擴(kuò)張。
基于Android的通訊錄開發(fā)教學(xué)視頻 Android開發(fā)教程目錄:
01_項目演示
02_增加界面01
03_增加界面02
04_增加界面03
05_顯示圖像選擇框01
06_顯示圖像選擇框02
07_顯示圖像選擇框03
08_顯示圖像選擇框04
09_保存用戶信息01
10_保存用戶信息02
11_保存用戶信息03_講解SQLiteOpenHelper
12_保存用戶信息04
13_主界面的繪制01
14_主界面的繪制02
15_主界面的繪制03
16_主界面的繪制04
17_展現(xiàn)用戶列表01
18_展現(xiàn)用戶列表02
19_展現(xiàn)用戶列表03
20_增加頁面的跳轉(zhuǎn)01
21_增加頁面的跳轉(zhuǎn)02
22_實現(xiàn)gallery無限循環(huán)
23_顯示詳細(xì)信息01
24_顯示詳細(xì)信息02
25_顯示詳細(xì)信息03
26_顯示詳細(xì)信息04
基于Android的通訊錄開發(fā)教學(xué)視頻大?。?37MB
教程地址: http://
第二篇:android 開發(fā)心得
即 使你的應(yīng)用程序是快速且響應(yīng)靈敏的,但一些設(shè)計仍然會給用戶造成問題——與其它應(yīng)用程序或?qū)υ捒蛭词孪扔媱澋慕换?,意外的?shù)據(jù)丟失,意料之外的阻塞等等。避免這些問題,有助于理解應(yīng)用程序運行的上下文和系統(tǒng)的交互過程,而這些又正影響著你的應(yīng)用程序。簡而言之,你應(yīng)該竭盡全力去開發(fā)一個與系統(tǒng)和其它應(yīng)用程 序流暢交互的應(yīng)用程序。
一 個常見的流暢問題是,一個應(yīng)用程序的后臺處理——例如,一個 Service或者
BroadcastReceiver——彈出一個對話框來響應(yīng)一些事件。這可能看起來沒啥大礙,尤其是你在模擬器上單獨地構(gòu)建和測試你 的應(yīng)用程序的時候。然而,當(dāng)你的應(yīng)用程序運行在真機(jī)上時,有可能你的應(yīng)用程序在沒有獲得用戶焦點時后臺處理顯示了一個對話框。因此,可能會出現(xiàn)在活躍的應(yīng) 用程序后方顯示了你的應(yīng)用程序的對話框,或者從當(dāng)前應(yīng)用程序奪取焦點顯示了一個對話框,而不管當(dāng)前用戶正在做什么(例如,正在打電話)。那種行為,對應(yīng)用 程序或用戶來說,就不應(yīng)該出現(xiàn)。
為了避免這些問題,你的應(yīng)用程序應(yīng)該使用合適的系統(tǒng)資源來通知用戶——Notification類。使用Notification,你的應(yīng)用程序可以在狀態(tài)欄顯示一個 icon來通知用戶已經(jīng)發(fā)生的事情,而不是奪取焦點和打斷用戶。
另 一個流暢問題的例子是未能正確實現(xiàn)Activity的 onPause()和其它生命周期方法而造成意外丟失了狀態(tài)或用戶數(shù)據(jù)。又或者,如果你的應(yīng)用程序想暴露數(shù)據(jù)給其它應(yīng)用程序使用,你應(yīng)該通過 ContentProvider來暴露,而不是(舉例)通過一個可讀的原始文件或數(shù)據(jù)庫來實現(xiàn)。
這 些例子的共同點是它們都應(yīng)該與系統(tǒng)和其它應(yīng)用程序協(xié)作好。Android系統(tǒng)設(shè)計時,就把應(yīng)用程序看作是一堆松散耦合的組件,而不是一堆黑盒代碼。作為開 發(fā)者來說,允許我們把整個系統(tǒng)看作是更大的組件集合。這有益于我們可以與其它應(yīng)用程序進(jìn)行清晰無縫的集成,因此,作為回報,我們應(yīng)該更好的設(shè)計我們的代 碼。
下面將討論常見的流暢問題以及如何避免它們:
一 定要記住Android是一個移動平臺??梢燥@而易見地說,其它Activity(例如,“Incoming Phone Call”應(yīng)用程序)可能會在任何時候彈出來遮蓋你的Activity,記住這個事實很重要。因為這個過程將觸發(fā) onSaveInstanceState()和 onPause()方法,并可能導(dǎo)致你的應(yīng)用程序
被殺死。
如 果用戶在你的應(yīng)用程序中正在編輯數(shù)據(jù)時,其它 Activity出現(xiàn)了,這時,你的應(yīng)用程序被殺死時可能丟失那些數(shù)據(jù)。當(dāng)然了,除非你事先保存了正在進(jìn)行的工作?!癆ndroid方式”是這樣做的:能 接收和編輯用戶輸入的 Android應(yīng)用程序應(yīng)該重寫 onSaveInstanceState()方法,并以恰當(dāng)?shù)姆绞奖4嫠鼈兊臓顟B(tài)。當(dāng)用戶重新訪問應(yīng)用程序時,她能得到她的數(shù)據(jù)。進(jìn)行這種處理方式最經(jīng)典的例子是 mail應(yīng)用程序。如果用戶正在輸入 email,這時其它 Activity啟動了,mail應(yīng)用程序應(yīng)該把正在編輯的email以草稿的方式保存起來。
如果你不想穿著內(nèi)衣在大街上溜達(dá)的話,你的數(shù)據(jù)也不應(yīng)該這樣。盡管可能存在暴露應(yīng)用程序的某種形式給其它應(yīng)用程序,但這通常不是最好的主意。暴露原始數(shù)據(jù),要求其它應(yīng)用程序能夠理解你的數(shù)據(jù)的格式;如果你變更了格式,那么,你將破壞那些沒有進(jìn)行同步更新的應(yīng)用程序。
“Android 方式”是創(chuàng)建一個 ContentProvider,以一種清晰的、深思熟慮的和可維護(hù)的API方式暴露你的數(shù)據(jù)給其它應(yīng)用程序。使用 ContentProvider,就好像是插入Java接口來分離和組裝兩片高耦合的代碼。這意味著你可以修改數(shù)據(jù)的內(nèi)部格式,而不用修改由 ContentProvider暴露的接口,這樣,也不會影響其它應(yīng)用程序。
如果用戶正在運行一個應(yīng)用程序(例如,Phone程序),斷定對用戶操作的目的才是安全的。這也就是為什么必須避免創(chuàng)建Activity,而是直接在當(dāng)前的 Activity中響應(yīng)用戶的輸入。那 就是說,不要在 BroadcastReceiver或在后臺運行的 Service中調(diào)用 callActivity()。這么做會中斷當(dāng)前運行的應(yīng)用程序,并導(dǎo)致用戶惱怒。也許更糟糕的是,你的 Activity可能成為“按鍵強(qiáng)盜”,竊取了用戶要提供給前一個 Activity的輸入。視乎你的應(yīng)用程序所做的事情,這可能是個壞消息。
不 選擇在后臺直接創(chuàng)建 Activity UI,取而代之的是,應(yīng)該使用NotificationManager來設(shè)置 Notification。它們會出現(xiàn)在狀態(tài)欄,并且用戶可以在他空閑的時候點擊它們,來查看你的應(yīng)用程序向他顯示了什么。(注意,如果你的 Activity已經(jīng)在前臺了,以上將不適用:這時,對于用戶的輸入,用戶期望的是看到下一個 Activity來響應(yīng))
如果你的應(yīng)用程序需要執(zhí)行一些昂貴或耗時的計算的話,你應(yīng)該盡可能地將它挪到線程里。這將阻止向用戶顯示可怕的“Application Not Responding”對話框,如果不這樣做,最終的結(jié)果會導(dǎo)致你的應(yīng)用程序完全終止。
一 般情況下,Activity中的所有代碼,包括它的 View,都運行在相同的線程里。在這個線程里,還需要處理UI事件。例如,當(dāng)用戶按下一個按鍵,一個 key-down事件就會添加到 Activity的主線程隊列里。事件處理系統(tǒng)需要很快讓這個事件出列并得到處理;如果沒有,系統(tǒng)數(shù)秒后會認(rèn)為應(yīng)用程序已經(jīng)掛起并為用戶提供殺死應(yīng)用程序 的機(jī)會。
如果有耗時的代碼,內(nèi)聯(lián)在Activity上運行也就是運行在事件處理線程里,這在很大程度上阻塞了事件處理。這會延遲輸入處理,并導(dǎo)致ANR對話框。為了避免這個,把你的計算移到線程里。
任 何值得使用的應(yīng)用程序都可能有幾個不同的屏幕。當(dāng)設(shè)計UI屏幕時,請一定要使用多個Activity對象實例。依賴于你的開發(fā)背景,你可能理解 Activity類似于 Java Applet,它是你應(yīng)用程序的入口點。然而,那并不精確:Applet子類是一個 Java Applet的單一入口點,而一個Activity應(yīng)該看作是你的應(yīng)用程序多個潛在入口點之一。你的“main”Activity和其它之間的唯一不同點 是“main”Activity正巧是在AndroidManifest.xml文件中唯一對“android.intent.action.MAIN”動作感興趣的Activity。因此,當(dāng)設(shè)計你的應(yīng)用程序的時候,把你的應(yīng)用程序看作是Activity對象的 集合。從長遠(yuǎn)來看,這會使得你的代碼更加方便維護(hù)。
當(dāng) 談到 UI觀感時,巧妙地交融非常重要。用戶在使用與自己期望相反的 UI的應(yīng)用程序時,會產(chǎn)生不愉快的感覺。當(dāng)設(shè)計你的 UI時,你應(yīng)該盡量避免太多自己的主題。相反的,使用同一個主題。你可以重寫或擴(kuò)展你需要的主題部分,但至少在與其它應(yīng)用程序相同的 UI基礎(chǔ)上開始。
不 同的 Android設(shè)備可能支持不同的屏幕分辨率。甚至一些可以自己變更分辨率,例如,切換到風(fēng)景模式。確保你的布局和圖片能足夠靈活地在不同的設(shè)備屏幕上正 常顯示。幸運的是,這很容易做到。簡而言之,你需要做的是為主要分辨率提供不同版本的作品,然后為不同的尺寸設(shè)計你的布局。(例如,避免使用硬編碼位置而 使用相對布局。)如果那樣做的話,系統(tǒng)會處理剩下的部分,而且你的應(yīng)用程序在任何設(shè)備上都看起來很棒。
Android設(shè)備會有多種網(wǎng)絡(luò)連接選項。所有的都提供數(shù)據(jù)訪問,但之間肯定有更快的。其中,速度最慢的是GPRS,GSM網(wǎng)絡(luò)的非 3G數(shù)據(jù)服務(wù)。即使具備 3G能力的設(shè)備在非3G的網(wǎng)絡(luò)上也會花費很多的時間,所以,網(wǎng)絡(luò)很慢仍然是一個長期存在的事實。
這 就是為什么你應(yīng)該按照最小化的網(wǎng)絡(luò)訪問和帶寬來編寫你的代碼。你不能假設(shè)網(wǎng)絡(luò)是快速的,所以,你應(yīng)該總是計劃它是慢的。如果你的用戶碰巧在一個快速的網(wǎng)絡(luò) 上,那很好——他們的用戶體驗會提升。你要避免相反的情形:在不同的地點和不同時間,應(yīng)用程序有時可用,有時慢得令人抓狂,這樣的程序可能不會受歡迎。
還 有一個潛在的地方是,如果你正在使用模擬器,那么你很容易受它迷糊,因為模擬器使用電腦的網(wǎng)絡(luò)連接。這比手機(jī)網(wǎng)絡(luò)快很多,所以,你需要修改模擬器設(shè)定來模 擬較低的網(wǎng)絡(luò)速度。你可以在 Eclipse中做到這點,在啟動選項的模擬器設(shè)置頁里設(shè)置或者在啟動模擬器時通過命令行選項設(shè)置。
Android 可以支持多種外觀形狀。也就是說,一些Android設(shè)備擁有全“QWERTY”鍵盤,而其它可能會有40鍵、12鍵或其它鍵盤設(shè)置。同樣的,一些設(shè)備可 能有觸摸屏,但一些也會沒有。當(dāng)創(chuàng)建你的應(yīng)用程序的時候,記住這一點。不要假定特定的鍵盤布局——除非你真的想限定你的應(yīng)用程序只運行在某些設(shè)備上。
如 果移動設(shè)備經(jīng)常插在墻上,那么,它也就不是很“移動”。移動設(shè)備是電池供電的,如果我們能讓每次充電的電池使用得更持久一些,那么每個人都會更加開心—— 尤其是用戶。
其中兩大耗電硬件是處理器和無線;這也就是我們?yōu)槭裁匆獙懕M可能少做工作、盡可能少去使用網(wǎng)絡(luò)的應(yīng)用程序的重要原因。
如 何讓你的應(yīng)用程序最小化的占用處理器,歸根結(jié)底還是要寫高效代碼。為了減少無線的電量消耗,確保對錯誤條件進(jìn)行正確的處理,并只獲取你要的東西。例如,如 果某一個網(wǎng)絡(luò)操作失敗了,不要不斷地進(jìn)行重試。如果失敗了一次,有可能是用戶不受歡迎,因此,如果你再以正確的方式操作,有可能還會失?。凰心阕龅亩际?在浪費電池。
用戶是相當(dāng)聰明的:如果你的程序高耗電,他們是一定會發(fā)現(xiàn)的。到那個時點,你唯一可以確定的是,你的程序?qū)⒑芸毂恍遁d掉。
第三篇:android教程JNI開發(fā)疑點總結(jié)
android教程JNI開發(fā)疑點總結(jié)
很多Android新手對于JNI開發(fā)過程中的疑問不是很清楚,根據(jù)android123@163.com郵箱中反饋的內(nèi)容我們整理如下:
1.JNI中,什么情況才處理jstring、jint、jobject這樣的類型,其實通過NDK開發(fā)Android C++應(yīng)用,大部分仍然是常規(guī)的cpp和h的標(biāo)準(zhǔn)寫法,只有需要和Java層通訊的方法才包含了類似JNIEXPORT void JNICALL XXX這樣的函數(shù),大多數(shù)的邏輯和標(biāo)準(zhǔn)C/C++沒有什么區(qū)別。
2.我有一個在Windows上開發(fā)好的dll能否在Android上使用呢? 這里Android開發(fā)網(wǎng)提醒大家,對于dll這樣的PE文件只能在Windows平臺下使用,而linux上的動態(tài)庫so文件如果是PC上的也無法通過JNI在Android上調(diào)用,由于CPU的指令不同,手機(jī)上必須使用ARM交叉編譯器生成才可以使用,而PC上的為x86或64位,即使是Hello World這樣代碼兼容性很強(qiáng),也必須在NDK中重新編譯才能在Android上使用。
3.學(xué)習(xí)JNI的基礎(chǔ)是什么,或者說什么順序?qū)W習(xí)? 這點Android123推薦大家先了解Java的類型,和內(nèi)部編碼,然后學(xué)習(xí)C/C++語言,對于NDK r5開始支持的C++語言,這里Android開發(fā)網(wǎng)要和大家說下了,如果需要在JNI中調(diào)用Java的類,你可以學(xué)習(xí)下反射機(jī)制,同時C++ STL在NDK r5開始支持,這樣開發(fā)應(yīng)用維護(hù)起來更方便些。最后看下NDK的Samples下載Android源碼Framework層基本上就沒有什么大問題了。
4.學(xué)習(xí)NDK最大的困難是什么? 這里Android123認(rèn)為,國內(nèi)網(wǎng)友大多數(shù)都在Windows下做開發(fā)工作,整個NDK環(huán)境需要Cygwin,同時mk這樣的makefile編譯腳本的手動編寫可能不是很友好,這點Android開發(fā)網(wǎng)已經(jīng)準(zhǔn)備了一整套的Android開發(fā)工具,將在近期公開,幫助大家在PC輔助開發(fā)Android應(yīng)用,同時常見問題提供了相應(yīng)的鏈接。
5.在Android JNI用處大嗎? 對于大多數(shù)開發(fā)者來說可能主要用于OpenGL游戲設(shè)計上,不過對于純運算,算法上C語言比Java有著很多天生的優(yōu)勢,這點不容置疑,多一門技術(shù)多一個出路嘛,整個Android源代碼十分龐大,開源的力量最終還是能打敗更封閉的Windows Phone和iOS的。
安卓資料,歡迎下載
第四篇:Android藍(lán)牙開發(fā)小結(jié)
學(xué)習(xí)之前先了解兩個基本概念:
一、RFCOMM協(xié)議:
一個基于歐洲電信標(biāo)準(zhǔn)協(xié)會ETSI07.10規(guī)程的串行線性仿真協(xié)議。此協(xié)議提供RS232控制和狀態(tài)信號,如基帶上的損壞,CTS以及數(shù)據(jù)信號等,為上層業(yè)務(wù)(如傳統(tǒng)的串行線纜應(yīng)用)提供了傳送能力。
RFCOMM是一個簡單傳輸協(xié)議,其目的是針對如何在兩個不同設(shè)備上的應(yīng)用之間保證一條完整的通信路徑,并在它們之間保持一通信段。
RFCOMM是為了兼容傳統(tǒng)的串口應(yīng)用,同時取代有線的通信方式,藍(lán)牙協(xié)議棧需要提供與有線串口一致的通信接口而開發(fā)出的協(xié)議。RFCOMM協(xié)議提供對基于L2CAP協(xié)議的串口仿真,基于ETSI07.10??芍С衷趦蓚€BT設(shè)備之間同時保持高達(dá)60路的通信連接。
RFCOMM只針對直接互連設(shè)備之間的連接,或者是設(shè)備與網(wǎng)絡(luò)接入設(shè)備之間的互連。通信兩端設(shè)備必須兼容于RFCOMM協(xié)議,有兩類設(shè)備:DTE(Data Terminal Endpoint,通信終端,如PC,PRINTER)和DCE(Data Circuit Endpoint,通信段的一部分,如Modem)。此兩類設(shè)備不作區(qū)分。
二、MAC硬件地址
MAC(Medium/MediaAccess Control, 介質(zhì)訪問控制)MAC地址是燒錄在NetworkInterfaceCard(網(wǎng)卡,NIC)里的.MAC地址,也叫硬件地址,是由48比特長(6字節(jié)),16進(jìn)制的數(shù)字組成.0-23位叫做組織唯一標(biāo)志符(organizationally unique,是識別LAN(局域網(wǎng))節(jié)點的標(biāo)識.24-47位是由廠家自己分配。其中第40位是組播地址標(biāo)志位。網(wǎng)卡的物理地址通常是由網(wǎng)卡生產(chǎn)廠家燒入網(wǎng)卡的EPROM(一種閃存芯片,通??梢酝ㄟ^程序擦寫),它存儲的是傳輸數(shù)據(jù)時真正賴以標(biāo)識發(fā)出數(shù)據(jù)的電腦和接收數(shù)據(jù)的主機(jī)的地址。
Android平臺提供的藍(lán)牙API去實現(xiàn)藍(lán)牙設(shè)備之間的通信,藍(lán)牙設(shè)備之間的通信主要包括了四個步驟:設(shè)置藍(lán)牙設(shè)備、尋找局域網(wǎng)內(nèi)可能或者匹配的設(shè)備、連接設(shè)備和設(shè)備之間的數(shù)據(jù)傳輸。以下是建立藍(lán)牙連接的所需要的一些基本類:
BluetoothAdapter類:代表了一個本地的藍(lán)牙適配器。它是所有藍(lán)牙交互的的入口點。利用它你可以發(fā)現(xiàn)其他藍(lán)牙設(shè)備,查詢綁定了的設(shè)備,使用已知的MAC地址實例化一個藍(lán)牙設(shè)備和建立一個BluetoothServerSocket(作為服務(wù)器端)來監(jiān)聽來自其他設(shè)備的連接。
BluetoothDevice類:代表了一個遠(yuǎn)端的藍(lán)牙設(shè)備,使用它請求遠(yuǎn)端藍(lán)牙設(shè)備連接或者獲取遠(yuǎn)端藍(lán)牙設(shè)備的名稱、地址、種類和綁定狀態(tài)。(其信息是封裝在bluetoothsocket中)。
Bluetoothsocket類:代表了一個藍(lán)牙套接字的接口(類似于tcp中的套接字),它是應(yīng)用程序通過輸入、輸出流與其他藍(lán)牙設(shè)備通信的連接點。
Blueboothserversocket類:代表打開服務(wù)連接來監(jiān)聽可能到來的連接請求(屬于server端),為了連接兩個藍(lán)牙設(shè)備必須有一個設(shè)備作為服務(wù)器打開一個服務(wù)套接字。當(dāng)遠(yuǎn)端設(shè)備發(fā)起連接連接請求的時候,并且已經(jīng)連接到了的時候,Blueboothserversocket類將會返回一個bluetoothsocket。
Bluetoothclass類:描述了一個藍(lán)牙設(shè)備的一般特點和能力。它的只讀屬性集定義了設(shè)備的主、次設(shè)備類和一些相關(guān)服務(wù)。然而,它并沒有準(zhǔn)確地描述所有該設(shè)備所支持的藍(lán)牙文件和服務(wù),而是作為對設(shè)備種類來說的一個小小暗示。下面說說具體的編程實現(xiàn) 1.啟動藍(lán)牙功能:
首先通過調(diào)用靜態(tài)方法getDefaultAdapter()獲取藍(lán)牙適配器BluetoothAdapter,以后你就可以使用該對象了。如果返回為空,the story is over。例如:
BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();if(mBluetoothAdapter == null){ // Device does not support Bluetooth } 其次,調(diào)用isEnabled()來查詢當(dāng)前藍(lán)牙設(shè)備的狀態(tài),如果返回為false,則表示藍(lán)牙設(shè)備沒有開啟,接下來你需要封裝一個ACTION_REQUEST_ENABLE請求到intent里面,調(diào)用startActivityForResult()方法使能藍(lán)牙設(shè)備,例如:
if(!mBluetoothAdapter.isEnabled()){ Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);}
2.查找設(shè)備:
使用BluetoothAdapter類里的方法,你可以查找遠(yuǎn)端設(shè)備(大概十米以內(nèi))或者查詢在你手機(jī)上已經(jīng)匹配(或者說綁定)的其他手機(jī)了。當(dāng)然需要確定對方藍(lán)牙設(shè)備已經(jīng)開啟或者已經(jīng)開啟了“被發(fā)現(xiàn)使能”功能(對方設(shè)備是可以被發(fā)現(xiàn)的是你能夠發(fā)起連接的前提條件)。如果該設(shè)備是可以被發(fā)現(xiàn)的,會反饋回來一些對方的設(shè)備信息,比如名字、MAC地址等,利用這些信息,你的設(shè)備就可以選擇去向?qū)Ψ匠跏蓟粋€連接。
如果你是第一次與該設(shè)備連接,那么一個配對的請求就會自動的顯示給用戶。當(dāng)設(shè)備配對好之后,他的一些基本信息(主要是名字和MAC)被保存下來并可以使用藍(lán)牙的API來讀取。使用已知的MAC地址就可以對遠(yuǎn)端的藍(lán)牙設(shè)備發(fā)起連接請求。
匹配好的設(shè)備和連接上的設(shè)備的不同點:匹配好只是說明對方設(shè)備發(fā)現(xiàn)了你的存在,并擁有一個共同的識別碼,并且可以連接。連接上:表示當(dāng)前設(shè)備共享一個RFCOMM信道并且兩者之間可以交換數(shù)據(jù)。也就是是說藍(lán)牙設(shè)備在建立RFCOMM信道之前,必須是已經(jīng)配對好了的。
3.查詢匹配好的設(shè)備:
在建立連接之前你必須先查詢配對好了的藍(lán)牙設(shè)備集(你周圍的藍(lán)牙設(shè)備可能不止一個),以便你選取哪一個設(shè)備進(jìn)行通信,例如你可以你可以查詢所有配對的藍(lán)牙設(shè)備,并使用一個數(shù)組適配器將其打印顯示出來:
Set
4.掃描設(shè)備:
掃描設(shè)備,只需要簡單的調(diào)用startDiscovery()方法,這個掃描的過程大概持續(xù)是12秒,應(yīng)用程序為了ACTION_FOUND動作需要注冊一個BroadcastReceiver來接受設(shè)備掃描到的信息。對于每一個設(shè)備,系統(tǒng)都會廣播ACTION_FOUND動作。例如: // Create a BroadcastReceiver for ACTION_FOUND private final BroadcastReceiver mReceiver = new BroadcastReceiver(){ public void onReceive(Context context, Intent intent){ String action = intent.getAction();// When discovery finds a device if(BluetoothDevice.ACTION_FOUND.equals(action)){ // Get the BluetoothDevice object from the Intent BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);// Add the name and address to an array adapter to show in a ListView mArrayAdapter.add(device.getName()+ “n” + device.getAddress());} } };// Register the BroadcastReceiver IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);registerReceiver(mReceiver, filter);// Don't forget to unregister during onDestroy 注意:掃描的過程是一個很耗費資源的過程,一旦你找到你需要的設(shè)備之后,在發(fā)起連接請求之前,確保你的程序調(diào)用cancelDiscovery()方法停止掃描。顯然,如果你已經(jīng)連接上一個設(shè)備,啟動掃描會減少你的通信帶寬。
5.使能被發(fā)現(xiàn):Enabling discoverability 如果你想使你的設(shè)備能夠被其他設(shè)備發(fā)現(xiàn),將ACTION_REQUEST_DISCOVERABLE動作封裝在intent中并調(diào)用startActivityForResult(Intent, int)方法就可以了。他將在不使你應(yīng)用程序退出的情況下使你的設(shè)備能夠被發(fā)現(xiàn)。缺省情況下的使能時間是120秒,當(dāng)然你可以可以通過添加EXTRA_DISCOVERABLE_DURATION字段來改變使能時間(最大不超過300秒,這是出于對你設(shè)備上的信息安全考慮)。例如: Intent discoverableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);discoverableIntent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 300);startActivity(discoverableIntent);運行該段代碼之后,系統(tǒng)會彈出一個對話框來提示你啟動設(shè)備使能被發(fā)現(xiàn)(此過程中如果你的藍(lán)牙功能沒有開啟,系統(tǒng)會幫你開啟),并且如果你準(zhǔn)備對該遠(yuǎn)端設(shè)備發(fā)現(xiàn)一個連接,你不需要開啟使能設(shè)備被發(fā)現(xiàn)功能,因為該功能只是在你的應(yīng)用程序作為服務(wù)器端的時候才需要。
6.連接設(shè)備:
在應(yīng)用程序中,想建立兩個藍(lán)牙設(shè)備之間的連接,必須實現(xiàn)客戶端和服務(wù)器端的代碼(因為任何一個設(shè)備都必須可以作為服務(wù)端或者客戶端)。一個開啟服務(wù)來監(jiān)聽,一個發(fā)起連接請求(使用服務(wù)器端設(shè)備的MAC地址)。當(dāng)他們都擁有一個藍(lán)牙套接字在同一RFECOMM信道上的時候,可以認(rèn)為他們之間已經(jīng)連接上了。服務(wù)端和客戶端通過不同的方式或其他們的藍(lán)牙套接字。當(dāng)一個連接監(jiān)聽到的時候,服務(wù)端獲取到藍(lán)牙套接字。當(dāng)客戶可打開一個FRCOMM信道給服務(wù)器端的時候,客戶端獲取到藍(lán)牙套接字。
注意:在此過程中,如果兩個藍(lán)牙設(shè)備還沒有配對好的,android系統(tǒng)會通過一個通知或者對話框的形式來通知用戶。RFCOMM連接請求會在用戶選擇之前阻塞。如下圖:
7.服務(wù)端的連接:
當(dāng)你想要連接兩臺設(shè)備時,一個必須作為服務(wù)端(通過持有一個打開的BluetoothServerSocket),目的是監(jiān)聽外來連接請求,當(dāng)監(jiān)聽到以后提供一個連接上的BluetoothSocket給客戶端,當(dāng)客戶端從BluetoothServerSocket得到BluetoothSocket以后就可以銷毀BluetoothServerSocket,除非你還想監(jiān)聽更多的連接請求。
建立服務(wù)套接字和監(jiān)聽連接的基本步驟:
首先通過調(diào)用listenUsingRfcommWithServiceRecord(String, UUID)方法來獲取BluetoothServerSocket對象,參數(shù)String代表了該服務(wù)的名稱,UUID代表了和客戶端連接的一個標(biāo)識(128位格式的字符串ID,相當(dāng)于PIN碼),UUID必須雙方匹配才可以建立連接。其次調(diào)用accept()方法來監(jiān)聽可能到來的連接請求,當(dāng)監(jiān)聽到以后,返回一個連接上的藍(lán)牙套接字BluetoothSocket。最后,在監(jiān)聽到一個連接以后,需要調(diào)用close()方法來關(guān)閉監(jiān)聽程序。(一般藍(lán)牙設(shè)備之間是點對點的傳輸)
注意:accept()方法不應(yīng)該放在主Acitvity里面,因為它是一種阻塞調(diào)用(在沒有監(jiān)聽到連接請求之前程序就一直停在那里)。解決方法是新建一個線程來管理。例如: private class AcceptThread extends Thread { private final BluetoothServerSocket mmServerSocket;public AcceptThread(){ // Use a temporary object that is later assigned to mmServerSocket, // because mmServerSocket is final BluetoothServerSocket tmp = null;try { // MY_UUID is the app's UUID string, also used by theclient code tmp = mAdapter.listenUsingRfcommWithServiceRecord(NAME, MY_UUID);} catch(IOException e){ } mmServerSocket = tmp;} public void run(){ BluetoothSocket socket = null;// Keep listening until exception occurs or a socket is returned while(true){ try { socket = mmServerSocket.accept();} catch(IOException e){ break;} // If a connection was accepted if(socket!= null){ // Do work to manage the connection(in a separate thread)manageConnectedSocket(socket);mmServerSocket.close();break;} } } /** Will cancel the listening socket, and cause the thread to finish */ public void cancel(){ try { mmServerSocket.close();} catch(IOException e){ } } }
8.客戶端的連接:
為了初始化一個與遠(yuǎn)端設(shè)備的連接,需要先獲取代表該設(shè)備的一個BluetoothDevice對象。通過BluetoothDevice對象來獲取BluetoothSocket并初始化連接,具體步驟:
使用BluetoothDevice對象里的方法createRfcommSocketToServiceRecord(UUID)來獲取BluetoothSocket。UUID就是匹配碼。然后,調(diào)用connect()方法來。如果遠(yuǎn)端設(shè)備接收了該連接,他們將在通信過程中共享RFFCOMM信道,并且connect()方法返回。例如: private class ConnectThread extends Thread { private final BluetoothSocket mmSocket;private final BluetoothDevice mmDevice;public ConnectThread(BluetoothDevice device){ // Use a temporary object that is later assigned to mmSocket, // because mmSocket is final BluetoothSocket tmp = null;mmDevice = device;// Get a BluetoothSocket to connect with the given BluetoothDevice try { // MY_UUID is the app's UUID string, also used by the server code tmp = device.createRfcommSocketToServiceRecord(MY_UUID);} catch(IOException e){ } mmSocket = tmp;}
public void run(){ // Cancel discovery because it will slow down the connection mAdapter.cancelDiscovery();try { // Connect the device through the socket.This will block // until it succeeds or throws an exception mmSocket.connect();} catch(IOException connectException){ // Unable to connect;close the socket and get out try { mmSocket.close();} catch(IOException closeException){ } return;} // Do work to manage the connection(in a separate thread)manageConnectedSocket(mmSocket);}
注意:conncet()方法也是阻塞調(diào)用,一般建立一個獨立的線程中來調(diào)用該方法。在設(shè)備discover過程中不應(yīng)該發(fā)起連接connect(),這樣會明顯減慢速度以至于連接失敗。且數(shù)據(jù)傳輸完成只有調(diào)用close()方法來關(guān)閉連接,這樣可以節(jié)省系統(tǒng)內(nèi)部資源。
9.管理連接(主要涉及數(shù)據(jù)的傳輸):
當(dāng)設(shè)備連接上以后,每個設(shè)備都擁有各自的BluetoothSocket?,F(xiàn)在你就可以實現(xiàn)設(shè)備之間數(shù)據(jù)的共享了。
1> 首先通過調(diào)用getInputStream()和getOutputStream()方法來獲取輸入輸出流。然后通過調(diào)用read(byte[])和write(byte[]).方法來讀取或者寫數(shù)據(jù)。
2> 實現(xiàn)細(xì)節(jié):以為讀取和寫操作都是阻塞調(diào)用,需要建立一個專用現(xiàn)成來管理。3>
private class ConnectedThread extends Thread { private final BluetoothSocket mmSocket;private final InputStream mmInStream;private final OutputStream mmOutStream;public ConnectedThread(BluetoothSocket socket){ mmSocket = socket;InputStream tmpIn = null;OutputStream tmpOut = null;// Get the input and output streams, using temp objects because // member streams are final try { tmpIn = socket.getInputStream();tmpOut = socket.getOutputStream();} catch(IOException e){ } mmInStream = tmpIn;mmOutStream = tmpOut;} public void run(){ byte[] buffer = new byte[1024];// buffer store for the stream int bytes;// bytes returned from read()// Keep listening to the InputStream until an exception occurs while(true){ try { // Read from the InputStream bytes = mmInStream.read(buffer);// Send the obtained bytes to the UI Activity mHandler.obtainMessage(MESSAGE_READ, bytes,-1, buffer).sendToTarget();} catch(IOException e){ break;} } } /* Call this from the main Activity to send data to the remote device */ public void write(byte[] bytes){ try { mmOutStream.write(bytes);} catch(IOException e){ } } /* Call this from the main Activity to shutdown the connection */ public void cancel(){ try { mmSocket.close();} catch(IOException e){ } } }
第五篇:Android 嵌入式開發(fā)心得體會
Android 嵌入式開發(fā)心得體會
剛開始接觸Android感覺到它很有意思,在界面開發(fā)上和web也可以形成了相通的架構(gòu),更加方便,視覺上也是非常的酷,在前期我通過的大量的Android SDK開發(fā)范例大全中的例子以及Android提供的APIDEMOS進(jìn)行學(xué)習(xí),盡管例子之間的連接比較零散,不過通過這些例子的學(xué)習(xí)我可以學(xué)習(xí)到了很多和以前java上相通的思想,因為Android在現(xiàn)在也是全新的技術(shù)和框架,在其中我也學(xué)到了如何用單例模式、工廠模式等常用的設(shè)計模式進(jìn)行學(xué)習(xí),通過API進(jìn)行開發(fā)客戶端,對Request發(fā)送,Response處理中通過比較方便的JSON對象傳輸,以及對XML、JSON、圖片、業(yè)務(wù)等下載處理,對API接口調(diào)用等問題處理,學(xué)習(xí)Android心得體會。首先在界面上,我們同樣可以通過不同布局進(jìn)行設(shè)計非??岬慕缑妫@些界面可以通過include進(jìn)行引入,和jsp、html也有相通的地方,同樣在android上可以用到自定義的樣式這和css也有比較相通的地方,我們可以通過一些公用的方法寫個BaseActivity這個基類,通過繼承方式比較不錯的實現(xiàn)了Activity的界面,因為這樣你可以Header(頭部)和Footer(尾部)進(jìn)行處理一些觸發(fā)事件或者特效等,布局模式以相對模式為主,線線布局模式可以在比較簡單的include進(jìn)行完成,最重要的一點就是:我們可以自己通過重寫方法或者通過實現(xiàn)View或者Layout等類進(jìn)行擴(kuò)充項目需要的布局(或者控件),在學(xué)習(xí)界面中,我發(fā)現(xiàn)Android為我們提供了很好的類似反射機(jī)制,通過Layout文件夾下的配置文件,可以快速的形成界面,在配置文件可以設(shè)置屬性或者樣式都是很快捷方便。對比較特殊的界面也可以通過處理嵌入到指定的界面,同樣你可以通過java代碼直接創(chuàng)建View進(jìn)行添加,不過這種方式比較復(fù)雜。對一些點擊、選中、按鍵等處理的事件,界面之間的跳轉(zhuǎn)Intent管理,通過Bundle對數(shù)據(jù)在界面之間進(jìn)行傳輸。其次在手機(jī)交互式通信服務(wù)中,學(xué)習(xí)了Android手機(jī)之間進(jìn)行短信發(fā)送、廣播、對廣播的監(jiān)聽、服務(wù)等,在Service類中沒有context,可以通過Handler來每秒反復(fù)運行,自動送出系統(tǒng)廣播信息,同時在這里我們也知道可以設(shè)計一個常用的變量類,設(shè)計一個當(dāng)前的CurrentActivity這個變量進(jìn)行控制,進(jìn)行處理。
總而言之,Android設(shè)計還是比較自由開闊的,只要有想法,自己動手便能實現(xiàn)。