第一篇:Android藍(lán)牙連接總結(jié)
藍(lán)牙連線時(shí)首先會(huì)定義一個(gè)專門用來(lái)連接的函數(shù)體BtconnectDevice,當(dāng)按下Btconnect(為一個(gè)Buttton名時(shí))時(shí),程序會(huì)判斷此時(shí)Btconnect鍵是什么狀態(tài),當(dāng)Btconnect鍵為連接狀態(tài)時(shí),因?yàn)榘戳薆tconnect鍵程序會(huì)斷開藍(lán)牙連接(調(diào)用BtconnectDevice函數(shù),注意此函數(shù)為有參函數(shù),實(shí)參為藍(lán)牙設(shè)備的連接地址),并且在Btconnect上顯示connect(代表此時(shí)用戶可以點(diǎn)選Btconnect連接藍(lán)牙);當(dāng)Btconnect鍵為斷開狀態(tài)時(shí)(程序通過(guò)判斷Btconnect上的字符是否為connect來(lái)判斷,因?yàn)閿嚅_藍(lán)牙連接時(shí),會(huì)讓Btconnect上顯示connect),此時(shí)按下Btconnect時(shí),程序會(huì)連接藍(lán)牙設(shè)備(把實(shí)參DeviceMAC傳給形參MACaddrofBTDevice,調(diào)用BtconnectDevice函數(shù),但此時(shí)不知道DeciceMAC是否有數(shù)據(jù),代表所以先要判斷,當(dāng)DeviceMAC大于0時(shí),DeciceMAC內(nèi)有數(shù)據(jù),可以連接,否則沒(méi)有,則不能連接)。
當(dāng)程序打開時(shí),設(shè)備會(huì)執(zhí)行初始化程序(Screen1.initialize,每當(dāng)程序頁(yè)面返回主界面時(shí),此函數(shù)即執(zhí)行一次,現(xiàn)在這樣理解),在程序中,首先要Btconnect按鍵功能失效(致Btconnect.Enable為False),然后把數(shù)據(jù)庫(kù)TinyDB1中標(biāo)簽名為StoredDevice處存儲(chǔ)的的藍(lán)牙設(shè)備地址給DeviceMAC(相當(dāng)于數(shù)組,TinyDB1相當(dāng)于數(shù)組名,StoredDevice相當(dāng)于數(shù)組下標(biāo),DeviceMAC為一個(gè)全局變量,各個(gè)程序模塊可分別調(diào)用它,并修改它,修改后的數(shù)據(jù)會(huì)影響別的程序模塊,不像局部變量,在這個(gè)程序中修改了變量,對(duì)別的程序不影響,APP Inventor中各個(gè)模塊程序中即使是局部變量,變量名也不可以相同,C和C++就不是這樣),然后程序去調(diào)用藍(lán)牙設(shè)備配對(duì)函數(shù)(lsDevicePaired)判斷是否與DeviceMAC這個(gè)設(shè)備地址配對(duì)上了,如果已配對(duì)成功,程序會(huì)首先使Btconnect按鈕功能可使用,同時(shí)lstDevice上顯示已配對(duì)的藍(lán)牙MAC地址;如果沒(méi)配對(duì)成功,則首先會(huì)清空DeviceMAC這個(gè)變量和StoredDevice處的數(shù)據(jù),并通過(guò)調(diào)用Notifier.ShowAlert函數(shù)來(lái)顯示配對(duì)失敗。請(qǐng)注意初始化程序中沒(méi)有使用藍(lán)牙連接函數(shù),它所要做的就是判斷Btconnect是否可使用,如果已配對(duì)成功,則Btconnect可使用,用戶可通過(guò)按此鍵來(lái)連接藍(lán)牙設(shè)備。
檢查錯(cuò)誤函數(shù),是在程序中發(fā)現(xiàn)錯(cuò)誤時(shí),程序會(huì)在屏幕上顯示相關(guān)錯(cuò)誤信息,供用戶查看信息,從而準(zhǔn)確的查出錯(cuò)誤。
當(dāng)要選擇連接哪一個(gè)藍(lán)牙設(shè)備時(shí),按下lstDevice但沒(méi)有選擇彈出來(lái)的項(xiàng)目時(shí)(要調(diào)用藍(lán)牙函數(shù)BluetoothClient1.AddressesAndNames,才能知道是否有藍(lán)牙設(shè)備)會(huì)調(diào)用lstDevice.BeforePicking函數(shù)。此函數(shù)首先會(huì)斷開藍(lán)牙連接,然后在Btconnect上顯示connect,表示藍(lán)牙現(xiàn)在可連接,然后調(diào)用藍(lán)牙函數(shù)BluetoothClient1.AddressesAndNames,將可用的藍(lán)牙設(shè)備名稱和地址放到 lstDevice列表中。然后用戶點(diǎn)選lstDevice列表中的項(xiàng)目,程序會(huì)調(diào)用lstDeviceAfterPicking函數(shù)。函數(shù)中會(huì)將剛才點(diǎn)選的數(shù)據(jù),放到DeviceMAC和TinyDB1中的StoredDevice中,lstDevice會(huì)顯示連接的藍(lán)牙設(shè)備的地址和MAC地址,然后使能Btconnect。
僅供參考,如有錯(cuò)誤,還是以實(shí)際操作結(jié)果為準(zhǔn)。
第二篇:Android藍(lán)牙開發(fā)小結(jié)
學(xué)習(xí)之前先了解兩個(gè)基本概念:
一、RFCOMM協(xié)議:
一個(gè)基于歐洲電信標(biāo)準(zhǔn)協(xié)會(huì)ETSI07.10規(guī)程的串行線性仿真協(xié)議。此協(xié)議提供RS232控制和狀態(tài)信號(hào),如基帶上的損壞,CTS以及數(shù)據(jù)信號(hào)等,為上層業(yè)務(wù)(如傳統(tǒng)的串行線纜應(yīng)用)提供了傳送能力。
RFCOMM是一個(gè)簡(jiǎn)單傳輸協(xié)議,其目的是針對(duì)如何在兩個(gè)不同設(shè)備上的應(yīng)用之間保證一條完整的通信路徑,并在它們之間保持一通信段。
RFCOMM是為了兼容傳統(tǒng)的串口應(yīng)用,同時(shí)取代有線的通信方式,藍(lán)牙協(xié)議棧需要提供與有線串口一致的通信接口而開發(fā)出的協(xié)議。RFCOMM協(xié)議提供對(duì)基于L2CAP協(xié)議的串口仿真,基于ETSI07.10。可支持在兩個(gè)BT設(shè)備之間同時(shí)保持高達(dá)60路的通信連接。
RFCOMM只針對(duì)直接互連設(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ì)訪問(wèn)控制)MAC地址是燒錄在NetworkInterfaceCard(網(wǎng)卡,NIC)里的.MAC地址,也叫硬件地址,是由48比特長(zhǎng)(6字節(jié)),16進(jìn)制的數(shù)字組成.0-23位叫做組織唯一標(biāo)志符(organizationally unique,是識(shí)別LAN(局域網(wǎng))節(jié)點(diǎn)的標(biāo)識(shí).24-47位是由廠家自己分配。其中第40位是組播地址標(biāo)志位。網(wǎng)卡的物理地址通常是由網(wǎng)卡生產(chǎn)廠家燒入網(wǎng)卡的EPROM(一種閃存芯片,通常可以通過(guò)程序擦寫),它存儲(chǔ)的是傳輸數(shù)據(jù)時(shí)真正賴以標(biāo)識(shí)發(fā)出數(shù)據(jù)的電腦和接收數(shù)據(jù)的主機(jī)的地址。
Android平臺(tái)提供的藍(lán)牙API去實(shí)現(xiàn)藍(lán)牙設(shè)備之間的通信,藍(lán)牙設(shè)備之間的通信主要包括了四個(gè)步驟:設(shè)置藍(lán)牙設(shè)備、尋找局域網(wǎng)內(nèi)可能或者匹配的設(shè)備、連接設(shè)備和設(shè)備之間的數(shù)據(jù)傳輸。以下是建立藍(lán)牙連接的所需要的一些基本類:
BluetoothAdapter類:代表了一個(gè)本地的藍(lán)牙適配器。它是所有藍(lán)牙交互的的入口點(diǎn)。利用它你可以發(fā)現(xiàn)其他藍(lán)牙設(shè)備,查詢綁定了的設(shè)備,使用已知的MAC地址實(shí)例化一個(gè)藍(lán)牙設(shè)備和建立一個(gè)BluetoothServerSocket(作為服務(wù)器端)來(lái)監(jiān)聽來(lái)自其他設(shè)備的連接。
BluetoothDevice類:代表了一個(gè)遠(yuǎn)端的藍(lán)牙設(shè)備,使用它請(qǐng)求遠(yuǎn)端藍(lán)牙設(shè)備連接或者獲取遠(yuǎn)端藍(lán)牙設(shè)備的名稱、地址、種類和綁定狀態(tài)。(其信息是封裝在bluetoothsocket中)。
Bluetoothsocket類:代表了一個(gè)藍(lán)牙套接字的接口(類似于tcp中的套接字),它是應(yīng)用程序通過(guò)輸入、輸出流與其他藍(lán)牙設(shè)備通信的連接點(diǎn)。
Blueboothserversocket類:代表打開服務(wù)連接來(lái)監(jiān)聽可能到來(lái)的連接請(qǐng)求(屬于server端),為了連接兩個(gè)藍(lán)牙設(shè)備必須有一個(gè)設(shè)備作為服務(wù)器打開一個(gè)服務(wù)套接字。當(dāng)遠(yuǎn)端設(shè)備發(fā)起連接連接請(qǐng)求的時(shí)候,并且已經(jīng)連接到了的時(shí)候,Blueboothserversocket類將會(huì)返回一個(gè)bluetoothsocket。
Bluetoothclass類:描述了一個(gè)藍(lán)牙設(shè)備的一般特點(diǎn)和能力。它的只讀屬性集定義了設(shè)備的主、次設(shè)備類和一些相關(guān)服務(wù)。然而,它并沒(méi)有準(zhǔn)確地描述所有該設(shè)備所支持的藍(lán)牙文件和服務(wù),而是作為對(duì)設(shè)備種類來(lái)說(shuō)的一個(gè)小小暗示。下面說(shuō)說(shuō)具體的編程實(shí)現(xiàn) 1.啟動(dòng)藍(lán)牙功能:
首先通過(guò)調(diào)用靜態(tài)方法getDefaultAdapter()獲取藍(lán)牙適配器BluetoothAdapter,以后你就可以使用該對(duì)象了。如果返回為空,the story is over。例如:
BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();if(mBluetoothAdapter == null){ // Device does not support Bluetooth } 其次,調(diào)用isEnabled()來(lái)查詢當(dāng)前藍(lán)牙設(shè)備的狀態(tài),如果返回為false,則表示藍(lán)牙設(shè)備沒(méi)有開啟,接下來(lái)你需要封裝一個(gè)ACTION_REQUEST_ENABLE請(qǐng)求到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))或者查詢?cè)谀闶謾C(jī)上已經(jīng)匹配(或者說(shuō)綁定)的其他手機(jī)了。當(dāng)然需要確定對(duì)方藍(lán)牙設(shè)備已經(jīng)開啟或者已經(jīng)開啟了“被發(fā)現(xiàn)使能”功能(對(duì)方設(shè)備是可以被發(fā)現(xiàn)的是你能夠發(fā)起連接的前提條件)。如果該設(shè)備是可以被發(fā)現(xiàn)的,會(huì)反饋回來(lái)一些對(duì)方的設(shè)備信息,比如名字、MAC地址等,利用這些信息,你的設(shè)備就可以選擇去向?qū)Ψ匠跏蓟粋€(gè)連接。
如果你是第一次與該設(shè)備連接,那么一個(gè)配對(duì)的請(qǐng)求就會(huì)自動(dòng)的顯示給用戶。當(dāng)設(shè)備配對(duì)好之后,他的一些基本信息(主要是名字和MAC)被保存下來(lái)并可以使用藍(lán)牙的API來(lái)讀取。使用已知的MAC地址就可以對(duì)遠(yuǎn)端的藍(lán)牙設(shè)備發(fā)起連接請(qǐng)求。
匹配好的設(shè)備和連接上的設(shè)備的不同點(diǎn):匹配好只是說(shuō)明對(duì)方設(shè)備發(fā)現(xiàn)了你的存在,并擁有一個(gè)共同的識(shí)別碼,并且可以連接。連接上:表示當(dāng)前設(shè)備共享一個(gè)RFCOMM信道并且兩者之間可以交換數(shù)據(jù)。也就是是說(shuō)藍(lán)牙設(shè)備在建立RFCOMM信道之前,必須是已經(jīng)配對(duì)好了的。
3.查詢匹配好的設(shè)備:
在建立連接之前你必須先查詢配對(duì)好了的藍(lán)牙設(shè)備集(你周圍的藍(lán)牙設(shè)備可能不止一個(gè)),以便你選取哪一個(gè)設(shè)備進(jìn)行通信,例如你可以你可以查詢所有配對(duì)的藍(lán)牙設(shè)備,并使用一個(gè)數(shù)組適配器將其打印顯示出來(lái):
Set
4.掃描設(shè)備:
掃描設(shè)備,只需要簡(jiǎn)單的調(diào)用startDiscovery()方法,這個(gè)掃描的過(guò)程大概持續(xù)是12秒,應(yīng)用程序?yàn)榱薃CTION_FOUND動(dòng)作需要注冊(cè)一個(gè)BroadcastReceiver來(lái)接受設(shè)備掃描到的信息。對(duì)于每一個(gè)設(shè)備,系統(tǒng)都會(huì)廣播ACTION_FOUND動(dòng)作。例如: // 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 注意:掃描的過(guò)程是一個(gè)很耗費(fèi)資源的過(guò)程,一旦你找到你需要的設(shè)備之后,在發(fā)起連接請(qǐng)求之前,確保你的程序調(diào)用cancelDiscovery()方法停止掃描。顯然,如果你已經(jīng)連接上一個(gè)設(shè)備,啟動(dòng)掃描會(huì)減少你的通信帶寬。
5.使能被發(fā)現(xiàn):Enabling discoverability 如果你想使你的設(shè)備能夠被其他設(shè)備發(fā)現(xiàn),將ACTION_REQUEST_DISCOVERABLE動(dòng)作封裝在intent中并調(diào)用startActivityForResult(Intent, int)方法就可以了。他將在不使你應(yīng)用程序退出的情況下使你的設(shè)備能夠被發(fā)現(xiàn)。缺省情況下的使能時(shí)間是120秒,當(dāng)然你可以可以通過(guò)添加EXTRA_DISCOVERABLE_DURATION字段來(lái)改變使能時(shí)間(最大不超過(guò)300秒,這是出于對(duì)你設(shè)備上的信息安全考慮)。例如: Intent discoverableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);discoverableIntent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 300);startActivity(discoverableIntent);運(yùn)行該段代碼之后,系統(tǒng)會(huì)彈出一個(gè)對(duì)話框來(lái)提示你啟動(dòng)設(shè)備使能被發(fā)現(xiàn)(此過(guò)程中如果你的藍(lán)牙功能沒(méi)有開啟,系統(tǒng)會(huì)幫你開啟),并且如果你準(zhǔn)備對(duì)該遠(yuǎn)端設(shè)備發(fā)現(xiàn)一個(gè)連接,你不需要開啟使能設(shè)備被發(fā)現(xiàn)功能,因?yàn)樵摴δ苤皇窃谀愕膽?yīng)用程序作為服務(wù)器端的時(shí)候才需要。
6.連接設(shè)備:
在應(yīng)用程序中,想建立兩個(gè)藍(lán)牙設(shè)備之間的連接,必須實(shí)現(xiàn)客戶端和服務(wù)器端的代碼(因?yàn)槿魏我粋€(gè)設(shè)備都必須可以作為服務(wù)端或者客戶端)。一個(gè)開啟服務(wù)來(lái)監(jiān)聽,一個(gè)發(fā)起連接請(qǐng)求(使用服務(wù)器端設(shè)備的MAC地址)。當(dāng)他們都擁有一個(gè)藍(lán)牙套接字在同一RFECOMM信道上的時(shí)候,可以認(rèn)為他們之間已經(jīng)連接上了。服務(wù)端和客戶端通過(guò)不同的方式或其他們的藍(lán)牙套接字。當(dāng)一個(gè)連接監(jiān)聽到的時(shí)候,服務(wù)端獲取到藍(lán)牙套接字。當(dāng)客戶可打開一個(gè)FRCOMM信道給服務(wù)器端的時(shí)候,客戶端獲取到藍(lán)牙套接字。
注意:在此過(guò)程中,如果兩個(gè)藍(lán)牙設(shè)備還沒(méi)有配對(duì)好的,android系統(tǒng)會(huì)通過(guò)一個(gè)通知或者對(duì)話框的形式來(lái)通知用戶。RFCOMM連接請(qǐng)求會(huì)在用戶選擇之前阻塞。如下圖:
7.服務(wù)端的連接:
當(dāng)你想要連接兩臺(tái)設(shè)備時(shí),一個(gè)必須作為服務(wù)端(通過(guò)持有一個(gè)打開的BluetoothServerSocket),目的是監(jiān)聽外來(lái)連接請(qǐng)求,當(dāng)監(jiān)聽到以后提供一個(gè)連接上的BluetoothSocket給客戶端,當(dāng)客戶端從BluetoothServerSocket得到BluetoothSocket以后就可以銷毀BluetoothServerSocket,除非你還想監(jiān)聽更多的連接請(qǐng)求。
建立服務(wù)套接字和監(jiān)聽連接的基本步驟:
首先通過(guò)調(diào)用listenUsingRfcommWithServiceRecord(String, UUID)方法來(lái)獲取BluetoothServerSocket對(duì)象,參數(shù)String代表了該服務(wù)的名稱,UUID代表了和客戶端連接的一個(gè)標(biāo)識(shí)(128位格式的字符串ID,相當(dāng)于PIN碼),UUID必須雙方匹配才可以建立連接。其次調(diào)用accept()方法來(lái)監(jiān)聽可能到來(lái)的連接請(qǐng)求,當(dāng)監(jiān)聽到以后,返回一個(gè)連接上的藍(lán)牙套接字BluetoothSocket。最后,在監(jiān)聽到一個(gè)連接以后,需要調(diào)用close()方法來(lái)關(guān)閉監(jiān)聽程序。(一般藍(lán)牙設(shè)備之間是點(diǎn)對(duì)點(diǎn)的傳輸)
注意:accept()方法不應(yīng)該放在主Acitvity里面,因?yàn)樗且环N阻塞調(diào)用(在沒(méi)有監(jiān)聽到連接請(qǐng)求之前程序就一直停在那里)。解決方法是新建一個(gè)線程來(lái)管理。例如: 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.客戶端的連接:
為了初始化一個(gè)與遠(yuǎn)端設(shè)備的連接,需要先獲取代表該設(shè)備的一個(gè)BluetoothDevice對(duì)象。通過(guò)BluetoothDevice對(duì)象來(lái)獲取BluetoothSocket并初始化連接,具體步驟:
使用BluetoothDevice對(duì)象里的方法createRfcommSocketToServiceRecord(UUID)來(lái)獲取BluetoothSocket。UUID就是匹配碼。然后,調(diào)用connect()方法來(lái)。如果遠(yuǎn)端設(shè)備接收了該連接,他們將在通信過(guò)程中共享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)用,一般建立一個(gè)獨(dú)立的線程中來(lái)調(diào)用該方法。在設(shè)備discover過(guò)程中不應(yīng)該發(fā)起連接connect(),這樣會(huì)明顯減慢速度以至于連接失敗。且數(shù)據(jù)傳輸完成只有調(diào)用close()方法來(lái)關(guān)閉連接,這樣可以節(jié)省系統(tǒng)內(nèi)部資源。
9.管理連接(主要涉及數(shù)據(jù)的傳輸):
當(dāng)設(shè)備連接上以后,每個(gè)設(shè)備都擁有各自的BluetoothSocket。現(xiàn)在你就可以實(shí)現(xiàn)設(shè)備之間數(shù)據(jù)的共享了。
1> 首先通過(guò)調(diào)用getInputStream()和getOutputStream()方法來(lái)獲取輸入輸出流。然后通過(guò)調(diào)用read(byte[])和write(byte[]).方法來(lái)讀取或者寫數(shù)據(jù)。
2> 實(shí)現(xiàn)細(xì)節(jié):以為讀取和寫操作都是阻塞調(diào)用,需要建立一個(gè)專用現(xiàn)成來(lái)管理。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總結(jié)
Android四大組件:
Activity—表現(xiàn)屏幕界面
Service—后臺(tái)服務(wù)
BroadcastReceiver—實(shí)現(xiàn)廣播機(jī)制
ContentProvider—實(shí)現(xiàn)數(shù)據(jù)存儲(chǔ)
Intent類:用來(lái)啟動(dòng)程序并傳遞信息的類
用于Activity、Receiver、Service之間進(jìn)行交互的類,通過(guò)無(wú)參構(gòu)造方法創(chuàng)建對(duì)象,增加其action、category、data、extra等屬性進(jìn)行信息傳遞,并通過(guò)Activity中的startActivity(Intent intent)進(jìn)行界面的跳轉(zhuǎn);通過(guò)Context中的StartService(Intent intent)進(jìn)行服務(wù)跳轉(zhuǎn);通過(guò)Context中的registerReceive(Intent intent)對(duì)廣播進(jìn)行注冊(cè),并通過(guò)sendBroadcast()進(jìn)行無(wú)序消息發(fā)送,或可以通過(guò)SendOrderedBroadcast()進(jìn)行有序的消息發(fā)送。Handler類:
用來(lái)發(fā)送和處理消息,并配合主線程完成UI的更新;消息Message/Runnable傳遞通過(guò)MessageQueue(消息隊(duì)列,先進(jìn)先出)進(jìn)行傳遞,并通過(guò)Lopper進(jìn)行接收,傳遞的消息可以為Message對(duì)象,也可以是Runnable對(duì)象;接收方法通過(guò)HandleMessage(Message msg)進(jìn)行獲取。SharedPreferences類:
一般用于第一次登錄時(shí)的設(shè)置,或者是各個(gè)界面的一些小型格式設(shè)置,如字體等。是本地的小型共享數(shù)據(jù)庫(kù),可以通過(guò)Context的靜態(tài)方法getSharedPreferences獲得其對(duì)象,對(duì)象內(nèi)的值均為鍵值對(duì)進(jìn)行儲(chǔ)存。通過(guò)SharedPreferences對(duì)象調(diào)用editor()獲取SharedPreferences.Editor對(duì)象,向共享數(shù)據(jù)庫(kù)中增加數(shù)據(jù),putString(),并提交數(shù)據(jù),commit();通過(guò)SharedPreferences對(duì)象獲取共享數(shù)據(jù)庫(kù)中的數(shù)據(jù),getString()。
ViewPager:實(shí)現(xiàn)界面滑動(dòng)的類;
通過(guò)設(shè)置OnPagerChangedListener設(shè)置ViewPager的監(jiān)聽事件;
實(shí)現(xiàn)流程:
①布局文件中設(shè)置ViewPager控件;
②代碼中進(jìn)行綁定控件;
③通過(guò)繼承PagerAdapter抽象類進(jìn)行設(shè)置適配器,并傳遞數(shù)據(jù)源;
④適配器中實(shí)現(xiàn)兩個(gè)抽象方法,兩個(gè)重寫方法:getCount()—獲取滑動(dòng)界面的數(shù)量,isViewFromObject()—判斷視圖是否是來(lái)自于Object文件中;重寫兩個(gè)方法,分別為destoryItem—銷毀指定位置的視圖;InstantiateItem(),設(shè)置指定位置的視圖;
Timer與TimerTask類:
Timer為計(jì)時(shí)器的類,通過(guò)無(wú)參構(gòu)造方法可以獲取對(duì)象,通過(guò)Timer.schedule(TimerTask task,long time)進(jìn)行設(shè)置多久后執(zhí)行某任務(wù),當(dāng)任務(wù)執(zhí)行完后,取消計(jì)時(shí)的功能,Timer.cancle();TimerTask類為抽象類,實(shí)例化時(shí),必須重寫run方法;執(zhí)行的內(nèi)容,均在run方法中進(jìn)行設(shè)置,并且執(zhí)行時(shí),已在子線程中進(jìn)行執(zhí)行。自定義View:用到的類有Paint、Canvas、Spec、SpecF、Path、View.MeasureSpec、Timer、TimerTask;
抽象類,通過(guò)子類繼承,獲取對(duì)象;在布局文件中綁定后,通過(guò)代碼,設(shè)置自定義View的屬性;自定義View中,通過(guò)重寫OnMeasure方法,對(duì)布局文件中的尺寸進(jìn)行測(cè)量,并由View中的setMeasureDimenson()方法,進(jìn)行數(shù)據(jù)的保存;通過(guò)重寫Ondraw方法,進(jìn)行繪圖;當(dāng)需要繪制動(dòng)態(tài)圖形時(shí),使用計(jì)時(shí)器Timer的schedule(TimerTask,long time,delay time2)方法,在time時(shí)間后,每隔time2時(shí)間,重寫執(zhí)行run方法中的內(nèi)容;將耗時(shí)的操作設(shè)置在run方法中,并通過(guò)View中的invalidate()方法刷新主線程中的繪的圖形,通過(guò)postInvalidate()刷新子線程中的圖形。數(shù)據(jù)庫(kù):
常用的數(shù)據(jù)庫(kù)有Oracle,需要安裝和配置的大型收費(fèi)數(shù)據(jù)庫(kù);MySQL是中型數(shù)據(jù)庫(kù),同樣需要安裝配置,但不需要收費(fèi);Sqlite是小型免費(fèi)的嵌入式數(shù)據(jù)庫(kù),占用內(nèi)存低,最新版本為3.0。Sqlite數(shù)據(jù)庫(kù)需要通過(guò)SqliteDatabaseOpenHelper進(jìn)行創(chuàng)建數(shù)據(jù)庫(kù),并通過(guò)SqliteDatabase進(jìn)行數(shù)據(jù)庫(kù)的操作。輔助類是抽象類,通過(guò)繼承,重寫兩個(gè)方法,并在子類的構(gòu)造方法中通過(guò)OpenHelper的構(gòu)造方法(Context context,String SqlName,SqliteDatabase.CursorFactory factory,int version)進(jìn)行數(shù)據(jù)庫(kù)的創(chuàng)建,在onCreate方法中,進(jìn)行數(shù)據(jù)庫(kù)表的創(chuàng)建,在onUpdate中進(jìn)行數(shù)據(jù)庫(kù)的版本更新。在數(shù)據(jù)庫(kù)的操作類中,執(zhí)行exect方法,通過(guò)sql語(yǔ)句對(duì)數(shù)據(jù)庫(kù)進(jìn)行操作。Create table student(_id integer primary key auto increament ,name text);insert into student(_id,name)values(1,zx);delete from student where _id=1;update student set _id=2 where name=zx;select *from student;ListView、GridView適配器的優(yōu)化:
將布局文件中的控件進(jìn)行封裝,當(dāng)視圖加載時(shí),判斷可變視圖是否存在,當(dāng)不存在時(shí),通過(guò)布局文件獲取視圖,并新建封裝類,將地址通過(guò)setTag()進(jìn)行發(fā)送;當(dāng)視圖存在時(shí),重復(fù)利用地址—getTag()。反射:
存儲(chǔ)數(shù)據(jù)的方式:
共享數(shù)據(jù)庫(kù)、數(shù)據(jù)庫(kù)、文件、網(wǎng)絡(luò)、內(nèi)容提供者
廣播:
廣播傳播時(shí),需要接收者、發(fā)送者、廣播頻道;根據(jù)發(fā)送者的發(fā)送方式不同,分為有序廣播、無(wú)序廣播;有序廣播為接收者有接收順序,根據(jù)設(shè)置的優(yōu)先級(jí)不同,確定先后順序,接收者同時(shí)也是發(fā)送者,向后面的廣播發(fā)送消息,發(fā)送過(guò)程中,可以添加信息,也可以停止廣播的傳輸;無(wú)序廣播,接收者之間無(wú)聯(lián)系,均從發(fā)送者處接收信息;廣播在傳輸過(guò)程中,不能被添加信息,也不可能被停止。廣播在發(fā)送前,需要對(duì)接收者進(jìn)行注冊(cè),注冊(cè)方式有兩種,動(dòng)態(tài)注冊(cè)、靜態(tài)注冊(cè)。動(dòng)態(tài)注冊(cè),是在代碼中進(jìn)行,通過(guò)Context對(duì)象調(diào)用靜態(tài)方法進(jìn)行注冊(cè),所有的廣播均可以用動(dòng)態(tài)注冊(cè),其生命周期依賴于應(yīng)用,相對(duì)于靜態(tài)注冊(cè),比較節(jié)省內(nèi)存;靜態(tài)方法在清單文件中進(jìn)行注冊(cè),部分系統(tǒng)廣播不能通過(guò)靜態(tài)注冊(cè)進(jìn)行,其生命周期依賴于系統(tǒng),當(dāng)系統(tǒng)啟動(dòng),即運(yùn)行接收廣播,較耗內(nèi)存。廣播接收者需要繼承BroadcastReceiver,并實(shí)現(xiàn)抽象方法onReceive(),通過(guò)回調(diào)接口,進(jìn)行數(shù)據(jù)的傳輸。注意:廣播發(fā)送前,必須進(jìn)行接收者的注冊(cè),并且,當(dāng)顯示跳轉(zhuǎn)時(shí),不需要意圖過(guò)濾器。安卓布局:九種布局
線性布局,水平或垂直方向兩種格式,主要特點(diǎn)為權(quán)重,即規(guī)定各控件在視圖中的占有的比例;
相對(duì)布局,相對(duì)于父控件或兄弟控件的布局,各控件需指定相對(duì)位置; 絕對(duì)布局,指定各控件在視圖中的絕對(duì)位置,幾乎不再使用; 表格布局,子布局放在行中,列由控件表示(TableRow); 幀布局:覆蓋前面布局的布局,一般用于暫停按鈕等; 風(fēng)格布局:可以跨行、跨列的布局,占滿換行;
左右側(cè)滑:可以實(shí)現(xiàn)左右側(cè)滑,通過(guò)設(shè)置主菜單和二級(jí)菜單設(shè)置左右兩個(gè)菜單; 下拉刷新:設(shè)置下拉刷新、上拉加載的功能; 抽屜布局;
安卓版本及對(duì)應(yīng)的API:
1.6—4;2—7;3—11;4—15;4.3—18;5—20;5.1—21;6—23;7—25; 安卓四層架構(gòu):
應(yīng)用層:Java語(yǔ)言開發(fā),主要從事App開發(fā);
運(yùn)行庫(kù)層:Java語(yǔ)言與C語(yǔ)言,View視圖、管理類等的開發(fā); 架構(gòu)層:C語(yǔ)言與Linux語(yǔ)言,各種框架、瀏覽器等; 內(nèi)核層:Linux、C語(yǔ)言,開發(fā)各種驅(qū)動(dòng); 安卓四大組件:
Activity:界面,實(shí)現(xiàn)程序與用戶之間的交換,有自己的生命周期,七個(gè)生命周期;4種啟動(dòng)模式 Service:
BroadcastReceive:三要素,發(fā)送者、接收者、發(fā)送頻道(Intent);類型:有序(接收有序,有數(shù)據(jù)傳送,可以攔截?cái)?shù)據(jù))、無(wú)序廣播(相對(duì));注冊(cè)方式:靜態(tài)注冊(cè),持久監(jiān)聽,占用內(nèi)存比較高生命周期跟隨系統(tǒng),動(dòng)態(tài)注冊(cè)(代碼中),所有廣播都可以動(dòng)態(tài)注冊(cè),部分系統(tǒng)廣播不能動(dòng)態(tài)注冊(cè),臨時(shí)監(jiān)聽,占用內(nèi)存較少,生命周期隨應(yīng)用進(jìn)行;
ContentProvide:不能存放數(shù)據(jù),五種存放數(shù)據(jù)方式之一,特點(diǎn)為:①為數(shù)據(jù)的獲取等操作添加一個(gè)統(tǒng)一的接口②可以實(shí)現(xiàn)跨應(yīng)用訪問(wèn)數(shù)據(jù);③可以實(shí)現(xiàn)Android中通訊錄、消息、音頻、視頻等的訪問(wèn)或操作;通過(guò)ContentReceive進(jìn)行數(shù)據(jù)的訪問(wèn),可以對(duì)數(shù)據(jù)進(jìn)行增刪改查操作。
動(dòng)畫: IO流: 序列化: AlertDialog:
Set實(shí)現(xiàn)類: 手機(jī)電量檢測(cè):
自定義SurfaceView:
自定義View:三個(gè)構(gòu)造方法的區(qū)別
Message:Handler.obtain/new/Message.obtain
HttpUriConnection訪問(wèn)網(wǎng)絡(luò)
gride 異步任務(wù) 動(dòng)畫
抽象類和接口 反射 克隆 序列化 側(cè)滑的實(shí)現(xiàn) 數(shù)據(jù)庫(kù) Socket:
Gson解析
異步任務(wù)和子線程區(qū)別 WebView 版本更新 照片的圓角化
Collection與Collections Sql語(yǔ)句
MVP框架與MVC: TCP與UDP的區(qū)別: 一鍵分享的流程: Http協(xié)議的理解: 不使用框架訪問(wèn)網(wǎng)絡(luò): List集合與set集合: 自定義View的流程: 線性布局的特點(diǎn): ViewPager的原理: 服務(wù)的啟動(dòng)方式:
Activity的啟動(dòng)方式: Xml數(shù)據(jù)解析:
第四篇:Android 個(gè)人總結(jié)
Android 個(gè)人總結(jié)
通過(guò)本學(xué)期的的學(xué)習(xí),我知道了android是由google開發(fā)的一款手機(jī)平臺(tái),android的基本架構(gòu)是基于linux內(nèi)核,由內(nèi)核向外的反別為庫(kù)和應(yīng)用架構(gòu),然后就是我們手機(jī)上的可視化應(yīng)用了,android是一個(gè)系統(tǒng),但是并非是操作系統(tǒng)。
在開發(fā)之前,我們首先要搭建一個(gè)開發(fā)環(huán)境,用的是java編程的eclipse,我們從網(wǎng)上下載sdk包,里面包含了android開發(fā)常用的工具,android既是手機(jī)操作系統(tǒng),也是跨平臺(tái)(windows,mac,linux)的開發(fā)工具,雖然是使用linux為核心的平臺(tái),但是你可以在很多地方感覺(jué)到類似做網(wǎng)頁(yè)開發(fā)的感覺(jué)。具有本身獨(dú)特的進(jìn)程管理方式,完整的上網(wǎng)功能,搭配了google地圖,Gmail等服務(wù),即使像我們這些尚未入門的開發(fā)者也能開發(fā)出自己理想的應(yīng)用程序來(lái)。
剛開始的時(shí)候,得知android開發(fā)需要使用java語(yǔ)言心里了小小的畏懼,但隨著學(xué)習(xí)的漸漸深入就會(huì)發(fā)現(xiàn)android平臺(tái)只是使用了java的語(yǔ)法而已,所以,即使我們不具備java語(yǔ)言開發(fā)的基礎(chǔ),也可以放心地加入到android開發(fā)當(dāng)中來(lái)。
第一節(jié)課,老師向我們?cè)敿?xì)介紹了開發(fā)界面右邊窗口的內(nèi)容,首先是src目錄,里面包含了我們開發(fā)界面的java文件以及各種我們創(chuàng)建的類組成的開發(fā)包。然后是gen目錄,里面涵蓋的是系統(tǒng)的類文件(如R.java,Buidconfig.java)與android系統(tǒng)的依賴文件(Android Dependencies)。再下來(lái)是assets(用戶資源文件),里面文件的訪問(wèn)是通過(guò)文件路徑的形式調(diào)用。Bin文件里面包括了res資源文件,android項(xiàng)目配置文件androidmanifest以及我們開發(fā)之后產(chǎn)生的后綴為.apk的應(yīng)用程序文件。Res是系統(tǒng)資源目錄,我們要用到得圖片資源,顏色資源,字符串資源都在里面。一般的開發(fā)都要用到界面文件也包含在里面。
Eclipse具有史上超豪華的手機(jī)控件,包括常用的文本文件,文本框,按鈕,進(jìn)度條等,還有特殊形式的email,gmail文本框,在開發(fā)過(guò)程當(dāng)中,很多控件都是以拖拉的形式拖拽到開發(fā)界面上,大大地減少了我們開發(fā)時(shí)候的工作量,在配置文件中,我們可以添加各種各樣的系統(tǒng)動(dòng)作,以及系統(tǒng)服務(wù),還可以建立用戶自己的文件庫(kù)。
當(dāng)我們開發(fā)完成的時(shí)候,就可以運(yùn)行手機(jī)模擬器,在上面,我們可以像操作當(dāng)今市場(chǎng)上最流行的android手機(jī)一樣操作我們的模擬器,可視化的界面可以我們隨心所欲地下載我們開發(fā)的應(yīng)用程序到模擬器上,就可以實(shí)現(xiàn)步步跟進(jìn),想要修改哪里就一目了然了,模擬器上人性化的設(shè)計(jì)界面大大方便了用戶與機(jī)器之間的交流。如果我們擁有一部android系統(tǒng)的手機(jī)的話,就可以把自己開發(fā)的應(yīng)用程序下到手機(jī)上,看到自己的成果,頓生成就感,真的很有樂(lè)趣。也加大了我對(duì)學(xué)習(xí)android的信心。
總體來(lái)說(shuō),學(xué)習(xí)android就要不怕困難,迎難而上。Android不久可以滿足自己的成就感,還可以在未來(lái)的生活中找到自己理想的工作。用別人準(zhǔn)備好的各種類,包來(lái)開發(fā)出自己獨(dú)特風(fēng)格的應(yīng)用程序,既省時(shí)又省力,何樂(lè)而不為呢。在這里,要感謝曾老師對(duì)我的栽培和關(guān)懷,他教給了我知識(shí),使我在學(xué)習(xí)的時(shí)候少走了很多的彎路,也增加了我對(duì)未來(lái)工作的信心。
第五篇:Android 課程總結(jié)
一、Android開發(fā)環(huán)境的搭建。
1、Android SDK的安裝;
2、ADT的安裝和配置;
3、Android 模擬器的配置。
二、編寫第一個(gè)Android程序───Hello World(1學(xué)時(shí))
1、創(chuàng)建一個(gè)Android應(yīng)用程序的步驟;
2、Android 應(yīng)用程序目錄結(jié)構(gòu);
3、AndroidManidest.xml文件的作用;
4、Android相關(guān)資源文件的作用。
三、Activity及Activity和Intent(2學(xué)時(shí))
1、Activity的主要作用;
2、創(chuàng)建一個(gè)Activity的方法;
3、在AndroidManifest.xml文件中的注冊(cè)應(yīng)用Activity的方法;
4、在Activity中添加控件的方法;
5、多個(gè)Activity之間的切換;
6、Intent的基本作用;
7、在一個(gè)Activity中啟動(dòng)另一個(gè)Activity的方法;
8、使用Intent在Activity中傳遞數(shù)據(jù)的基本方法。
四、常見控件的使用方法(基礎(chǔ))
1、TextView的使用方法;
2、EditText的使用方法;
3、Button的使用方法;
4、Menu的使用方法。
五、Activity的生命周期(2學(xué)時(shí))
1、Activity的七個(gè)周期:
① OnCreate();② OnDestroy();③ OnPause();④ OnRestart();⑤ OnResume();⑥ OnStart();⑦ OnStop();
2、Task的基本概念;
3、Activity和Task之間的關(guān)系;
4、對(duì)話框風(fēng)格的Activity的使用方法。
六、Activity的布局(3學(xué)時(shí))
1、LinearLayout的使用方法;
2、TableLayout的使用方法;
3、LinearLayout和TableLayout的嵌套使用;
4、RelativeLayout的使用方法(重點(diǎn)、難點(diǎn))
七、常用控件是使用方法二(2學(xué)時(shí))
1、RadioGroup和RadioButton的使用方法;
2、CheckBox的使用方法;
3、Toast的基本用法。
4、ProgressBar的使用方法;
5、ListView的用法。
八、Handler的使用方法(2學(xué)時(shí))
1、Handler的基本概念;
2、Handler的基本用法;
3、使用Handler更新ProgressBar
4、Handler與線程;
5、Bundle的用法;
6、在新線程中處理消息的方法。
九、SQLite使用方法
1、SQLite介紹;
2、SQLiteOpenHeper使用方法;
3、使用adb訪問(wèn)SQLite
4、增、刪、改、查。
十、Android文件下載
1、使用HTTP協(xié)議下載文件;
2、將下載的文件寫入SDCARD。
十一、Content Provider初步(2學(xué)時(shí))
1、Content Provider的基本概念;
2、Uri;
3、Content Provider的實(shí)現(xiàn)方法。
十二、XML文件的解析方法
1、什么是SAX;
2、SAX的基本原理;
3、SAX常用接口;
4、SAX解析。
十三、廣播機(jī)制(2學(xué)時(shí))
1、Android的廣播機(jī)制(圖鑒);
2、BroadCastReceive的作用;
3、BroadCastReceive的編寫方法;
4、BroadCastReceive的生命周期。
5、注冊(cè)BroadCastReceive的方法;
6、Android內(nèi)置BroadCastReceive Actions。
十四、WIFI網(wǎng)絡(luò)的使用
1、什么是WIFI;
2、獲取WIFI網(wǎng)卡的狀態(tài);
3、操作WIFI所需要的權(quán)限;
4、改變WIFI網(wǎng)卡的狀態(tài)。
十五、Socket編程
1、什么是Socket;
2、Socket基本通信模型(見圖);
3、使用基于TCP協(xié)議的Socket;
4、使用基于UDP協(xié)議的Socket。
十六、Service
1、Service是什么;
2、Service不是什么;
3、Service的生命周期;
4、啟動(dòng)和停止Service;