国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 系統(tǒng) > Android > 正文

Android實現(xiàn)藍牙聊天功能

2019-12-12 00:49:21
字體:
供稿:網(wǎng)友

藍牙,時下最流行的智能設(shè)備傳輸數(shù)據(jù)的方式之一,通過手機app和智能設(shè)備進行連接,獲取設(shè)備上的測量數(shù)據(jù),我們生活中隨處可見的比如藍牙智能手環(huán),藍牙電子秤,藍牙心電測量設(shè)備等等。

本篇我將緊接著上篇結(jié)尾所寫,一起來看下手機之間如何通過藍牙實現(xià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();

此藍牙聊天工具最后實現(xiàn)的效果是這樣的:

將回到聊天主界面:

public void onActivityResult(int requestCode, int resultCode, Intent data) { LogUtils.getInstance().e(getClass(), "onActivityResult " + resultCode); switch (requestCode) { case REQUEST_CONNECT_DEVICE: // 當DeviceListActivity返回與設(shè)備連接的消息 if (resultCode == Activity.RESULT_OK) { // 連接設(shè)備的MAC地址 String address = data.getExtras().getString( DeviceListActivity.EXTRA_DEVICE_ADDRESS); // 得到藍牙對象 BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(address); // 開始連接設(shè)備 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)聽藍牙傳入的連接,如果連接被接受的話,再開啟第三個線程去處理所有傳入和傳出的數(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);}

開線程去連接

/** * @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(), "關(guān)閉連接失敗" + e2); } // 開啟聊天接收線程 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)聽傳入的連接 */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: // 沒有準備好或已經(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)聽消息 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) { // 在重新啟動監(jiān)聽模式啟動該服務(wù) 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àn)的,當然具體情況,根據(jù)項目來,比如藍牙協(xié)議協(xié)議解析這塊的根據(jù)協(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, "無法連接設(shè)備"); msg.setData(bundle); mHandler.sendMessage(msg);}/** * 設(shè)備斷開連接,通知Activity */private void connectionLost() { Message msg = mHandler.obtainMessage(BluetoothChatActivity.MESSAGE_TOAST); Bundle bundle = new Bundle(); bundle.putString(BluetoothChatActivity.TOAST, "設(shè)備斷開連接"); msg.setData(bundle); mHandler.sendMessage(msg);}

當點擊發(fā)送按鈕時,將文本輸入框中的文字發(fā)送數(shù)據(jù)的方法:

private void sendMessage(String message) { if (mChatService.getState() != BluetoothChatService.STATE_CONNECTED) { Toast.makeText(this, R.string.not_connected,Toast.LENGTH_SHORT).show(); return;} if (message.length() > 0) { byte[] send = message.getBytes(); mChatService.write(send); }}//調(diào)用BluetoothChatService類中的write進行數(shù)據(jù)發(fā)送public void write(byte[] out) { ConnectedThread r; synchronized (this) { if (mState != STATE_CONNECTED) return; r = mConnectedThread; } r.write(out);}

如此,藍牙聊天的流程就是這樣,如果退出聊天的時候,停止所有線程;

public synchronized void stop() { LogUtils.getInstance().e(getClass(), "---stop()"); setState(STATE_NONE); if (mConnectThread != null) { mConnectThread.cancel(); mConnectThread = null;} if (mConnectedThread != null) { mConnectedThread.cancel(); mConnectedThread = null;} if (mAcceptThread != null) { mAcceptThread.cancel(); mAcceptThread = null; }}

相信看完本篇文章,在安卓藍牙連接這塊應(yīng)該問題不大了(spp協(xié)議)。

源碼地址:點我查看源碼

以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持武林網(wǎng)。

發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 台中市| 莫力| 浦县| 都安| 巴楚县| 广安市| 泉州市| 西昌市| 分宜县| 宝丰县| 滨州市| 云龙县| 岚皋县| 杂多县| 南江县| 康定县| 江陵县| 鱼台县| 崇阳县| 凯里市| 海宁市| 漯河市| 淮南市| 类乌齐县| 年辖:市辖区| 常宁市| 富源县| 门头沟区| 汝城县| 兴仁县| 郁南县| 清水河县| 江西省| 罗源县| 饶河县| 澳门| 朝阳市| 斗六市| 弋阳县| 南木林县| 凉城县|