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

首頁 > 系統 > Android > 正文

android實現主動連接和被動連接的藍牙聊天功能

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

在項目中經常用到藍牙的應用,在這里特意寫了一個demo。并且封裝了代碼,可以主動連接和被動連接一起使用,也可以分開使用。方便后面以后查詢使用,也重新踩了部分坑。

項目地址:android實現藍牙聊天功能

1、程序簡單的界面

android,主動連接,被動連接,藍牙聊天

android,主動連接,被動連接,藍牙聊天

android,主動連接,被動連接,藍牙聊天

2、客戶端,主動連接

package com.bluetooth.tool;  import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothDevice; import android.bluetooth.BluetoothSocket;  import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.util.UUID;  //藍牙連接管理類 public class BluetoothManage {  private static final Object mLock = new Object();  //藍牙類的具體實現核心成員  private BluetoothAdapter mBtAdapter = BluetoothAdapter.getDefaultAdapter();  //藍牙類的具體數據核心成員  private BluetoothSocket mTransferSocket = null;  //當前連接的藍牙地址  String mstrName = "";//當前連接用到的IP地址  String mstrAddress = "";//當前連接用到的IP地址  //讀線程  ReadThread mReadThread = null;  //從數據核心成員拿到的輸入輸出  InputStream mInputStream = null;  OutputStream mOutputStream = null;  private static BluetoothManage manage = null;   public static BluetoothManage getInstance(){  synchronized (BluetoothManage.class){   if(manage == null)   manage = new BluetoothManage();  }  return manage;  }   public boolean sendData(int nLength, byte[] data) {  if (mOutputStream == null) return false;  try {   mOutputStream.write(data, 0, nLength);   return true;  } catch (IOException e) {   e.printStackTrace();  }  return false;  }   ConnectListener mConnectListener = null;   public void regConnectListener(ConnectListener arg0) {  mConnectListener = arg0;  }   TopDataIOListener mIOListener = null;   public void regIOListener(TopDataIOListener arg0) {  mIOListener = arg0;  }   public void unRegIOListener() {  mIOListener = null;  }   public boolean setSelectedDevice(String strDevice) {  String[] strings = strDevice.split("//|");   if (strings.length == 2) {   mstrName = strings[0];   mstrAddress = strings[1];   return true;  }  return false;  }   public String getSelectedDeviceName() {  if (mstrAddress.length() == 0) {   return null;  }   return String.format("%s|%s", mstrName, mstrAddress);  }   public void connect() {  if (mstrAddress.length() == 0) return;   final BluetoothDevice device = mBtAdapter.getRemoteDevice(mstrAddress);  new Thread(new Runnable() {   @Override   public void run() {   synchronized (mLock) {    String strLogString = "";    try {    try {     mTransferSocket = device.createRfcommSocketToServiceRecord(UUID.fromString("00001101-0000-1000-8000-00805F9B34FB"));    } catch (IOException e1) {     mTransferSocket = null;    }     if (mTransferSocket == null) {     if (null != mConnectListener)     mConnectListener.OnConnectStatusCallBack(false);     return;    }    long nStartMillTime = System.currentTimeMillis();     //連接    try {     mTransferSocket.connect();    } catch (IOException e1) {     try {     mTransferSocket.close();     } catch (IOException e2) {     e2.printStackTrace();     }     //等待一定時間     mTransferSocket = null;      try {     long havePassTime = System.currentTimeMillis() - nStartMillTime;     if (havePassTime < 6000) {      Thread.sleep(7000 - havePassTime);     }     } catch (InterruptedException e) {     e.printStackTrace();     }    }    //連接失敗    if (mTransferSocket == null) {     if (null != mConnectListener)     mConnectListener.OnConnectStatusCallBack(false);     return;    }     try {     mInputStream = mTransferSocket.getInputStream();     mOutputStream = mTransferSocket.getOutputStream();     mReadThread = new ReadThread();     mReadThread.start();      if (null != mConnectListener)     mConnectListener.OnConnectStatusCallBack(true);    } catch (IOException e1) {     //斷開連接     try {     if (mTransferSocket != null)      mTransferSocket.close();     } catch (IOException e2) {     e2.printStackTrace();     }      mTransferSocket = null;     e1.printStackTrace();      if (null != mConnectListener)     mConnectListener.OnConnectStatusCallBack(false);    }    } catch (Exception e) {    //總體異常    if (null != mConnectListener)     mConnectListener.OnConnectStatusCallBack(false);    }   }   }//run()  }).start();  }   //讀取數據  class ReadThread extends Thread {  public void run() {   int nMaxBufLength = 1024;   byte[] buffer = new byte[nMaxBufLength];   int byteRead = -1;    synchronized (mLock) {   while (!isInterrupted()) {    try {    if (mInputStream != null) {     byteRead = mInputStream.read(buffer);     if (byteRead > 0 && byteRead <= buffer.length) {     if (mIOListener != null)      mIOListener.OnIOCallBack(byteRead, buffer);     } else /*if (byteRead < 0 || byteRead > buffer.length)*/ {     //連接已斷開     if (mConnectListener != null) {      mConnectListener.OnDisConnectCallBack();     }     break;     }    } else {     break;    }    } catch (IOException e) {    //連接已斷開    if (mConnectListener != null) {     mConnectListener.OnDisConnectCallBack();    }    break;    }   }//while(!isInterrupted())   }//synchronized (mLock)  }  }   //斷開藍牙  public void disConnect() {  mConnectListener = null;  //結束讀線程  if (mReadThread != null) {   mReadThread.interrupt();   mReadThread = null;  }  //取消所有連接  if (mTransferSocket != null) {   try {   mTransferSocket.close();   if (mInputStream != null)    mInputStream.close();   if (mOutputStream != null)    mOutputStream.close();   mInputStream = null;   mOutputStream = null;   mTransferSocket = null;   } catch (IOException e) {   e.printStackTrace();   } catch (Exception e) {   }  }  } } 

