Android系統(tǒng)開發(fā)全攻略(二)
當(dāng)發(fā)現(xiàn)藍牙功能未啟用時,如下調(diào)用設(shè)置啟用藍牙:
如果發(fā)現(xiàn)當(dāng)前設(shè)備沒有打開對外可見模式,則傳遞 Intent 來調(diào)用打開可發(fā)現(xiàn)模式,代碼如下:
BluetoothDevice 類,此為對應(yīng)的遠程藍牙 Device
createRfcommSocketToServiceRecord() :創(chuàng)建該 Device 的 socket 。
BluetoothSocket 類
connect() :請求連接藍牙。
getInputStream() :得到輸入流,用于接收遠程方信息。
getOutputStream() :得到輸出流,發(fā)送給遠程方的信息。
close() :關(guān)閉藍牙連接。
InputStream 類:
read(byte[]) :以阻塞方式讀取輸入流。
OutputStream 類:
write(byte[]) :將信息寫入該輸出流,發(fā)送給遠程。
3. BluetoothChat 例程分析
Google 提供的關(guān)于 Bluetooth 開發(fā)的例程為 Bluetoothchat ,使用截圖可見本文一開始。除去配置及 ui 定義等文件,主程序文件共三個: BluetoothChat.java 、 BluetoothChatService.java 以及 DeviceListActivity.java ,詳細功能可見下面的描述。
3.1. 整體調(diào)用關(guān)系序列圖
3.2. BluetoothChat.java
例程的主 Activity 。 onCreate() 得到本地 BluetoothAdapter 設(shè)備,檢查是否支持。 onStart() 中檢查是否啟用藍牙,并請求啟用,然后執(zhí)行 setupChat() 。 setupChat() 中先對界面中的控件進行初始化增加點擊監(jiān)聽器等,然創(chuàng)建 BluetoothChatService 對象,該對象在整個應(yīng)用過程中存在,并執(zhí)行藍牙連接建立、消息發(fā)送接受等實際的行為。
3.3. BluetoothChatService.java
public synchronized void start() :
開啟 mAcceptThread 線程,由于樣例程序是僅 2 人的聊天過程,故之前先檢測 mConnectThread 和 mConnectedThread 是否運行,運行則先退出這些線程。
public synchronized void connect(BluetoothDevice device) :
取消 CONNECTING 和 CONNECTED 狀態(tài)下的相關(guān)線程,然后運行新的 mConnectThread 線程。
public synchronized void connected(BluetoothSocket socket, BluetoothDevice device) :
開啟一個 ConnectedThread 來管理對應(yīng)的當(dāng)前連接。之前先取消任意現(xiàn)存的 mConnectThread 、 mConnectedThread 、 mAcceptThread 線程,然后開啟新 mConnectedThread ,傳入當(dāng)前剛剛接受的 socket 連接。最后通過 Handler 來通知 UI 連接 OK 。
public synchronized void stop() :
停止所有相關(guān)線程,設(shè)當(dāng)前狀態(tài)為 NONE 。
public void write(byte[] out) :
在 STATE_CONNECTED 狀態(tài)下,調(diào)用 mConnectedThread 里的 write 方法,寫入 byte 。
private void connectionFailed() :
連接失敗的時候處理,通知 ui ,并設(shè)為 STATE_LISTEN 狀態(tài)。
private void connectionLost() :
當(dāng)連接失去的時候,設(shè)為 STATE_LISTEN 狀態(tài)并通知 ui 。
內(nèi)部類:
private class AcceptThread extends Thread :
創(chuàng)建監(jiān)聽線程,準(zhǔn)備接受新連接。使用阻塞方式,調(diào)用 BluetoothServerSocket.accept() 。提供 cancel 方法關(guān)閉 socket 。
private class ConnectThread extends Thread :
這是定義的連接線程,專門用來對外發(fā)出連接對方藍牙的請求和處理流程。構(gòu)造函數(shù)里通過 BluetoothDevice.createRfcommSocketToServiceRecord() ,從待連接的 device 產(chǎn)生 BluetoothSocket. 然后在 run 方法中 connect ,成功后調(diào)用 BluetoothChatSevice 的 connected() 方法。定義 cancel() 在關(guān)閉線程時能夠關(guān)閉相關(guān) socket 。
private class ConnectedThread extends Thread :
這個是雙方藍牙連接后一直運行的線程。構(gòu)造函數(shù)中設(shè)置輸入輸出流。 Run 方法中使用阻塞模式的 InputStream.read() 循環(huán)讀取輸入流, 然后 post 到 UI 線程中更新聊天消息。也提供了 write() 將聊天消息寫入輸出流傳輸至對方,傳輸成功后回寫入 UI 線程。最后 cancel() 關(guān)閉連接的 socket 。
3.4. DeviceListActivity.java
該類包含 UI 和操作的 Activity 類,作用是得到系統(tǒng)默認(rèn)藍牙設(shè)備的已配對設(shè)備列表,以及搜索出的未配對的新設(shè)備的列表。然后提供點擊后發(fā)出連接設(shè)備請求的功能。
除了 RFCOMM 通信外, Android 上關(guān)于 Bluetooth 的還有 SDP 、 GAP 、耳機設(shè)備連接等內(nèi)容,本文還未涉及,將會隨著藍牙相關(guān) API 在新版本中的進一步完善來學(xué)習(xí)使用。
四、Android智能手機平臺多分辨率解決方案詳解
摘 要:近年來,智能手機的功能越來越強大,移動終端應(yīng)用程序?qū)映霾桓F,移動互聯(lián)網(wǎng)改變?nèi)藗兊纳睢?a class="contentlabel" href="http://m.butianyuan.cn/news/listbylabel/label/Android">Android 系統(tǒng)是開放手機聯(lián)盟推出的一款開源的手機操作系統(tǒng),正是由于其開放性,沒有采用Windows PhONe7 類似的硬件限定標(biāo)準(zhǔn),目前基于Android系統(tǒng)的機型越來越多,一些硬件指標(biāo)出現(xiàn)了混亂的局面,其中最明顯的就是屏幕分辨率的問題。如何使開發(fā)者的應(yīng)用程序盡可能多地適應(yīng)多種分辨率,正是本文要講述的問題。文章首先介紹Android 的系統(tǒng)架構(gòu),然后介紹Android 平臺中分辨率的相關(guān)術(shù)語,之后重點講述在開發(fā)過程中如何部署資源以及所應(yīng)遵循的原則,最后給出測試多分辨率兼容性的方法。
0 引 言
2007 年11 月,Google 公司發(fā)布基于Linux2.6 內(nèi)核的移動終端操作系統(tǒng)- Android, 由于其開源性, 得到很多手機廠商的追捧和應(yīng)用開發(fā)者的青睞。近年來智能手機發(fā)展迅速,運行速度、存儲容量和可靠性等指標(biāo)有了顯著提高[1],當(dāng)今的智能手機用戶對應(yīng)用軟件的舒適性和美觀性有了更大的期望,應(yīng)用程序界面友好性已經(jīng)越來越重要。但是由于Android 的開源性,硬件廠商屏幕分辨率不統(tǒng)一,據(jù)統(tǒng)計目前市場上Android系統(tǒng)手機的分辨率有10 余種,分辨率分布如此廣泛使得開發(fā)者在處理多分辨率適應(yīng)方面遇到了不少難題。文章首先介紹Android 平臺的系統(tǒng)架構(gòu)及資源管理方法,之后介紹目前開發(fā)者在處理多分辨率時采用的方法,而后重點分析Android 平臺資源加載機制并且結(jié)合實例給出多分辨率的處理步驟及技巧,最后介紹測試多分辨率效果的方法。
1 Android 平臺簡介
Android 是一個包括操作系統(tǒng)、中間件和關(guān)鍵應(yīng)用的移動設(shè)備軟件堆[2],Android 系統(tǒng)和其他系統(tǒng)一樣,采用分層的架構(gòu)。由下至上依此為Linux 操作系統(tǒng)和驅(qū)動、程序庫及Android 運行時環(huán)境、應(yīng)用程序框架層、應(yīng)用層。 Android 應(yīng)用程序的基本組件有Activity、Intent、BroadcaSTReceiver、Service 四種,各個組件的配置信息以及權(quán)限管理、版本管理等配置信息都保存在AndroidManifest.xml 中。
1.1 Android 應(yīng)用程序資源管理
手機界面上加載的圖片是Android 資源的一種,除此之外還有XML 資源(anim.xml layout.xml 等) 以及原數(shù)據(jù)文件( 音視頻文件等)[3]。新建一個HelloAndroid 的Android 應(yīng)用程序,默認(rèn)生成的文件架構(gòu)包含src,gen,assets,res 等文件夾,以及AndroidManifest.xml 配置文件。src 文件夾中保存的是Android 源代碼,res 文件夾代表應(yīng)用程序需要使用到的資源文件,gen 包中包含R.java 文件。Res 文件夾中包含的所有資源文件都對應(yīng)在R.java 中。
當(dāng)開發(fā)者在res/ 目錄中任何一個子目錄中添加相應(yīng)類型的文件之后,ADT 會在R.java 文件中相應(yīng)的匿名內(nèi)部類中國自動生成一條靜態(tài)int 類型的常量,對添加的文件進行索引。
Android 系統(tǒng)采取這種架構(gòu)使視圖等資源文件與控制代碼分離,實現(xiàn)松耦合。然而可以使用R.java 文件在代碼中對相應(yīng)的資源文件進行存取,靈活操作。
1.2 一般多分辨率處理方法及其缺點
1.2.1 圖片縮放
基于當(dāng)前屏幕的精度,平臺自動加載任何未經(jīng)縮放的限定尺寸和精度的圖片。如果圖片不匹配,平臺會加載默認(rèn)資源并且在放大或者縮小之后可以滿足當(dāng)前界面的顯示要求。例如,當(dāng)前為高精度屏幕,平臺會加載高精度資源(如HelloAndroid中drawable-hdpi 中的位圖資源),如果沒有,平臺會將中精度資源縮放至高精度,導(dǎo)致圖片顯示不清晰。
1.2.2 自動定義像素尺寸和位置
如果程序不支持多種精度屏幕,平臺會自動定義像素絕對位置和尺寸值等,這樣就能保證元素能和精度160 的屏幕上一樣能顯示出同樣尺寸的效果。例如,要讓W(xué)VGA 高精度屏幕和傳統(tǒng)的HVGA 屏幕一樣顯示同樣尺寸的圖片,當(dāng)程序不支持時,系統(tǒng)會對程序慌稱屏幕分辨率為320×480,在(10,10)到(100,100)的區(qū)域內(nèi)繪制圖形完成之后,系統(tǒng)會將圖形放大到(15,15)到(150,150)的屏幕顯示區(qū)域。
1.2.3 兼容更大尺寸的屏幕
當(dāng)前屏幕超過程序所支持屏幕的上限時,定義supportsscreens元素,這樣超出顯示的基準(zhǔn)線時,平臺在此顯示黑色的背景圖。例如,WVGA 中精度屏幕上,如程序不支持這樣的大屏幕,系統(tǒng)會謊稱是一個320×480 的,多余的顯示區(qū)域會被填充成黑色。
1.2.4 采用OpenGL 動態(tài)繪制圖片
Android 底層提供了OpenGL 的接口和方法,可以動態(tài)繪制圖片,但是這種方式對不熟悉計算機圖形學(xué)的開發(fā)者來講是一個很大的挑戰(zhàn)。一般開發(fā)游戲,采用OpenGL 方式。
1.2.5 多個apk 文件
Symbian 和傳統(tǒng)的J2ME 就是采用這種方式,為一款應(yīng)用提供多個分辨率版本,用戶根據(jù)自己的需求下載安裝相應(yīng)的可執(zhí)行文件。針對每一種屏幕單獨開發(fā)應(yīng)用程序不失為一種好方法,但是目前Google Market 對一個應(yīng)用程序多個分辨率版本的支持還不完善,開發(fā)者還是需要盡可能使用一個apk 文件適應(yīng)多個分辨率。
2 多分辨率處理方案詳解
2.1 基本術(shù)語介紹
2.1.1 屏幕尺寸
真正的物理尺寸,屏幕對角線的長度,單位是英寸。為了簡化起見,Android 把支持的所有物理尺寸分成了4 組:small,normal, large, extra large.
2.1.2 屏幕密度Density
一定物理范圍的像素的個數(shù),單位通常是dpi(dots perinch), 即每英寸的點數(shù)。例如一個低分辨率屏幕相對于高分辨率屏幕在一定的物理區(qū)域內(nèi)包含的像素點要少。為了簡化起見,Android 將所有的屏幕密度分成四組:low, medium,high 和extra high.
2.1.3 方向Orientation
從用戶視角來看的屏幕的方向,Portrait 縱向和Landscape 橫向。
2.1.4 分辨率Resolution
屏幕上所有的像素點數(shù)目,一般用480*800 的形式來表示。密度無關(guān)像素dp: Android 平臺中虛擬的像素單位,定義成一種密度無關(guān)的形式,像素px 和dp 的轉(zhuǎn)換公式為 px =dp*(dpi/160)。在界面開發(fā)中應(yīng)使用dp 作為像素單位,從而保證在不同的屏幕密度上控件所占的實際px 因密度而自動調(diào)整。
2.2 手機屏幕的分類
Android 采用兩種標(biāo)準(zhǔn)對屏幕進行分類。按照屏幕尺寸分為四組small, normal, large, extra large;按照屏幕密度分為四組 low, medium ,high 和extra high,其分界線如圖1所示。
圖1 Android 中的屏幕分類
為了優(yōu)化程序UI,讓其適應(yīng)多種分辨率并能清晰顯示,一般情況下需要為不同屏幕大小密度提供不同的圖片文件和對應(yīng)的布局文件,在運行的時候,Android 系統(tǒng)會根據(jù)當(dāng)前設(shè)備的屏幕大小及密度等信息,選擇加載其中一套匹配的資源加以運行,從而達到適應(yīng)多分辨率的效果。
2.3 Android 支持多分辨率原理及步驟
由以上分析,默認(rèn)的加載方式都不能很好地適應(yīng)不同的分辨率,Android 從1.6 開始支持多種分辨率的處理,原理簡而言之就是根據(jù)屏幕參數(shù),動態(tài)加載資源文件。在Android 項目文件結(jié)構(gòu)中,drawable 文件夾下包含三個子文件夾,分別為drawable-hdpi, drawable-mdpi, drawable-ldpi, 分別存放hdpi,mdpi,ldip 的位圖。應(yīng)用程序運行時,Android 系統(tǒng)會根據(jù)當(dāng)前設(shè)備的屏幕大小、分辨率、屏幕密度、方向、長寬比等信息,選擇相應(yīng)文件夾進行加載。Android 配置修飾符的定義規(guī)則如下:
1)在res 文件夾下新建目錄,命名為《resources_name》-《qualifier》 這種格式,其中《resources_name》 為標(biāo)準(zhǔn)資源名稱,例如drawable 或者layout;《qualifier》 即修飾符,指定對應(yīng)的屏幕參數(shù),比如normal/small/large,hdpi/mdpi/ldpi,land/port,long/notlong 等。
2)在步驟1 新建的文件夾中存入相應(yīng)的資源,比如位圖資源或者layout 資源,資源文件的名字必須與默認(rèn)資源文件的名字相同。例如:
3)Android 系統(tǒng)支持多分辨率的機制離不開Android-Manifest.xml 文件的supports-screen 元素,若應(yīng)用程序要適應(yīng)多種分辨率,需要將anyDensity 設(shè)置為true.
2.4 界面設(shè)計技巧
前面的部分已經(jīng)詳細講解了如何架構(gòu)應(yīng)用程序使其更好地適應(yīng)多種分辨率屏幕,此外,在界面設(shè)計和控制中我們還應(yīng)該掌握一些原則或者技巧,從而使應(yīng)用程序界面友好、適應(yīng)性強。
1)在XML layout 文件中定義長度的時候,最好使用wrap_content,fill_parent, 或者dp 進行描述,這樣可以保證在屏幕上面展示的時候有合適的大小。例如,一個view layout_width=“100dip”,在 HVGA@160 density 的設(shè)備上顯示100 個px,而在 WVGA@240 density 的設(shè)備上顯示150 個px,但是所占的物理尺寸時相同的。
2)在Activity 或者其他控制視圖加載的代碼處,不要使用像素單位的硬編碼。
3)不要使用AbsoluteLayout.絕對布局是由AndroidUI toolkit 提供的布局容器中的一種。但是與其他layout 不一樣的是,AbsoluteLayout 使用固定的位置表示,使得在不同的屏幕上面顯示效果不好,因此AbsoluteLayout 在sdk1.6 及以后的版本中被棄用了。
4)為不同屏幕密度的手機,提供不同的位圖資源,可以使得界面清晰無縮放。
3 多分辨率兼容性測試方案
在產(chǎn)品發(fā)行之前,要在所有的目標(biāo)手機上進行全面的測試。Android SDK 包含了一套測試多分辨率的機制??梢宰约憾ㄖ芶vd 作為應(yīng)用程序的測試環(huán)境,avd 會模擬真實機器的屏幕大小和密度。例如圖2 為模擬器的列表,可以將程序運行在這四個模擬器中進行多分辨率的測試。
圖2 虛擬機列表
4 結(jié)論
本文介紹Android 平臺的體系架構(gòu)和分辨率相關(guān)的術(shù)語,詳細論述資源加載原理和多分辨率處理的詳細流程,最后給出了測試應(yīng)用程序是否適應(yīng)多種分辨率的方法。結(jié)合本人實踐經(jīng)驗進行講述,內(nèi)容深入淺出,較完整地論述了如何使應(yīng)用程序盡可能多地適應(yīng)多種分辨率屏幕。
評論