当前位置:   article > 正文

Android 蓝牙设备通讯的开发(配对/连接/传输数据)_android 获取蓝牙列表,连接蓝牙,发送数据

android 获取蓝牙列表,连接蓝牙,发送数据

最近公司想做一个关于蓝牙的项目,同时我也学习到了很多关于蓝牙方面的很多知识点,希望在这里跟大家分享下,不足之处有望指明.

项目源码:http://download.csdn.net/detail/qq_30552993/9529815

这里先附上项目图片,不过这里ListView中如果是已配对的就进行连接,如果是未配对的就进行配对,配对完成之后这里的话要重新搜索设备,这里没做刷新.还有就是可以在两只手机上都装上这个,再连接上就可以进行发送到另一只手机上去,不知道为什么有时候好像蓝牙有些不知是否不太稳定,出现搜索蓝牙有些没搜到.

在很多方面,蓝牙是一种能够发送或接受两个不同的设备之间传输的数据。 Android平台包含了蓝牙框架,使设备以无线方式与其他蓝牙设备进行数据交换的支持。

Android提供蓝牙API来执行这些不同的操作。

  1. 扫描其他蓝牙设备
  2. 获取配对设备列表
  3. 连接到通过服务发现其他设备
  • Android提供BluetoothAdapter类蓝牙通信。通过调用创建的对象的静态方法getDefaultAdapter()。其语法如下给出。
  1. private BluetoothAdapter BA;
  2. BA = BluetoothAdapter.getDefaultAdapter();
  • 这里我把一些关于蓝牙的打开/关闭/配对/连接/数据传输的线程都封装BlueToothUtils这个蓝牙工具类中
  1. import android.bluetooth.BluetoothAdapter;
  2. import android.bluetooth.BluetoothDevice;
  3. import android.bluetooth.BluetoothServerSocket;
  4. import android.bluetooth.BluetoothSocket;
  5. import android.content.Context;
  6. import android.os.Handler;
  7. import android.os.Message;
  8. import android.util.Log;
  9. import android.widget.Toast;
  10. import java.io.IOException;
  11. import java.io.InputStream;
  12. import java.io.OutputStream;
  13. import java.lang.reflect.Field;
  14. import java.lang.reflect.InvocationTargetException;
  15. import java.lang.reflect.Method;
  16. import java.util.ArrayList;
  17. import java.util.List;
  18. import java.util.Set;
  19. import java.util.UUID;
  20. /**
  21. * Created by shaolin on 5/23/16.
  22. */
  23. public class BlueToothUtils {
  24. private static final String TAG = "BlueToothUtils";
  25. private Context mContext;
  26. public static BlueToothUtils sInstance;
  27. private BluetoothAdapter mBA;
  28. // UUID.randomUUID()随机获取UUID
  29. private final UUID MY_UUID = UUID
  30. .fromString("db764ac8-4b08-7f25-aafe-59d03c27bae3");
  31. // 连接对象的名称
  32. private final String NAME = "LGL";
  33. // 这里本身即是服务端也是客户端,需要如下类
  34. private BluetoothSocket mSocket;
  35. private BluetoothDevice mOldDevice;
  36. private BluetoothDevice mCurDevice;
  37. // 输出流_客户端需要往服务端输出
  38. private OutputStream os;
  39. //线程类的实例
  40. private AcceptThread ac;
  41. public static synchronized BlueToothUtils getInstance() {
  42. if (sInstance == null) {
  43. sInstance = new BlueToothUtils();
  44. }
  45. return sInstance;
  46. }
  47. public BlueToothUtils() {
  48. mBA = BluetoothAdapter.getDefaultAdapter();
  49. ac = new AcceptThread();
  50. }
  51. public void setContext(Context context) {
  52. this.mContext = context;
  53. }
  54. public BluetoothAdapter getBA() {
  55. return mBA;
  56. }
  57. public AcceptThread getAc() {
  58. return ac;
  59. }
  60. public BluetoothDevice getCurDevice() {
  61. return mCurDevice;
  62. }
  63. /**
  64. * 判断是否打开蓝牙
  65. *
  66. * @return
  67. */
  68. public boolean isEnabled() {
  69. if (mBA.isEnabled()) {
  70. return true;
  71. }
  72. return false;
  73. }
  74. /**
  75. * 搜索设备
  76. */
  77. public void searchDevices() {
  78. // 判断是否在搜索,如果在搜索,就取消搜索
  79. if (mBA.isDiscovering()) {
  80. mBA.cancelDiscovery();
  81. }
  82. // 开始搜索
  83. mBA.startDiscovery();
  84. Log.e(TAG, "正在搜索...");
  85. }
  86. /**
  87. * 获取已经配对的设备
  88. *
  89. * @return
  90. */
  91. public List<BluetoothDevice> getBondedDevices() {
  92. List<BluetoothDevice> devices = new ArrayList<>();
  93. Set<BluetoothDevice> pairedDevices = mBA.getBondedDevices();
  94. // 判断是否有配对过的设备
  95. if (pairedDevices.size() > 0) {
  96. for (BluetoothDevice device : pairedDevices) {
  97. devices.add(device);
  98. Log.e(TAG, "BondedDevice:" + device.getName());
  99. }
  100. }
  101. return devices;
  102. }
  103. /**
  104. * 与设备配对
  105. *
  106. * @param device
  107. */
  108. public void createBond(BluetoothDevice device) {
  109. try {
  110. Method createBondMethod = BluetoothDevice.class.getMethod("createBond");
  111. createBondMethod.invoke(device);
  112. } catch (Exception e) {
  113. e.printStackTrace();
  114. }
  115. }
  116. /**
  117. * 与设备解除配对
  118. *
  119. * @param device
  120. */
  121. public void removeBond(BluetoothDevice device) {
  122. try {
  123. Method removeBondMethod = device.getClass().getMethod("removeBond");
  124. removeBondMethod.invoke(device);
  125. } catch (Exception e) {
  126. e.printStackTrace();
  127. }
  128. }
  129. /**
  130. *
  131. * @param device
  132. * @param str 设置PIN码
  133. * @return
  134. */
  135. public boolean setPin(BluetoothDevice device, String str) {
  136. try {
  137. Method removeBondMethod = device.getClass().getDeclaredMethod("setPin",
  138. new Class[]{byte[].class});
  139. Boolean returnValue = (Boolean) removeBondMethod.invoke(device,
  140. new Object[]{str.getBytes()});
  141. Log.e("returnValue", "" + returnValue);
  142. } catch (SecurityException e) {
  143. e.printStackTrace();
  144. } catch (IllegalArgumentException e) {
  145. e.printStackTrace();
  146. } catch (Exception e) {
  147. e.printStackTrace();
  148. }
  149. return true;
  150. }
  151. /**
  152. * 取消用户输入
  153. */
  154. public boolean cancelPairingUserInput(BluetoothDevice device) {
  155. Boolean returnValue = false;
  156. try {
  157. Method createBondMethod = device.getClass().getMethod("cancelPairingUserInput");
  158. returnValue = (Boolean) createBondMethod.invoke(device);
  159. } catch (NoSuchMethodException e) {
  160. e.printStackTrace();
  161. } catch (InvocationTargetException e) {
  162. e.printStackTrace();
  163. } catch (IllegalAccessException e) {
  164. e.printStackTrace();
  165. }
  166. // cancelBondProcess()
  167. return returnValue.booleanValue();
  168. }
  169. /**
  170. * 取消配对
  171. */
  172. public boolean cancelBondProcess(BluetoothDevice device) {
  173. Boolean returnValue = null;
  174. try {
  175. Method createBondMethod = device.getClass().getMethod("cancelBondProcess");
  176. returnValue = (Boolean) createBondMethod.invoke(device);
  177. } catch (IllegalAccessException e) {
  178. e.printStackTrace();
  179. } catch (InvocationTargetException e) {
  180. e.printStackTrace();
  181. } catch (NoSuchMethodException e) {
  182. e.printStackTrace();
  183. }
  184. return returnValue.booleanValue();
  185. }
  186. /**
  187. * @param strAddr
  188. * @param strPsw
  189. * @return
  190. */
  191. public boolean pair(String strAddr, String strPsw) {
  192. boolean result = false;
  193. mBA.cancelDiscovery();
  194. if (!mBA.isEnabled()) {
  195. mBA.enable();
  196. }
  197. if (!BluetoothAdapter.checkBluetoothAddress(strAddr)) { // 检查蓝牙地址是否有效
  198. Log.d("mylog", "devAdd un effient!");
  199. }
  200. BluetoothDevice device = mBA.getRemoteDevice(strAddr);
  201. if (device.getBondState() != BluetoothDevice.BOND_BONDED) {
  202. Log.d("mylog", "NOT BOND_BONDED");
  203. try {
  204. setPin(device, strPsw); // 手机和蓝牙采集器配对
  205. createBond(device);
  206. result = true;
  207. } catch (Exception e) {
  208. Log.d("mylog", "setPiN failed!");
  209. e.printStackTrace();
  210. } //
  211. } else {
  212. Log.d("mylog", "HAS BOND_BONDED");
  213. try {
  214. createBond(device);
  215. setPin(device, strPsw); // 手机和蓝牙采集器配对
  216. createBond(device);
  217. result = true;
  218. } catch (Exception e) {
  219. Log.d("mylog", "setPiN failed!");
  220. e.printStackTrace();
  221. }
  222. }
  223. return result;
  224. }
  225. /**
  226. * 获取device.getClass()这个类中的所有Method
  227. *
  228. * @param clsShow
  229. */
  230. public void printAllInform(Class clsShow) {
  231. try {
  232. // 取得所有方法
  233. Method[] hideMethod = clsShow.getMethods();
  234. int i = 0;
  235. for (; i < hideMethod.length; i++) {
  236. Log.e("method name", hideMethod[i].getName() + ";and the i is:" + i);
  237. }
  238. // 取得所有常量
  239. Field[] allFields = clsShow.getFields();
  240. for (i = 0; i < allFields.length; i++) {
  241. Log.e("Field name", allFields[i].getName());
  242. }
  243. } catch (SecurityException e) {
  244. e.printStackTrace();
  245. } catch (IllegalArgumentException e) {
  246. e.printStackTrace();
  247. } catch (Exception e) {
  248. e.printStackTrace();
  249. }
  250. }
  251. /**
  252. * 打开蓝牙
  253. */
  254. public void openBlueTooth() {
  255. if (!mBA.isEnabled()) {
  256. // 弹出对话框提示用户是后打开
  257. /*Intent intent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
  258. startActivityForResult(intent, 1);*/
  259. // 不做提示,强行打开
  260. mBA.enable();
  261. showToast("打开蓝牙");
  262. } else {
  263. showToast("蓝牙已打开");
  264. }
  265. }
  266. /**
  267. * 关闭蓝牙
  268. */
  269. public void closeBlueTooth() {
  270. mBA.disable();
  271. showToast("关闭蓝牙");
  272. }
  273. /**
  274. * 弹出Toast窗口
  275. *
  276. * @param message
  277. */
  278. private void showToast(String message) {
  279. if (mContext != null) {
  280. Toast.makeText(mContext, message, Toast.LENGTH_LONG).show();
  281. } else {
  282. Log.e(TAG, "message:" + message);
  283. }
  284. }
  285. /**
  286. * 主动连接蓝牙
  287. *
  288. * @param device
  289. */
  290. public void connectDevice(BluetoothDevice device) {
  291. // 判断是否在搜索,如果在搜索,就取消搜索
  292. if (mBA.isDiscovering()) {
  293. mBA.cancelDiscovery();
  294. }
  295. try {
  296. // 获得远程设备
  297. if (mCurDevice == null || mCurDevice != mOldDevice) {
  298. mCurDevice = mBA.getRemoteDevice(device.getAddress());
  299. mOldDevice = mCurDevice;
  300. Log.e(TAG, "device:" + mCurDevice);
  301. mSocket = mCurDevice.createRfcommSocketToServiceRecord(MY_UUID);
  302. // 连接
  303. mSocket.connect();
  304. // 获得输出流
  305. os = mSocket.getOutputStream();
  306. }
  307. // 如果成功获得输出流
  308. } catch (IOException e) {
  309. e.printStackTrace();
  310. }
  311. }
  312. /**
  313. * 传输数据
  314. *
  315. * @param message
  316. */
  317. public void write(String message) {
  318. try {
  319. if (os != null) {
  320. os.write(message.getBytes("GBK"));
  321. }
  322. Log.e(TAG, "write:" + message);
  323. } catch (IOException e) {
  324. e.printStackTrace();
  325. }
  326. }
  327. // 服务端,需要监听客户端的线程类
  328. private Handler handler = new Handler() {
  329. public void handleMessage(Message msg) {
  330. showToast(String.valueOf(msg.obj));
  331. Log.e(TAG, "服务端:" + msg.obj);
  332. super.handleMessage(msg);
  333. }
  334. };
  335. // 线程服务类
  336. public class AcceptThread extends Thread {
  337. private BluetoothServerSocket serverSocket;
  338. private BluetoothSocket socket;
  339. // 输入 输出流
  340. private OutputStream os;
  341. private InputStream is;
  342. public AcceptThread() {
  343. try {
  344. serverSocket = mBA.listenUsingRfcommWithServiceRecord(NAME, MY_UUID);
  345. } catch (IOException e) {
  346. e.printStackTrace();
  347. }
  348. }
  349. @Override
  350. public void run() {
  351. // 截获客户端的蓝牙消息
  352. try {
  353. socket = serverSocket.accept(); // 如果阻塞了,就会一直停留在这里
  354. is = socket.getInputStream();
  355. os = socket.getOutputStream();
  356. while (true) {
  357. synchronized (this) {
  358. byte[] tt = new byte[is.available()];
  359. if (tt.length > 0) {
  360. is.read(tt, 0, tt.length);
  361. Message msg = new Message();
  362. msg.obj = new String(tt, "GBK");
  363. Log.e(TAG, "客户端:" + msg.obj);
  364. handler.sendMessage(msg);
  365. }
  366. }
  367. }
  368. } catch (Exception e) {
  369. e.printStackTrace();
  370. }
  371. }
  372. }
  373. }

参考:Android Bluetooth(蓝牙)实例 -Android教程

如何实现android蓝牙开发 自动配对连接,并不弹出提示框 - 天边的星星 - 博客园

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小蓝xlanll/article/detail/646881
推荐阅读
相关标签
  

闽ICP备14008679号