android 蓝牙聊天(主动连接和被动连接)

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

项目地址:https://gitee.com/mmsxxiaomo/BluetoothChat

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




评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值