版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領
文檔簡介
【移動應用開發(fā)技術】Android實現藍牙聊天功能的方
這篇文章主要介紹了Android實現藍牙聊天功能的方,具有一定借鑒價值,感興趣的朋友可以參考下,希望大家閱讀完這篇文章之后大有收獲,下面讓在下帶著大家一起了解一下。藍牙,時下最流行的智能設備傳輸數據的方式之一,通過手機app和智能設備進行連接,獲取設備上的測量數據,我們生活中隨處可見的比如藍牙智能手環(huán),藍牙電子秤,藍牙心電測量設備等等。先貼出上篇的一些demo;當點擊圖上的兩個列表中的任何一個列表,執(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();此藍牙聊天工具最后實現的效果是這樣的:將回到聊天主界面:public
void
onActivityResult(int
requestCode,
int
resultCode,
Intent
data)
{
LogUtils.getInstance().e(getClass(),
"onActivityResult
"
+
resultCode);
switch
(requestCode)
{
case
REQUEST_CONNECT_DEVICE:
//
當DeviceListActivity返回與設備連接的消息
if
(resultCode
==
Activity.RESULT_OK)
{
//
連接設備的MAC地址
String
address
=
data.getExtras().getString(
DeviceListActivity.EXTRA_DEVICE_ADDRESS);
//
得到藍牙對象
BluetoothDevice
device
=
mBluetoothAdapter.getRemoteDevice(address);
//
開始連接設備
mChatService.connect(device);
}
break;
case
REQUEST_ENABLE_BT:
//
判斷藍牙是否啟用
if
(resultCode
==
Activity.RESULT_OK)
{
//
建立連接
setupChat();
}
else
{
LogUtils.getInstance().e(getClass(),
"藍牙未啟用");
Toast.makeText(this,
R.string.bt_not_enabled_leaving,
Toast.LENGTH_SHORT).show();
finish();
}
}
}在此,我將重點介紹下BluetoothChatService類中的連接流程;因為藍牙聊天是兩個手機之間進行通訊,所以他們互為主機和從機,主要思路以及步驟如下:1.開一個線程獲取socket去連接藍牙;2.開一個線程獲監(jiān)聽藍牙傳入的連接,如果連接被接受的話,再開啟第三個線程去處理所有傳入和傳出的數據;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);
}開線程去連接/**
*
@description:藍牙連接線程
*
@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(),
"開始mConnectThread");
setName("ConnectThread");
//
mAdapter.cancelDiscovery();
try
{
mmSocket.connect();
}
catch
(IOException
e)
{
//
連接失敗,更新ui
connectionFailed();
try
{
mmSocket.close();
}
catch
(IOException
e2)
{
LogUtils.getInstance().e(getClass(),
"關閉連接失敗"
+
e2);
}
//
開啟聊天接收線程
startChat();
return;
}
synchronized
(BluetoothChatService.this)
{
mConnectThread
=
null;
}
connected(mmSocket,
mmDevice);
}
public
void
cancel()
{
try
{
mmSocket.close();
}
catch
(IOException
e)
{
LogUtils.getInstance().e(getClass(),
"關閉連接失敗"
+
e);
}
}
}/**
*
監(jiān)聽傳入的連接
*/
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:
//
開始連接線程
connected(socket,
socket.getRemoteDevice());
break;
case
STATE_NONE:
case
STATE_CONNECTED:
//
沒有準備好或已經連接
try
{
socket.close();
}
catch
(IOException
e)
{
LogUtils.getInstance().e(getClass(),"不能關閉這些連接"
+
e);
}
break;
}
}
}
}
LogUtils.getInstance().e(getClass(),
"結束mAcceptThread");
}
public
void
cancel()
{
LogUtils.getInstance().e(getClass(),
"取消
"
+
this);
try
{
mmServerSocket.close();
}
catch
(IOException
e)
{
LogUtils.getInstance().e(getClass(),
"關閉失敗"
+
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)聽消息
while
(true)
{
try
{
byte[]
buffer
=
new
byte[256];
bytes
=
mmInStream.read(buffer);
String
readStr
=
new
String(buffer,
0,
bytes);//
字節(jié)數組直接轉換成字符串
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)
{
//
在重新啟動監(jiān)聽模式啟動該服務
startChat();
}
break;
}
}
}
/**
*
寫入OutStream連接
*
*
@param
buffer
*
要寫的字節(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);
}
}
}大概的流程就是上面三個線程里面所展現的,當然具體情況,根據項目來,比如藍牙協(xié)議協(xié)議解析這塊的根據協(xié)議定義的方式來進行解析;代碼中牽扯的到的藍牙連接狀態(tài)的改變,用到的handle,直接把狀態(tài)發(fā)送至activity,通知activity更新;
/**
*
無法連接,通知Activity
*/
private
void
connectionFailed()
{
setState(STATE_LISTEN);
Message
msg
=
mHandler.obtainMessage(BluetoothChatActivity.MESSAGE_TOAST);
Bundle
bundle
=
new
Bundle();
bundle.putString(BluetoothChatActivity.TOAST,
"無法連接設備");
msg.setData(bundle);
mHandler.sendMessage(msg);
}
/**
*
設備斷開連接,通知Activity
*/
private
void
connectionLost()
{
Message
msg
=
mHandler.obtainMessage(BluetoothChatActivity.MESSAGE_TOAST);
Bundle
bundle
=
new
Bundle();
bundle.putString(BluetoothChatActivity.TOAST,
"設備斷開連接");
msg.setData(bundle);
mHandler.sendMessage(msg);
}當點擊發(fā)送按鈕時,將文本輸入框中的文字發(fā)送數據的方法:private
void
sendMessage(String
message)
{
if
(mChatService.getState()
!=
BluetoothChatService.STATE_CONNECTED)
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經權益所有人同意不得將文件中的內容挪作商業(yè)或盈利用途。
- 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
- 6. 下載文件中如有侵權或不適當內容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 2026年廣東松山職業(yè)技術學院單招職業(yè)技能考試模擬測試卷附答案
- 2026年犯罪心理及測試研究考試備考題庫帶答案
- 2026年團員入團知識試題及完整答案一套
- 2026安徽消防中控員招聘筆試模擬試題及答案解析
- 2026年廣東省潮州市單招職業(yè)適應性考試模擬測試卷及答案1套
- 安徽宿州學院2026年度高層次人才招聘49人筆試備考題庫及答案解析
- 2025內蒙古呼和浩特春華水務開發(fā)集團有限責任公司招聘補充筆試模擬試題及答案解析
- 2025廣東深圳市光明區(qū)選調職員8人考試模擬卷附答案
- 2025年皖通公司合肥處招聘收費協(xié)管員10人考前自測高頻考點模擬試題附答案
- 2025山東德州市陵城區(qū)經濟開發(fā)區(qū)選聘20人備考題庫附答案
- 2026北京大興初二上學期期末語文試卷和答案
- 2025年武漢大學專職管理人員和學生輔導員招聘真題
- 2025新疆智慧口岸建設白皮書
- 2025嵐圖汽車社會招聘(公共基礎知識)測試題附答案
- 2025-2026小學嶺南版(2024)美術二年級上冊教學設計(附目錄)
- 2025福建德化閩投抽水蓄能有限公司招聘15人模擬試卷附答案
- 微生物檢驗標準操作規(guī)范
- 安徽金軒科技有限公司 年產60萬噸硫磺制酸項目環(huán)境影響報告書
- 魔鬼理論之k線秘笈圖解課件
- 2023屆廣東省佛山市普通高中高三上學期教學質量檢測(一模)物理試題含答案
- GB/T 9163-2001關節(jié)軸承向心關節(jié)軸承
評論
0/150
提交評論