主動連接應該是比較簡單的,一個類就能實現,包括數據的收發。

3、藍牙服務端,接收藍牙連接

/**  * Copyright (C) 2009 The Android Open Source Project  *  * Licensed under the Apache License, Version 2.0 (the "License");  * you may not use this file except in compliance with the License.  * You may obtain a copy of the License at  *  * http://www.apache.org/licenses/LICENSE-2.0  *  * Unless required by applicable law or agreed to in writing, software  * distributed under the License is distributed on an "AS IS" BASIS,  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  * See the License for the specific language governing permissions and  * limitations under the License.  */  package com.bluetooth.tool;  import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothDevice; import android.bluetooth.BluetoothServerSocket; import android.bluetooth.BluetoothSocket; import android.content.Context; import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.util.Log; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.util.UUID;  /**  * This class does all the work for setting up and managing Bluetooth  * connections with other devices. It has a thread that listens for incoming  * connections, a thread for connecting with a device, and a thread for  * performing data transmissions when connected.  */ public class BluetoothChatService {  // Debugging  private static final String TAG = "BluetoothChatService";  private static final boolean D = true;   // Name for the SDP record when creating server socket  private static final String NAME = "BluetoothChat";   // Unique UUID for this application  // private static final UUID MY_UUID =  // UUID.fromString("fa87c0d0-afac-11de-8a39-0800200c9a66");  private static final UUID MY_UUID = UUID   .fromString("00001101-0000-1000-8000-00805F9B34FB");  //   // Member fields  private final BluetoothAdapter mAdapter;  private final Handler mHandler;  private AcceptThread mAcceptThread;  private ConnectThread mConnectThread;  private ConnectedThread mConnectedThread;  private int mState;  private BluetoothDevice mBluetoothDevice = null;   // Constants that indicate the current connection state  public static final int STATE_NONE = 0; // we're doing nothing  public static final int STATE_LISTEN = 1; // now listening for incoming       // connections  public static final int STATE_CONNECTING = 2; // now initiating an outgoing        // connection  public static final int STATE_CONNECTED = 3; // now connected to a remote        // device   public static boolean mbIsOpenTimer = false;  /**  * Constructor. Prepares a new BluetoothChat session.  *  * @param context  *  The UI Activity Context  * @param handler  *  A Handler to send messages back to the UI Activity  */  public BluetoothChatService(Context context, Handler handler) {  mAdapter = BluetoothAdapter.getDefaultAdapter();  mState = STATE_NONE;  mHandler = handler;  }   /**  * Set the current state of the chat connection  *  * @param state  *  An integer defining the current connection state  */  private synchronized void setState(int state) {  if (D)   Log.d(TAG, "setState() " + mState + " -> " + state);  mState = state;   // Give the new state to the Handler so the UI Activity can update  mHandler.obtainMessage(BluetoothChat.MESSAGE_STATE_CHANGE, state, -1)   .sendToTarget();  }   /**  * Return the current connection state.  */  public synchronized int getState() {  return mState;  }   /**  * Start the chat service. Specifically start AcceptThread to begin a  * session in listening (server) mode. Called by the Activity onResume()  */  public synchronized void start() {  if (D)   Log.d(TAG, "start");   // Cancel any thread attempting to make a connection  if (mConnectThread != null) {   mConnectThread.cancel();   mConnectThread = null;  }   // Cancel any thread currently running a connection  if (mConnectedThread != null) {   mConnectedThread.cancel();   mConnectedThread = null;  }   // Start the thread to listen on a BluetoothServerSocket  if (mAcceptThread == null) {   Log.d(TAG, "start mAcceptThread");   mAcceptThread = new AcceptThread();   mAcceptThread.start();  }  setState(STATE_LISTEN);  }   /**  * Start the ConnectThread to initiate a connection to a remote device.  *  * @param device  *  The BluetoothDevice to connect  */  public synchronized void connect(BluetoothDevice device) {  if (D)   Log.d(TAG, "connect to: " + device);   // Cancel any thread attempting to make a connection  if (mState == STATE_CONNECTING) {   if (mConnectThread != null) {   mConnectThread.cancel();   mConnectThread = null;   }  }   // Cancel any thread currently running a connection  if (mConnectedThread != null) {   mConnectedThread.cancel();   mConnectedThread = null;  }   // Start the thread to connect with the given device  mConnectThread = new ConnectThread(device);  mConnectThread.start();  setState(STATE_CONNECTING);  mBluetoothDevice = device;  }   /**  * Start the ConnectedThread to begin managing a Bluetooth connection  *  * @param socket  *  The BluetoothSocket on which the connection was made  * @param device  *  The BluetoothDevice that has been connected  */  public synchronized void connected(BluetoothSocket socket,   BluetoothDevice device) {  if (D)   Log.d(TAG, "connected");   // Cancel the thread that completed the connection  if (mConnectThread != null) {   mConnectThread.cancel();   mConnectThread = null;  }   // Cancel any thread currently running a connection  if (mConnectedThread != null) {   mConnectedThread.cancel();   mConnectedThread = null;  }   // Cancel the accept thread because we only want to connect to one  // device  if (mAcceptThread != null) {   mAcceptThread.cancel();   mAcceptThread = null;  }   // Start the thread to manage the connection and perform transmissions  mConnectedThread = new ConnectedThread(socket);  mConnectedThread.start();   // Send the name of the connected device back to the UI Activity  Message msg = mHandler.obtainMessage(BluetoothChat.MESSAGE_DEVICE_NAME);  Bundle bundle = new Bundle();  bundle.putString(BluetoothChat.DEVICE_NAME, device.getName());  msg.setData(bundle);  mHandler.sendMessage(msg);   setState(STATE_CONNECTED);  }   /**  * Stop all threads  */  public synchronized void stop() {  if (D)   Log.d(TAG, "stop");  if (mConnectThread != null) {   mConnectThread.cancel();   mConnectThread = null;  }  if (mConnectedThread != null) {   mConnectedThread.cancel();   mConnectedThread = null;  }  if (mAcceptThread != null) {   mAcceptThread.cancel();   mAcceptThread = null;  }  setState(STATE_NONE);  }   /**  * Write to the ConnectedThread in an unsynchronized manner  *  * @param out  *  The bytes to write  * @see ConnectedThread#write(byte[])  */  public void write(byte[] out) {  // Create temporary object  ConnectedThread r;  // Synchronize a copy of the ConnectedThread  synchronized (this) {   if (mState != STATE_CONNECTED)   return;   r = mConnectedThread;  }  // Perform the write unsynchronized  r.write(out);  }   /**  * Indicate that the connection attempt failed and notify the UI Activity.  */  private void connectionFailed() {  setState(STATE_LISTEN);   // Send a failure message back to the Activity  Message msg = mHandler.obtainMessage(BluetoothChat.MESSAGE_TOAST);  Bundle bundle = new Bundle();  bundle.putString(BluetoothChat.TOAST, "Unable to connect device");  msg.setData(bundle);  mHandler.sendMessage(msg);  }   /**  * Indicate that the connection was lost and notify the UI Activity.  */  private void connectionLost() {  setState(STATE_LISTEN);   // Send a failure message back to the Activity  Message msg = mHandler.obtainMessage(BluetoothChat.MESSAGE_TOAST);  Bundle bundle = new Bundle();  bundle.putString(BluetoothChat.TOAST, "Device connection was lost");  msg.setData(bundle);  mHandler.sendMessage(msg);  start();  }   /**  * This thread runs while listening for incoming connections. It behaves  * like a server-side client. It runs until a connection is accepted (or  * until cancelled).  */  private class AcceptThread extends Thread {  // The local server socket  private final BluetoothServerSocket mmServerSocket;   public AcceptThread() {   BluetoothServerSocket tmp = null;    // Create a new listening server socket   try {   tmp = mAdapter    .listenUsingRfcommWithServiceRecord(NAME, MY_UUID);   } catch (IOException e) {   Log.e(TAG, "listen() failed", e);   }   mmServerSocket = tmp;  }   public void run() {   if (D)   Log.d(TAG, "BEGIN mAcceptThread" + this);   setName("AcceptThread");   BluetoothSocket socket = null;    // Listen to the server socket if we're not connected   while (mState != STATE_CONNECTED) {   try {    // This is a blocking call and will only return on a    // successful connection or an exception    if(mmServerSocket != null)    {    Log.d(TAG, "waitting accept!");    socket = mmServerSocket.accept();    Log.d(TAG, "accpting!");    }    else    {    setState(STATE_NONE);        if (mAcceptThread != null) {     mAcceptThread = null;    }        Log.d(TAG, "mmServerSocket = null!");    break;    }      } catch (IOException e) {    Log.e(TAG, "accept() failed", e);    break;   }    // If a connection was accepted   if (socket != null) {    synchronized (BluetoothChatService.this) {    switch (mState) {    case STATE_LISTEN:    case STATE_CONNECTING:     // Situation normal. Start the connected thread.     connected(socket, socket.getRemoteDevice());     break;    case STATE_NONE:    case STATE_CONNECTED:     // Either not ready or already connected. Terminate     // new socket.     try {     socket.close();     } catch (IOException e) {     Log.e(TAG, "Could not close unwanted socket", e);     }     break;    }    }   }   }   if (D)   Log.i(TAG, "END mAcceptThread");  }   public void cancel() {   if (D)   Log.d(TAG, "cancel " + this);   try {   if(mmServerSocket != null)    mmServerSocket.close();   } catch (IOException e) {   Log.e(TAG, "close() of server failed", e);   }  }  }   /**  * This thread runs while attempting to make an outgoing connection with a  * device. It runs straight through; the connection either succeeds or  * fails.  */  private class ConnectThread extends Thread {  private final BluetoothSocket mmSocket;  private final BluetoothDevice mmDevice;   public ConnectThread(BluetoothDevice device) {   mmDevice = device;   BluetoothSocket tmp = null;    // Get a BluetoothSocket for a connection with the   // given BluetoothDevice   try {   tmp = device.createRfcommSocketToServiceRecord(MY_UUID);   } catch (IOException e) {   Log.e(TAG, "create() failed", e);   }   mmSocket = tmp;  }   public void run() {   Log.i(TAG, "BEGIN mConnectThread");   setName("ConnectThread");    // Always cancel discovery because it will slow down a connection   mAdapter.cancelDiscovery();    // Make a connection to the BluetoothSocket   try {   // This is a blocking call and will only return on a   // successful connection or an exception   mmSocket.connect();   } catch (IOException e) {   connectionFailed();   // Close the socket   try {    mmSocket.close();   } catch (IOException e2) {    Log.e(TAG,     "unable to close() socket during connection failure",     e2);   }   // Start the service over to restart listening mode   BluetoothChatService.this.start();   return;   }    // Reset the ConnectThread because we're done   synchronized (BluetoothChatService.this) {   mConnectThread = null;   }    // Start the connected thread   connected(mmSocket, mmDevice);  }   public void cancel() {   try {   mmSocket.close();   } catch (IOException e) {   Log.e(TAG, "close() of connect socket failed", e);   }  }  }   /**  * This thread runs during a connection with a remote device. It handles all  * incoming and outgoing transmissions.  */  private class ConnectedThread extends Thread {  private final BluetoothSocket mmSocket;  private final InputStream mmInStream;  private final OutputStream mmOutStream;   public ConnectedThread(BluetoothSocket socket) {   Log.d(TAG, "create ConnectedThread");   mmSocket = socket;   InputStream tmpIn = null;   OutputStream tmpOut = null;   try {   tmpIn = socket.getInputStream();   tmpOut = socket.getOutputStream();   } catch (IOException e) {   Log.e(TAG, "temp sockets not created", e);   }    mmInStream = tmpIn;   mmOutStream = tmpOut;  }   public void run() {   Log.i(TAG, "BEGIN mConnectedThread");   byte[] buffer = new byte[1024];   int bytes;    // Keep listening to the InputStream while connected   while (true) {   try {    // Read from the InputStream    if(mmInStream != null ){    bytes = mmInStream.read(buffer);    if(bytes > 0 && bytes <= buffer.length)    {     onDadaReceive(buffer,0,bytes);    }    else{     Log.i("recieve", "Baddata");    }    }    else{    Log.i(TAG, "BadInputStream");    connectionLost();    break;    }   }   catch (IOException e) {    Log.i(TAG, "disconnected" + e.toString(), e);    connectionLost();    break;   } catch (Exception e) {    e.printStackTrace();   }   }  }   private void onDadaReceive(byte[] buffer, int i, int bytes) {   if(bytes>0)   {   //????   mHandler.obtainMessage(BluetoothChat.MESSAGE_READ, bytes,    -1, buffer).sendToTarget();    }   else   Log.e("recieve","null");   }   /**   * Write to the connected OutStream.   *   * @param buffer   *  The bytes to write   */  public void write(byte[] buffer) {   try {   mmOutStream.write(buffer);    // Share the sent message back to the UI Activity   mHandler.obtainMessage(BluetoothChat.MESSAGE_WRITE, -1, -1,    buffer).sendToTarget();   } catch (IOException e) {   Log.e(TAG, "Exception during write", e);   }  }   public void cancel() {   try {   mmSocket.close();   } catch (IOException e) {   Log.e(TAG, "close() of connect socket failed", e);   }  }  }  } 

這個藍牙服務的代碼,是標準藍牙示例demo代碼

我根據上面,自已封裝了一層,方便管理數據。

package com.bluetooth.tool;  import android.content.Context; import android.os.Handler; import android.os.Message; import android.util.Log;  /**  * 藍牙服務,接收藍牙連接  */ public class BluetoothChat {  // Debugging  private static final String TAG = "BluetoothChat";  private static final boolean D = true;   public static final int MESSAGE_STATE_CHANGE = 1;  public static final int MESSAGE_READ = 2;  public static final int MESSAGE_WRITE = 3;  public static final int MESSAGE_DEVICE_NAME = 4;  public static final int MESSAGE_TOAST = 5;   // Key names received from the BluetoothChatService Handler  public static final String DEVICE_NAME = "device_name";  public static final String TOAST = "toast";   private String mConnectedDeviceName = null;  private static StringBuffer mOutStringBuffer;  private static BluetoothChatService mChatService = null;  private static Context mContext;  private volatile static BluetoothChat mBluetoothChat = null;  TopDataIOListener mIOListener = null;   public static BluetoothChat GetInstance(Context context) {  if (mBluetoothChat == null && mContext == null) {   synchronized (BluetoothChat.class){   mBluetoothChat = new BluetoothChat();   mContext = context;   }  }  return mBluetoothChat;  }    public void onStart() {  if (mChatService == null)   setupChat();  if (mChatService != null) {   if (mChatService.getState() == BluetoothChatService.STATE_NONE) {   mChatService.start();   }  }  }   private void setupChat() {  mChatService = new BluetoothChatService(mContext,mHandler);  mOutStringBuffer = new StringBuffer("");  }   public void onDestroy() {  if (mChatService != null)   mChatService.stop();  }   public void sendMessage(String message) {  if (mChatService.getState() != BluetoothChatService.STATE_CONNECTED) {   Log.i("Show", "");   return;  }  if (message.length() > 0) {   byte[] send = message.getBytes();   mChatService.write(send);   mOutStringBuffer.setLength(0);  }  }   private final Handler mHandler = new Handler() {  @Override  public void handleMessage(Message msg) {   switch (msg.what) {   case MESSAGE_STATE_CHANGE:   if (D)    Log.i(TAG, "MESSAGE_STATE_CHANGE: " + msg.arg1);   switch (msg.arg1) {   case BluetoothChatService.STATE_CONNECTED:    break;   case BluetoothChatService.STATE_CONNECTING:    break;   case BluetoothChatService.STATE_LISTEN:    break;   case BluetoothChatService.STATE_NONE:    break;   }   break;   case MESSAGE_WRITE:   byte[] writeBuf = (byte[]) msg.obj;   String writeMessage = new String(writeBuf);   break;   case MESSAGE_READ:   byte[] readBuf = (byte[]) msg.obj;   //收到的藍牙數據,回傳給界面顯示   if (mIOListener != null)    mIOListener.OnIOCallBack(readBuf.length, readBuf);   break;   case MESSAGE_DEVICE_NAME:   mConnectedDeviceName = msg.getData().getString(DEVICE_NAME);   Log.i(TAG, "MESSAGE_DEVICE_NAME " + mConnectedDeviceName);   break;   case MESSAGE_TOAST:   break;   }  }  };   public void regIOListener(TopDataIOListener arg0) {  mIOListener = arg0;  }  } 

還有一個藍牙的廣播。這里就不貼代碼了。

4、權限

<uses-permission android:name="android.permission.BLUETOOTH" /> <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" /> <!-- 部分手機6.0以上 藍牙startDiscovery方法需要加上這個權限 --> <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/> 

藍牙服務接收廣播注冊

<receiver android:name=".tool.BluetoothReceiver">  <intent-filter android:priority="1000">  <action android:name="android.bluetooth.adapter.action.STATE_CHANGED"/>  <action android:name="android.bluetooth.device.action.ACL_CONNECTED"/>  <action android:name="android.bluetooth.device.action.ACL_DISCONNECTED"/>  <action android:name="android.bluetooth.device.action.BOND_STATE_CHANGED"/>  </intent-filter> </receiver> 

5、在上面注釋看到了有個bug注釋

就是部分手機6.0以上 藍牙藍牙startDiscovery方法需要加上這個權限android.permission.ACCESS_COARSE_LOCATION。不然啟動搜索藍牙無效。


注:相關教程知識閱讀請移步到Android開發頻道。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 郴州市| 华池县| 商河县| 吉木乃县| 和林格尔县| 天等县| 峨边| 德化县| 平江县| 乌兰察布市| 寿光市| 阆中市| 临西县| 周至县| 油尖旺区| 安庆市| 乐陵市| 揭阳市| 宜州市| 泸西县| 安塞县| 中方县| 鄂托克前旗| 西宁市| 讷河市| 嵩明县| 定远县| 蓬安县| 威远县| 内丘县| 沧源| 宣化县| 个旧市| 楚雄市| 株洲县| 高安市| 石河子市| 塔城市| 临西县| 武乡县| 唐河县|