版權(quán)說(shuō)明:本文檔由用戶(hù)提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
【移動(dòng)應(yīng)用開(kāi)發(fā)技術(shù)】Android實(shí)現(xiàn)藍(lán)牙聊天功能的方
這篇文章主要介紹了Android實(shí)現(xiàn)藍(lán)牙聊天功能的方,具有一定借鑒價(jià)值,感興趣的朋友可以參考下,希望大家閱讀完這篇文章之后大有收獲,下面讓在下帶著大家一起了解一下。藍(lán)牙,時(shí)下最流行的智能設(shè)備傳輸數(shù)據(jù)的方式之一,通過(guò)手機(jī)app和智能設(shè)備進(jìn)行連接,獲取設(shè)備上的測(cè)量數(shù)據(jù),我們生活中隨處可見(jiàn)的比如藍(lán)牙智能手環(huán),藍(lán)牙電子秤,藍(lán)牙心電測(cè)量設(shè)備等等。先貼出上篇的一些demo;當(dāng)點(diǎn)擊圖上的兩個(gè)列表中的任何一個(gè)列表,執(zhí)行如下代碼:mBtAdapter.cancelDiscovery();
String
info
=
((TextView)
v).getText().toString();
String
address
=
info.substring(info.length()
-
17);
Intent
intent
=
new
Intent();
intent.putExtra(EXTRA_DEVICE_ADDRESS,
address);
setResult(Activity.RESULT_OK,
intent);
finish();此藍(lán)牙聊天工具最后實(shí)現(xiàn)的效果是這樣的:將回到聊天主界面:public
void
onActivityResult(int
requestCode,
int
resultCode,
Intent
data)
{
LogUtils.getInstance().e(getClass(),
"onActivityResult
"
+
resultCode);
switch
(requestCode)
{
case
REQUEST_CONNECT_DEVICE:
//
當(dāng)DeviceListActivity返回與設(shè)備連接的消息
if
(resultCode
==
Activity.RESULT_OK)
{
//
連接設(shè)備的MAC地址
String
address
=
data.getExtras().getString(
DeviceListActivity.EXTRA_DEVICE_ADDRESS);
//
得到藍(lán)牙對(duì)象
BluetoothDevice
device
=
mBluetoothAdapter.getRemoteDevice(address);
//
開(kāi)始連接設(shè)備
mChatService.connect(device);
}
break;
case
REQUEST_ENABLE_BT:
//
判斷藍(lán)牙是否啟用
if
(resultCode
==
Activity.RESULT_OK)
{
//
建立連接
setupChat();
}
else
{
LogUtils.getInstance().e(getClass(),
"藍(lán)牙未啟用");
Toast.makeText(this,
R.string.bt_not_enabled_leaving,
Toast.LENGTH_SHORT).show();
finish();
}
}
}在此,我將重點(diǎn)介紹下BluetoothChatService類(lèi)中的連接流程;因?yàn)樗{(lán)牙聊天是兩個(gè)手機(jī)之間進(jìn)行通訊,所以他們互為主機(jī)和從機(jī),主要思路以及步驟如下:1.開(kāi)一個(gè)線程獲取socket去連接藍(lán)牙;2.開(kāi)一個(gè)線程獲監(jiān)聽(tīng)藍(lán)牙傳入的連接,如果連接被接受的話,再開(kāi)啟第三個(gè)線程去處理所有傳入和傳出的數(shù)據(jù);public
synchronized
void
connect(BluetoothDevice
device)
{
if
(mState
==
STATE_CONNECTING)
{
if
(mConnectThread
!=
null)
{
mConnectThread.cancel();
mConnectThread
=
null;
}
}
if
(mConnectedThread
!=
null)
{
mConnectedThread.cancel();
mConnectedThread
=
null;
}
mConnectThread
=
new
ConnectThread(device);
mConnectThread.start();
setState(STATE_CONNECTING);
}開(kāi)線程去連接/**
*
@description:藍(lán)牙連接線程
*
@author:zzq
*
@time:
2016-8-6
下午1:18:41
*/
private
class
ConnectThread
extends
Thread
{
private
final
BluetoothSocket
mmSocket;
private
final
BluetoothDevice
mmDevice;
public
ConnectThread(BluetoothDevice
device)
{
mmDevice
=
device;
BluetoothSocket
tmp
=
null;
try
{
tmp
=
device.createRfcommSocketToServiceRecord(MY_UUID);
}
catch
(IOException
e)
{
LogUtils.getInstance().e(getClass(),
"socket獲取失?。?
+
e);
}
mmSocket
=
tmp;
}
public
void
run()
{
LogUtils.getInstance().e(getClass(),
"開(kāi)始mConnectThread");
setName("ConnectThread");
//
mAdapter.cancelDiscovery();
try
{
mmSocket.connect();
}
catch
(IOException
e)
{
//
連接失敗,更新ui
connectionFailed();
try
{
mmSocket.close();
}
catch
(IOException
e2)
{
LogUtils.getInstance().e(getClass(),
"關(guān)閉連接失敗"
+
e2);
}
//
開(kāi)啟聊天接收線程
startChat();
return;
}
synchronized
(BluetoothChatService.this)
{
mConnectThread
=
null;
}
connected(mmSocket,
mmDevice);
}
public
void
cancel()
{
try
{
mmSocket.close();
}
catch
(IOException
e)
{
LogUtils.getInstance().e(getClass(),
"關(guān)閉連接失敗"
+
e);
}
}
}/**
*
監(jiān)聽(tīng)傳入的連接
*/
private
class
AcceptThread
extends
Thread
{
private
final
BluetoothServerSocket
mmServerSocket;
public
AcceptThread()
{
BluetoothServerSocket
tmp
=
null;
try
{
tmp
=
mAdapter.listenUsingRfcommWithServiceRecord(NAME,
MY_UUID);
}
catch
(IOException
e)
{
LogUtils.getInstance().e(getClass(),
"--獲取socket失敗:"
+
e);
}
mmServerSocket
=
tmp;
}
public
void
run()
{
setName("AcceptThread");
BluetoothSocket
socket
=
null;
while
(mState
!=
STATE_CONNECTED)
{
LogUtils.getInstance().e(getClass(),
"accept-循環(huán)執(zhí)行中-");
try
{
socket
=
mmServerSocket.accept();
}
catch
(IOException
e)
{
LogUtils.getInstance().e(getClass(),
"accept()
失敗"
+
e);
break;
}
//
如果連接被接受
if
(socket
!=
null)
{
synchronized
(BluetoothChatService.this)
{
switch
(mState)
{
case
STATE_LISTEN:
case
STATE_CONNECTING:
//
開(kāi)始連接線程
connected(socket,
socket.getRemoteDevice());
break;
case
STATE_NONE:
case
STATE_CONNECTED:
//
沒(méi)有準(zhǔn)備好或已經(jīng)連接
try
{
socket.close();
}
catch
(IOException
e)
{
LogUtils.getInstance().e(getClass(),"不能關(guān)閉這些連接"
+
e);
}
break;
}
}
}
}
LogUtils.getInstance().e(getClass(),
"結(jié)束mAcceptThread");
}
public
void
cancel()
{
LogUtils.getInstance().e(getClass(),
"取消
"
+
this);
try
{
mmServerSocket.close();
}
catch
(IOException
e)
{
LogUtils.getInstance().e(getClass(),
"關(guān)閉失敗"
+
e);
}
}
}
/**
*
連接成功后的線程
處理所有傳入和傳出的傳輸
*/
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;
//
得到BluetoothSocket輸入和輸出流
try
{
tmpIn
=
socket.getInputStream();
tmpOut
=
socket.getOutputStream();
}
catch
(IOException
e)
{
LogUtils.getInstance().e(getClass(),"temp
sockets
not
created"
+
e);
}
mmInStream
=
tmpIn;
mmOutStream
=
tmpOut;
}
public
void
run()
{
int
bytes;
String
str1
=
"";
//
循環(huán)監(jiān)聽(tīng)消息
while
(true)
{
try
{
byte[]
buffer
=
new
byte[256];
bytes
=
mmInStream.read(buffer);
String
readStr
=
new
String(buffer,
0,
bytes);//
字節(jié)數(shù)組直接轉(zhuǎn)換成字符串
String
str
=
bytes2HexString(buffer).replaceAll("00",
"").trim();
if
(bytes
>
0)
{//
將讀取到的消息發(fā)到主線程
mHandler.obtainMessage(BluetoothChatActivity.MESSAGE_READ,
bytes,
-1,buffer).sendToTarget();
}
else
{
LogUtils.getInstance().e(getClass(),"disconnected");
connectionLost();
if
(mState
!=
STATE_NONE)
{
LogUtils.getInstance().e(getClass(),
"disconnected");
startChat();
}
break;
}
}
catch
(IOException
e)
{
LogUtils.getInstance().e(getClass(),
"disconnected"
+
e);
connectionLost();
if
(mState
!=
STATE_NONE)
{
//
在重新啟動(dòng)監(jiān)聽(tīng)模式啟動(dòng)該服務(wù)
startChat();
}
break;
}
}
}
/**
*
寫(xiě)入OutStream連接
*
*
@param
buffer
*
要寫(xiě)的字節(jié)
*/
public
void
write(byte[]
buffer)
{
try
{
mmOutStream.write(buffer);
//
把消息傳給UI
mHandler.obtainMessage(BluetoothChatActivity.MESSAGE_WRITE,
-1,-1,
buffer).sendToTarget();
}
catch
(IOException
e)
{
LogUtils.getInstance().e(getClass(),
"Exception
during
write:"
+
e);
}
}
public
void
cancel()
{
try
{
mmSocket.close();
}
catch
(IOException
e)
{
LogUtils.getInstance().e(getClass(),"close()
of
connect
socket
failed:"
+
e);
}
}
}大概的流程就是上面三個(gè)線程里面所展現(xiàn)的,當(dāng)然具體情況,根據(jù)項(xiàng)目來(lái),比如藍(lán)牙協(xié)議協(xié)議解析這塊的根據(jù)協(xié)議定義的方式來(lái)進(jìn)行解析;代碼中牽扯的到的藍(lán)牙連接狀態(tài)的改變,用到的handle,直接把狀態(tài)發(fā)送至activity,通知activity更新;
/**
*
無(wú)法連接,通知Activity
*/
private
void
connectionFailed()
{
setState(STATE_LISTEN);
Message
msg
=
mHandler.obtainMessage(BluetoothChatActivity.MESSAGE_TOAST);
Bundle
bundle
=
new
Bundle();
bundle.putString(BluetoothChatActivity.TOAST,
"無(wú)法連接設(shè)備");
msg.setData(bundle);
mHandler.sendMessage(msg);
}
/**
*
設(shè)備斷開(kāi)連接,通知Activity
*/
private
void
connectionLost()
{
Message
msg
=
mHandler.obtainMessage(BluetoothChatActivity.MESSAGE_TOAST);
Bundle
bundle
=
new
Bundle();
bundle.putString(BluetoothChatActivity.TOAST,
"設(shè)備斷開(kāi)連接");
msg.setData(bundle);
mHandler.sendMessage(msg);
}當(dāng)點(diǎn)擊發(fā)送按鈕時(shí),將文本輸入框中的文字發(fā)送數(shù)據(jù)的方法:private
void
sendMessage(String
message)
{
if
(mChatService.getState()
!=
BluetoothChatService.STATE_CONNECTED)
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶(hù)所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶(hù)上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶(hù)上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶(hù)因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- GB/T 44361-2024工業(yè)車(chē)輛 檢查與維護(hù)規(guī)范
- GB/T 44268.2-2024顯微鏡照明特性的定義和測(cè)量第2部分:明場(chǎng)顯微鏡中與顏色有關(guān)的照明特性
- 二年級(jí)數(shù)學(xué)教學(xué)總結(jié)3
- DB3301∕T 65.14-2024 反恐怖防范系統(tǒng)管理規(guī)范 第14部分:商場(chǎng)超市
- DB2311∕T 072-2024 黑河市大棚西瓜栽培技術(shù)規(guī)程
- 開(kāi)題論證書(shū)家園協(xié)作背景下幼兒早期閱讀興趣培養(yǎng)的實(shí)踐研究
- 人生智慧:從吃梨的哲學(xué)到情緒管理的藝術(shù)
- 廣東省肇慶市端州區(qū)2024-2025學(xué)年高三上學(xué)期第一次檢測(cè)歷史試題
- 2022-2023學(xué)年高二物理競(jìng)賽課件:放大電路的動(dòng)態(tài)分析
- 2024年恩施旅客運(yùn)輸從業(yè)資格證考試題庫(kù)
- 2024年機(jī)動(dòng)車(chē)輛保險(xiǎn)合同范文
- Unit 2 Different families 第四課時(shí)(教學(xué)設(shè)計(jì))-2024-2025學(xué)年人教PEP版(2024)英語(yǔ)三年級(jí)上冊(cè)
- 2024-2025學(xué)年部編版語(yǔ)文七年級(jí)上冊(cè) 第一次月考試卷
- 【生物】第二章認(rèn)識(shí)細(xì)胞作業(yè)設(shè)計(jì)2024-2025學(xué)年人教版生物七年級(jí)上冊(cè)
- 2024年軍隊(duì)文職真題
- 部編本人教版《道德與法治》七年級(jí)上冊(cè)第一單元測(cè)試題(含答案)
- 二十屆三中全知識(shí)點(diǎn)
- 2024兒童青少年抑郁治療與康復(fù)痛點(diǎn)調(diào)研報(bào)告 -基于患者家長(zhǎng)群體的調(diào)研
- 2024廣西專(zhuān)業(yè)技術(shù)人員繼續(xù)教育公需科目參考答案(97分)
- 江蘇省建筑與裝飾工程計(jì)價(jià)定額(2014)電子表格版
- 田徑大單元教學(xué)計(jì)劃
評(píng)論
0/150
提交評(píng)論