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

在项目中经常用到蓝牙的应用,在这里特意写了一个demo。并且封装了代码,可以主动连接和被动连接一起使用,也可以分开使用。方便后面以后查询使用,也重新踩了部分坑。

项目地址:android实现蓝牙聊天功能

1、程序简单的界面

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。不然启动搜索蓝牙无效。

(0)

相关推荐

  • android获取ibeacon列表的方法

    android获取ibeacon列表,供大家参考,具体内容如下 最近公司有需要做ibeacon需求. 因为涉及扫码的时间.特意写一个service实现获取列表 可以根据扫描时间扫描出ibeacon列表 包含 uuid,设备名称,单位(米),电量等. 请根据自己的项目进行改造代码. 核心代码如下: /** * * <ibeaon服务> * * @author fulushan * @date 创建时间:2018年4月5日 下午11:34:04 */ public class IbeaconSer

  • Android 蓝牙连接 ESC/POS 热敏打印机打印实例(蓝牙连接篇)

    公司的一个手机端的 CRM 项目最近要增加小票打印的功能,就是我们点外卖的时候经常会见到的那种小票.这里主要涉及到两大块的知识: 蓝牙连接及数据传输 ESC/POS 打印指令 蓝牙连接不用说了,太常见了,这篇主要介绍这部分的内容.但ESC/POS 打印指令是个什么鬼?简单说,我们常见的热敏小票打印机都支持这样一种指令,只要按照指令的格式向打印机发送指令,哪怕是不同型号品牌的打印机也会执行相同的动作.比如打印一行文本,换行,加粗等都有对应的指令,这部分内容放在下一篇介绍. 本篇主要基于官方文档,相

  • Android系统中的蓝牙连接程序编写实例教程

    Bluetooth结构 1.JAVA层 frameworks/base/core/java/android/bluetooth/ 包含了bluetooth的JAVA类. 2.JNI层 frameworks/base/core/jni/android_bluetooth_开头的文件 定义了bluez通过JNI到上层的接口. frameworks/base/core/jni/android_server_bluetoothservice.cpp 调用硬件适配层的接口system/bluetooth/

  • iBeacon使用蓝牙连接范围精确到1-3米

    最近再写一个项目,需要自动签到.用的就是iBeacon,刚开始的时候比较懵比,不知道iBeacon是用来干啥的.因为iBeacon就是一个小盒盒,还是密封好的,就感觉自己懵了.然后上网查资料,才知道iBeacon就是一个小型的基站,手机打开蓝牙之后,如果你在这个基站的范围之内,会自动匹配上.你对iBeacon不需要做任何的操作,因为里面有电池,说是可以使用5年左右. 以上就是大概的情况,接下来介绍的是代码展示部分. 首先,在你的主清单中AndroidManifest.xml中添加权限: <use

  • Android提高之BLE开发Android手机搜索iBeacon基站

    前面文章讲述了Android手机与BLE终端之间的通信,而最常见的BLE终端应该是苹果公司倡导的iBeacon基站.iBeacon技术基于BLE,它的特点是通过广播对外发送消息,手机不需要连上iBeacon基站也能获取它的信息,目前主要用来做室内定位和营销信息推送,在BLE发出的广播里带上带上特定的信息从而被识别为iBeacon.在iOS里面使用iBeacon要经过passbook注册iBeacon的UUID和对应的文字简介,而在Android上则无类似passbook这种系统级的后台蓝牙搜索服

  • Android 蓝牙连接 ESC/POS 热敏打印机打印实例(ESC/POS指令篇)

    上一篇 主要介绍了如何通过蓝牙连接到打印机.这一篇,我们就介绍如何向打印机发送打印指令,来打印字符和图片. 1. 构造输出流 首先要明确一点,就是蓝牙连接打印机这种场景下,手机是 Client 端,打印机是 Server 端. 在上一篇的最后,我们从 BluetoothSocket 得到了一个OutputStream.这里我们做一层包装,得到一个OutputStreamWriter 对象: OutputStreamWriter writer = new OutputStreamWriter(ou

  • Android 扫描附近的蓝牙设备并连接蓝牙音响的示例

    写了一个可以扫描附近蓝牙设备的小Demo,可以查看蓝牙设备的设备名和Mac地址 代码量不多,很容易看懂 /** * 作者:叶应是叶 * 时间:2017/9/8 20:13 * 描述: */ public class ScanDeviceActivity extends AppCompatActivity { private LoadingDialog loadingDialog; private DeviceAdapter deviceAdapter; private BluetoothAdap

  • Android手机通过蓝牙连接佳博打印机的实例代码

    所使用的打印机为佳博打印机,支持蓝牙.wifi.usb我所使用的是通过蓝牙来连接. 在网上找到一个佳博官方针对安卓开发的App源码,但是各种的跳转,没有看太懂,所以又去问度娘,找到了一个不错的文章 Android对于蓝牙开发从2.0版本的sdk才开始支持,而且模拟器不支持,测试至少需要两部手机,所以制约了很多技术人员的开发. 1. 首先,要操作蓝牙,先要在AndroidManifest.xml里加入权限 // 管理蓝牙设备的权限 <uses-permissionandroid:name="

  • Android开发实现实时检测蓝牙连接状态的方法【附源码下载】

    本文实例讲述了Android开发实现实时检测蓝牙连接状态的方法.分享给大家供大家参考,具体如下: 本程序能实时监听并检测Android蓝牙的连接状态,无论是通过界面上的switch按钮打开/关闭手机蓝牙,还是手动打开/关闭手机蓝牙,程序都能监听当前的状态. 一.软件界面 二.程序实现 ① switch开关--打开/关闭蓝牙 Switch switchTest = (Switch) findViewById(R.id.switch1); switchTest.setOnCheckedChangeL

  • Android检测IBeacon热点的方法

    IBeacon是BLE的一种,搜索iBeacon基站关键在于设备扫描到的scanRecord数组,识别是否有下面加粗斜体的02 15这两个数字.如果有,搜索到的蓝牙设备就是IBeacon. // AirLocate: // 02 01 1a 1a ff 4c 00 02 15 # Apple's fixed iBeacon advertising prefix // e2 c5 6d b5 df fb 48 d2 b0 60 d0 f5 a7 10 96 e0 # iBeacon profile

随机推荐