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

首頁 > 系統 > Android > 正文

Android實現一對一藍牙聊天APP

2019-12-12 00:49:25
字體:
來源:轉載
供稿:網友

學習了,三天的Android 藍牙開發,開始是一頭霧水,看著別人講的Google官方的demo感覺很容易,所有自己也嘗試寫一個很簡單的聊天demo.可是想的很簡單,自己做起來也花了,將近一天的時間才搞定這個基本的流程設計.下面是幾點心得后面再貼代碼

1)寫一個簡單的demo也好,記得一定需要有總體的流程,才開始摳代碼
2)既然是demo畢竟就是新的知識,代碼中間的log點一定/不能少,這是你快速調試的利器
3)還是thinking in java 里面的那句話,思考什么是可變的,什么是不可變的,然后分開,這樣來實現代碼的封裝,感覺很不錯了.只是現在感覺還是很難想明白
4)開始思考以面向對象的流程處理問題,需要怎么弄,也是封裝代碼的一種思想

藍牙聊天的基本功能:

1.實現一對一藍牙連接
2.實現一對一聊天

很簡單的功能,思路看著也很清晰,可是深入去寫,才知道,水還是深度的,java不熟的話.
此處基本的如何打開藍牙不在復述,請自行百度.

思路:

1)初始化,打開手機的藍牙,開始藍牙服務器線程,等待連接
2)配對,獲取某臺手機的藍牙address地址.
3)開啟連接線程連接手機藍牙
4)連接成功后,開啟,藍牙聊天的線程,進行聊天的通訊.

上面四步是主要思路,其中存在著幾個細節的地方,就是在開發中某些邏輯問題,線程間的安全問題,也是需要好好處理的. 讓我感受比較深的地方是,一對一聊天,相當于,首相每臺機器都可能作為服務器在進行通訊,所以一開始開啟了兩個服務監聽,一旦有一個接入進來,這里需要弄清楚哪個是接入對象,哪個是被接入對象, 沒有作為服務端的,可以把服務端線程關閉掉。

下面貼點代碼

/** * 客戶端啟動連接線程 * 通過藍牙的mac地址獲取連接 * @author Administrator * */ private class ConnectThread extends Thread { private BluetoothDevice mDevice; private BluetoothSocket btSocket = null; public ConnectThread(String address) {  // TODO Auto-generated constructor stub  mDevice = mBluetoothAdapter.getRemoteDevice(address); } @Override public void run() {  // TODO Auto-generated method stub  connect(mDevice); } private void connect(BluetoothDevice btDev) {  Method creMethod;  try {  creMethod = BluetoothDevice.class.getMethod("createBond");  creMethod.invoke(btDev);  } catch (Exception e) {  // TODO Auto-generated catch block  e.printStackTrace();  }  try {  btSocket = btDev.createRfcommSocketToServiceRecord(MYUUID);  System.out.println("========" + "start connect");  Log.d("BlueToothTestActivity", "開始連接...");  btSocket.connect();  mClientSocket = btSocket;  isConnected=true;  mHandler.sendEmptyMessage(SUCCESS_SERVICE_BEGIN_TALKING);  // 作為客戶端 關閉 服務端 等待的鏈接  if (acceptThread != null) {   acceptThread.close();  }  startTalk();  } catch (IOException e) {  // TODO Auto-generated catch block  System.out.println("???????????????? close socket");  close();  System.out.println(e.toString());  e.printStackTrace();  } } private void close() {  if (btSocket != null) {  try {   btSocket.close();   mHandler.sendEmptyMessage(FAILED_SERVICE_SOCRCKET);  } catch (IOException e1) {   // TODO Auto-generated catch block   e1.printStackTrace();  }  } }}
/** * 服務端的設計 * 每個藍牙的客戶端先要開啟服務端等待接入 * @author Administrator **/ 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 the client  // code  tmp = mBluetoothAdapter.listenUsingRfcommWithServiceRecord("Fisrt", MYUUID);  } catch (IOException e) {  mHandler.sendEmptyMessage(FAILED_SERVICE_SOCRCKET);  }  mmServerSocket = tmp; } public void run() {  BluetoothSocket socket = null;  // Keep listening until exception occurs or a socket is returned  while (isRun) {  try {   socket = mmServerSocket.accept();   mHandler.sendEmptyMessage(SUCCESS_SERVICE_SOCRCKET);   Log.e("TAG", "========== server start ====");  } catch (IOException e) {   mHandler.sendEmptyMessage(FAILED_SERVICE_SOCRCKET);   close();  }  // If a connection was accepted  if (socket != null) {   // 服務端連接成功,啟動聊天線程,通過 同一個 socket 防止多線程賦值出現空值的問題   isConnected=true;   mClientSocket = socket;   mTalkThread = new TalkThread();   mTalkThread.start();   // Do work to manage the connection (in a separate thread)   // 多線程操作小心不安全性   synchronized (BlueConnectService.this) {   //close();   }  }  } } public void close() {  isRun = false;  try {  mmServerSocket.close();  } catch (IOException e) {  // TODO Auto-generated catch block  e.printStackTrace();  } }}
/** *設計連接成功后的聊天線程 1.建立流,打通連接 2.發送和接收數據 3.顯示數據 *需要注意的是聊天的時候,需要同一個socket建立連接才能獲取對應的輸入輸出流 */ private class TalkThread extends Thread { private final BluetoothSocket talkSocket; private final InputStream mIs; private final OutputStream mOs; private boolean isRunning = true; public TalkThread() {  // TODO Auto-generated constructor stub  talkSocket = mClientSocket;  if (talkSocket == null) {  System.out.println("================= talkThread erro ");  // return;  }  InputStream is = null;  OutputStream os = null;  try {  is = talkSocket.getInputStream();  os = talkSocket.getOutputStream();  } catch (IOException e) {  // TODO Auto-generated catch block  try {   System.out.println("???????????????? close socket");   talkSocket.close();   CloseUtil.closeStream(is, os);  } catch (IOException e1) {   // TODO Auto-generated catch block   e1.printStackTrace();  }  e.printStackTrace();  }  mIs = is;  mOs = os; } @Override public void run() {  // TODO Auto-generated method stub  super.run();  byte[] buffer = new byte[1024];  int len;  while (isRunning) {  try {   len = mIs.read(buffer);   mHandler.obtainMessage(READ_MESSAGE, len, -1, buffer).sendToTarget();  } catch (IOException e) {   // TODO Auto-generated catch block   e.printStackTrace();   try {   isRunning = false;   isConnected=false;   System.out.println("???????????????? close socket");   talkSocket.close();   // 需要重啟服務器   // 啟動服務器   } catch (IOException e1) {   // TODO Auto-generated catch block   e1.printStackTrace();   }   CloseUtil.closeStream(mIs, mOs);  }  } } public void write(byte[] bytes) {  try {  mOs.write(bytes);  mHandler.obtainMessage(WRITE_MESSAGE, bytes.length, -1, bytes).sendToTarget();  } catch (IOException e) {  // TODO Auto-generated catch block  e.printStackTrace();  } }}

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持武林網。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 横峰县| 凤城市| 清苑县| 上虞市| 巴青县| 通渭县| 洛阳市| 罗甸县| 西青区| 江津市| 昭觉县| 抚宁县| 广安市| 永年县| 北安市| 富锦市| 宜春市| 芦山县| 乐陵市| 镇江市| 通州区| 九江县| 双鸭山市| 宜川县| 京山县| 临西县| 固原市| 新宾| 上林县| 海城市| 甘谷县| 竹北市| 陆丰市| 巩留县| 延寿县| 蒙自县| 嘉定区| 原阳县| 闽侯县| 苍梧县| 宣城市|