蓝牙是一种支持设备短距离传输数据的无线技术。android在2.0以后提供了这方面的支持。 
从查找蓝牙设备到能够相互通信要经过几个基本步骤(本机做为服务器): 
1.设置权限 
在manifest中配置

  1. <uses-permission android:name="android.permission.BLUETOOTH"/>
  2. <uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>

2.启动蓝牙 
首先要查看本机是否支持蓝牙,获取BluetoothAdapter蓝牙适配器对象

  1. BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
  2. if(mBluetoothAdapter == null){
  3. //表明此手机不支持蓝牙
  4. return;
  5. }
  6. if(!mBluetoothAdapter.isEnabled()){ //蓝牙未开启,则开启蓝牙
  7. Intent enableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
  8. startActivityForResult(enableIntent, REQUEST_ENABLE_BT);
  9. }
  10. //......
  11. public void onActivityResult(int requestCode, int resultCode, Intent data){
  12. if(requestCode == REQUEST_ENABLE_BT){
  13. if(requestCode == RESULT_OK){
  14. //蓝牙已经开启
  15. }
  16. }
  17. }

3。发现蓝牙设备 
这里可以细分为几个方面 
(1)使本机蓝牙处于可见(即处于易被搜索到状态),便于其他设备发现本机蓝牙

  1. //使本机蓝牙在300秒内可被搜索
  2. private void ensureDiscoverable() {
  3. if (mBluetoothAdapter.getScanMode() !=
  4. BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE) {
  5. Intent discoverableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
  6. discoverableIntent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 300);
  7. startActivity(discoverableIntent);
  8. }
  9. }

(2)查找已经配对的蓝牙设备,即以前已经配对过的设备

  1. Set<BluetoothDevice> pairedDevices = mBluetoothAdapter.getBondedDevices();
  2. if (pairedDevices.size() > 0) {
  3. findViewById(R.id.title_paired_devices).setVisibility(View.VISIBLE);
  4. for (BluetoothDevice device : pairedDevices) {
  5. //device.getName() +" "+ device.getAddress());
  6. }
  7. } else {
  8. mPairedDevicesArrayAdapter.add("没有找到已匹对的设备");
  9. }

(3)通过mBluetoothAdapter.startDiscovery();搜索设备,要获得此搜索的结果需要注册 
一个BroadcastReceiver来获取。先注册再获取信息,然后处理

  1. //注册,当一个设备被发现时调用onReceive
  2. IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
  3. this.registerReceiver(mReceiver, filter);
  4. //当搜索结束后调用onReceive
  5. filter = new IntentFilter(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
  6. this.registerReceiver(mReceiver, filter);
  7. //.......
  8. private BroadcastReceiver mReceiver = new BroadcastReceiver() {
  9. @Override
  10. public void onReceive(Context context, Intent intent) {
  11. String action = intent.getAction();
  12. if(BluetoothDevice.ACTION_FOUND.equals(action)){
  13. BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
  14. // 已经配对的则跳过
  15. if (device.getBondState() != BluetoothDevice.BOND_BONDED) {
  16. mNewDevicesArrayAdapter.add(device.getName() + "\n" + device.getAddress());  //保存设备地址与名字
  17. }
  18. }else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)) {  //搜索结束
  19. if (mNewDevicesArrayAdapter.getCount() == 0) {
  20. mNewDevicesArrayAdapter.add("没有搜索到设备");
  21. }
  22. }
  23. }
  24. };

4.建立连接 
查找到设备 后,则需要建立本机与其他设备之间的连接。 
一般用本机搜索其他蓝牙设备时,本机可以作为一个服务端,接收其他设备的连接。 
启动一个服务器端的线程,死循环等待客户端的连接,这与ServerSocket极为相似。 
这个线程在准备连接之前启动

  1. //UUID可以看做一个端口号
  2. private static final UUID MY_UUID =
  3. UUID.fromString("fa87c0d0-afac-11de-8a39-0800200c9a66");
  4. //像一个服务器一样时刻监听是否有连接建立
  5. private class AcceptThread extends Thread{
  6. private BluetoothServerSocket serverSocket;
  7. public AcceptThread(boolean secure){
  8. BluetoothServerSocket temp = null;
  9. try {
  10. temp = mBluetoothAdapter.listenUsingRfcommWithServiceRecord(
  11. NAME_INSECURE, MY_UUID);
  12. } catch (IOException e) {
  13. Log.e("app", "listen() failed", e);
  14. }
  15. serverSocket = temp;
  16. }
  17. public void run(){
  18. BluetoothSocket socket=null;
  19. while(true){
  20. try {
  21. socket = serverSocket.accept();
  22. } catch (IOException e) {
  23. Log.e("app", "accept() failed", e);
  24. break;
  25. }
  26. }
  27. if(socket!=null){
  28. //此时可以新建一个数据交换线程,把此socket传进去
  29. }
  30. }
  31. //取消监听
  32. public void cancel(){
  33. try {
  34. serverSocket.close();
  35. } catch (IOException e) {
  36. Log.e("app", "Socket Type" + socketType + "close() of server failed", e);
  37. }
  38. }
  39. }

搜索到设备后可以获取设备的地址,通过此地址获取一个BluetoothDeviced对象,可以看做客户端,通过此对象device.createRfcommSocketToServiceRecord(MY_UUID);同一个UUID可与服务器建立连接获取另一个socket对象,由此服务端与客户端各有一个socket对象,此时 
他们可以互相交换数据了。 
创立客户端socket可建立线程

  1. //另一个设备去连接本机,相当于客户端
  2. private class ConnectThread extends Thread{
  3. private BluetoothSocket socket;
  4. private BluetoothDevice device;
  5. public ConnectThread(BluetoothDevice device,boolean secure){
  6. this.device = device;
  7. BluetoothSocket tmp = null;
  8. try {
  9. tmp = device.createRfcommSocketToServiceRecord(MY_UUID_SECURE);
  10. } catch (IOException e) {
  11. Log.e("app", "create() failed", e);
  12. }
  13. }
  14. public void run(){
  15. mBluetoothAdapter.cancelDiscovery();    //取消设备查找
  16. try {
  17. socket.connect();
  18. } catch (IOException e) {
  19. try {
  20. socket.close();
  21. } catch (IOException e1) {
  22. Log.e("app", "unable to close() "+
  23. " socket during connection failure", e1);
  24. }
  25. connetionFailed();  //连接失败
  26. return;
  27. }
  28. //此时可以新建一个数据交换线程,把此socket传进去
  29. }
  30. public void cancel() {
  31. try {
  32. socket.close();
  33. } catch (IOException e) {
  34. Log.e("app", "close() of connect  socket failed", e);
  35. }
  36. }
  37. }

5.建立数据通信线程,进行读取数据

  1. //建立连接后,进行数据通信的线程
  2. private class ConnectedThread extends Thread{
  3. private BluetoothSocket socket;
  4. private InputStream inStream;
  5. private OutputStream outStream;
  6. public ConnectedThread(BluetoothSocket socket){
  7. this.socket = socket;
  8. try {
  9. //获得输入输出流
  10. inStream = socket.getInputStream();
  11. outStream = socket.getOutputStream();
  12. } catch (IOException e) {
  13. Log.e("app", "temp sockets not created", e);
  14. }
  15. }
  16. public void run(){
  17. byte[] buff = new byte[1024];
  18. int len=0;
  19. //读数据需不断监听,写不需要
  20. while(true){
  21. try {
  22. len = inStream.read(buff);
  23. //把读取到的数据发送给UI进行显示
  24. Message msg = handler.obtainMessage(BluetoothChat.MESSAGE_READ,
  25. len, -1, buff);
  26. msg.sendToTarget();
  27. } catch (IOException e) {
  28. Log.e("app", "disconnected", e);
  29. connectionLost();   //失去连接
  30. start();    //重新启动服务器
  31. break;
  32. }
  33. }
  34. }
  35. public void write(byte[] buffer) {
  36. try {
  37. outStream.write(buffer);
  38. // Share the sent message back to the UI Activity
  39. handler.obtainMessage(BluetoothChat.MESSAGE_WRITE, -1, -1, buffer)
  40. .sendToTarget();
  41. } catch (IOException e) {
  42. Log.e("app", "Exception during write", e);
  43. }
  44. }
  45. public void cancel() {
  46. try {
  47. socket.close();
  48. } catch (IOException e) {
  49. Log.e("app", "close() of connect socket failed", e);
  50. }
  51. }
  52. }

到这里,蓝牙通信的基本操作已经全部完成。

Android蓝牙操作笔记的更多相关文章

  1. Android蓝牙操作笔记(转)

    蓝牙是一种支持设备短距离传输数据的无线技术.android在2.0以后提供了这方面的支持. 从查找蓝牙设备到能够相互通信要经过几个基本步骤(本机做为服务器): 1.设置权限 在manifest中配置 ...

  2. Android蓝牙学习笔记

    一 Bluetooth基本概念 蓝牙是无线数据和语音传输的开放式标准,它将各种通信设备.计算机及其终端设备.各种数字数据系统.甚至家用电器采用无线方式联接起来.它的传输距离为10cm-10m,如果增加 ...

  3. Android 蓝牙操作详解

    1.启用蓝牙并使设备处于可发现状态    1.1 在使用BluetoothAdapter类的实例进操作之前,应启用isEnable()方法检查设备是否启用了蓝牙适配器.       // 使用意图提示 ...

  4. Android蓝牙操作

    1.添加蓝牙权限 <uses-permission android:name = "android.permission.BLUETOOTH"/> <!--启用应 ...

  5. Android:日常学习笔记(10)———使用LitePal操作数据库

    Android:日常学习笔记(10)———使用LitePal操作数据库 引入LitePal 什么是LitePal LitePal是一款开源的Android数据库框架,采用了对象关系映射(ORM)的模式 ...

  6. Android群英传笔记——第一章:Android体系与系统架构

    Android群英传笔记--第一章:Android体系与系统架构 图片都是摘抄自网络 今天确实挺忙的,不过把第一章的笔记做一下还是可以的,嘿嘿 1.1 Google的生态圈 还是得从Android的起 ...

  7. Android自动化学习笔记:编写MonkeyRunner脚本的几种方式

    ---------------------------------------------------------------------------------------------------- ...

  8. Android自动化学习笔记之MonkeyRunner:官方介绍和简单实例

    ---------------------------------------------------------------------------------------------------- ...

  9. android蓝牙打印机

    您还未登录!|登录|注册|帮助 首页 业界 移动 云计算 研发 论坛 博客 下载 更多 reality_jie的专栏 编程的过程是一种微妙的享受       目录视图 摘要视图 订阅 CSDN2013 ...

随机推荐

  1. The Impact of Garbage Collection on Application Performance

    As we’ve seen, the performance of the garbage collector is not determined by the number of dead obje ...

  2. bzoj3157 3516

    太神了,被数学题虐了 orz http://m.blog.csdn.net/blog/skywalkert/43970331 这道题关键是抓住m较小的特点,构造递推解决 ; ..,..] of lon ...

  3. UVa 1471 (LIS变形) Defense Lines

    题意: 给出一个序列,删掉它的一个连续子序列(该子序列可以为空),使得剩下的序列有最长的连续严格递增子序列. 分析: 这个可以看作lrj的<训练指南>P62中讲到的LIS的O(nlogn) ...

  4. 剑指Offer:二进制中1的个数

    题目:输入一个整数,输出该数二进制表示中1的个数. // 二进制中1的个数 #include <stdio.h> int wrong_count_1_bits(int n) // 错误解法 ...

  5. 如何编写Linux设备驱动程序

    一.Linux device driver 的概念 系统调用是操作系统内核和应用程序之间的接口,设备驱动程序是操作系统内核和机器硬件之间的接口.设备驱动程序为应用程序屏蔽了硬件的细节,这样在应用程序看 ...

  6. HDU4738 Caocao's Bridges 无向图的桥

    一眼题:找所有的桥,然后求最小权值 但是有很多坑点 1:如果本来不联通 输出0,(这个坑我知道) 2:但是还有一个坑,就是当整个连通,最小桥的权值是0时,也必须派一个人去,wa了无数遍(还是太年轻) ...

  7. FOJ 1608 Huge Mission 线段树

    每个节点维护一个最小值,更新发现如果大于最小值,直接向下更新.速度还可以.. #include<cstdio> #include<algorithm> #include< ...

  8. MSP430开学的序章

    吐槽一下最近在搞什么~~~,星期三在等板子来,自己的板子,激动呀!!F5系列的板子,激动呀!结果板子到星期五才拿到!开始的时候,感觉自己没多大问题,结果一上手就问题百出,因为没仔细看用户手册,导致光盘 ...

  9. 【暑假】[深入动态规划]UVa 1380 A Scheduling Problem

     UVa 1380 A Scheduling Problem 题目: http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=41557 ...

  10. 卡特兰数 BZOJ3907 网格 NOIP2003 栈

    卡特兰数 卡特兰数2 卡特兰数:主要是求排列组合问题 1:括号化矩阵连乘,问多少种方案 2:走方格,不能过对角线,问多少种方案 3:凸边型,划分成三角形 4:1到n的序列进栈,有多少种出栈方案 NOI ...