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

    

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

BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();  if(mBluetoothAdapter == null){          //表明此手机不支持蓝牙  sijienet.com        return;  }  if(!mBluetoothAdapter.isEnabled()){ //蓝牙未开启,则开启蓝牙              Intent enableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);              startActivityForResult(enableIntent, REQUEST_ENABLE_BT);  }  //......  public void onActivityResult(int requestCode, int resultCode, Intent data){         if(requestCode == REQUEST_ENABLE_BT){                if(requestCode == RESULT_OK){                     //蓝牙已经开启                 }         }  }  

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

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

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

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

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

//注册,当一个设备被发现时调用onReceive  IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);          this.registerReceiver(mReceiver, filter);    //当搜索结束后调用onReceive  filter = new IntentFilter(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);          this.registerReceiver(mReceiver, filter);  //.......  private BroadcastReceiver mReceiver = new BroadcastReceiver() {          @Override          public void onReceive(Context context, Intent intent) {              String action = intent.getAction();              if(BluetoothDevice.ACTION_FOUND.equals(action)){                   BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);                    // 已经配对的则跳过                   if (device.getBondState() != BluetoothDevice.BOND_BONDED) {                        mNewDevicesArrayAdapter.add(device.getName() + "\n" + device.getAddress());  //保存设备地址与名字                   }              }else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)) {  //搜索结束                  if (mNewDevicesArrayAdapter.getCount() == 0) {                      mNewDevicesArrayAdapter.add("没有搜索到设备");                  }              }            }  };  

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

//UUID可以看做一个端口号  private static final UUID MY_UUID =          UUID.fromString("fa87c0d0-afac-11de-8a39-0800200c9a66");     //像一个服务器一样时刻监听是否有连接建立      private class AcceptThread extends Thread{          private BluetoothServerSocket serverSocket;                    public AcceptThread(boolean secure){              BluetoothServerSocket temp = null;              try {                  temp = mBluetoothAdapter.listenUsingRfcommWithServiceRecord(                              NAME_INSECURE, MY_UUID);              } catch (IOException e) {                    Log.e("app", "listen() failed", e);              }              serverSocket = temp;          }                    public void run(){              BluetoothSocket socket=null;              while(true){                  try {                      socket = serverSocket.accept();                  } catch (IOException e) {                       Log.e("app", "accept() failed", e);                       break;                  }              }              if(socket!=null){                  //此时可以新建一个数据交换线程,把此socket传进去              }          }                    //取消监听          public void cancel(){                 try {                  serverSocket.close();              } catch (IOException e) {                  Log.e("app", "Socket Type" + socketType + "close() of server failed", e);              }          }    }  

搜索到设备后可以获取设备的地址,通过此地址获取一个BluetoothDeviced对象,可以看做客户端,通过此对象device.createRfcommSocketToServiceRecord(MY_UUID);同一个UUID可与服务

器建立连接获取另一个socket对象,由此服务端与客户端各有一个socket对象,此时
他们可以互相交换数据了。
创立客户端socket可建立线程

//另一个设备去连接本机,相当于客户端   private class ConnectThread extends Thread{      private BluetoothSocket socket;      private BluetoothDevice device;      public ConnectThread(BluetoothDevice device,boolean secure){          this.device = device;          BluetoothSocket tmp = null;          try {      tmp = device.createRfcommSocketToServiceRecord(MY_UUID_SECURE);  } catch (IOException e) {       Log.e("app", "create() failed", e);  }      }            public void run(){          mBluetoothAdapter.cancelDiscovery();    //取消设备查找          try {      socket.connect();  } catch (IOException e) {      try {          socket.close();      } catch (IOException e1) {           Log.e("app", "unable to close() "+                            " socket during connection failure", e1);      }      connetionFailed();  //连接失败      return;  }        //此时可以新建一个数据交换线程,把此socket传进去      }              public void cancel() {             try {                 socket.close();             } catch (IOException e) {                 Log.e("app", "close() of connect  socket failed", e);             }         }   }  

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

//建立连接后,进行数据通信的线程      private class ConnectedThread extends Thread{          private BluetoothSocket socket;          private InputStream inStream;          private OutputStream outStream;                    public ConnectedThread(BluetoothSocket socket){                            this.socket = socket;              try {                  //获得输入输出流                  inStream = socket.getInputStream();                  outStream = socket.getOutputStream();              } catch (IOException e) {                  Log.e("app", "temp sockets not created", e);              }          }                    public void run(){              byte[] buff = new byte[1024];              int len=0;              //读数据需不断监听,写不需要              while(true){                  try {                      len = inStream.read(buff);                      //把读取到的数据发送给UI进行显示                      Message msg = handler.obtainMessage(BluetoothChat.MESSAGE_READ,                              len, -1, buff);                      msg.sendToTarget();                  } catch (IOException e) {                      Log.e("app", "disconnected", e);                      connectionLost();   //失去连接                      start();    //重新启动服务器                      break;                  }              }          }                              public void write(byte[] buffer) {              try {                  outStream.write(buffer);                    // Share the sent message back to the UI Activity                  handler.obtainMessage(BluetoothChat.MESSAGE_WRITE, -1, -1, buffer)                          .sendToTarget();              } catch (IOException e) {                  Log.e("app", "Exception during write", e);              }          }            public void cancel() {              try {                  socket.close();              } catch (IOException e) {                  Log.e("app", "close() of connect socket failed", e);              }          }      }  

蓝牙基本操作完成,要对socket有一定认识的童鞋才能够熟练操作。

更多相关文章

  1. SpringBoot 2.0 中 HikariCP 数据库连接池原理解析
  2. Android(安卓)开发学习进程0.15 adb cardview framelayout 控件
  3. Xamarin Android基本功能实现
  4. AndroidStudio 优秀的第三方数据库 GreenDao
  5. Android(安卓)6.0 变更
  6. 编译可在Nexus5上运行的CyanogenMod13.0 ROM(基于Android6.0)
  7. Android的连接服务器
  8. android通过蓝牙实现两台手机传输数据
  9. Android中ConnectivityManager监听网络状态

随机推荐

  1. Android(安卓)布局管理器
  2. 安卓的历史
  3. Android(安卓)studio百度地图SDK开发 202
  4. Android创建和使用数据库详…
  5. 社区讨论:Android的架构设计
  6. Android(安卓)UI设计的基本元素有哪些
  7. Android中 android:layout_weight 属性
  8. Android中显示,隐藏Status Bar和Navigatio
  9. android SDK应用
  10. Android(安卓)UI开发第十二篇——动画效