温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

android实现主动连接和被动连接的蓝牙聊天功能

发布时间:2020-09-13 21:11:37 来源:脚本之家 阅读:441 作者:mmsx 栏目:移动开发

在项目中经常用到蓝牙的应用,在这里特意写了一个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。不然启动搜索蓝牙无效。

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI