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

首頁 > 系統 > Android > 正文

Android實現一對一藍牙聊天APP

2019-10-22 18:10:14
字體:
來源:轉載
供稿:網友

學習了,三天的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();  } }}

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


注:相關教程知識閱讀請移步到Android開發頻道。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 论坛| 永德县| 茶陵县| 巴塘县| 东兴市| 沙湾县| 弥勒县| 温泉县| 阳高县| 桐城市| 哈巴河县| 莫力| 浠水县| 沙雅县| 自贡市| 政和县| 香格里拉县| 济宁市| 郧西县| 海晏县| 文山县| 正镶白旗| 新乡市| 宁海县| 武穴市| 曲靖市| 扎赉特旗| 台安县| 乳山市| 遂昌县| 临泉县| 雷山县| 丘北县| 云阳县| 突泉县| 新干县| 和顺县| 凤山市| 江源县| 南投县| 始兴县|