欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

Android检测IBeacon热点的方法

程序员文章站 2022-06-04 12:11:48
ibeacon是ble的一种,搜索ibeacon基站关键在于设备扫描到的scanrecord数组,识别是否有下面加粗斜体的02 15这两个数字。如果有,搜索到的蓝牙设备就是...

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 uuid
// 00 00 # major
// 00 00 # minor
// c5 # the 2's complement of the calibrated tx power

下面分步骤来实现检测ibeacon热点。

一、获得手机蓝牙控制权限

在manifest 文件中写上:

<uses-permission android:name="android.permission.bluetooth"/>
<uses-permission android:name="android.permission.bluetooth_admin"/>

二、检测手机是否支持蓝牙,并获取mbluetoothadapter 对象

if (!getpackagemanager().hassystemfeature(
        packagemanager.feature_bluetooth_le))
    {
      toast.maketext(this, r.string.ble_not_supported, toast.length_short)
          .show();
      finish();
    }
    final bluetoothmanager bluetoothmanager = (bluetoothmanager) getsystemservice(context.bluetooth_service);
    mbluetoothadapter = bluetoothmanager.getadapter();

    if (mbluetoothadapter == null)
    {
      toast.maketext(this, r.string.error_bluetooth_not_supported,
          toast.length_short).show();
      finish();
      return;
    }

三、实现lescancallback回调接口

设备每次检测到一个蓝牙设备,就会回调这个接口中的onlescan()方法,并且传入扫描到的device,rssi,scanrecord等参数。

private bluetoothadapter.lescancallback mlescancallback = new bluetoothadapter.lescancallback()
  {
    @override
    public void onlescan(final bluetoothdevice device, int rssi,
        byte[] scanrecord)
    {
      //在这里处理扫描到的参数
      //判断是不是ibeacon设备,做相应的处理。
    }
  };

四、处理扫描到的参数的方法

public class ibeaconclass
{

  static public class ibeacon
  {
    public string name;
    public int major;
    public int minor;
    public string proximityuuid;
    public string bluetoothaddress;
    public int txpower;
    public int rssi;
  }


  /**
   * 将扫描到的信息传入这个方法
   * 该方法会判断扫描到的设备是不是ibeacon
   * 如果是就返回一个ibeacon对象
   * 如果不是就返回null
   * @param device
   * @param rssi
   * @param scandata
   * @return
   */
  public static ibeacon fromscandata(bluetoothdevice device, int rssi,
      byte[] scandata)
  {

    int startbyte = 2;
    boolean patternfound = false;
    while (startbyte <= 5)
    {
      if (((int) scandata[startbyte + 2] & 0xff) == 0x02
          && ((int) scandata[startbyte + 3] & 0xff) == 0x15)
      {
        // yes! this is an ibeacon
        patternfound = true;
        break;
      } else if (((int) scandata[startbyte] & 0xff) == 0x2d
          && ((int) scandata[startbyte + 1] & 0xff) == 0x24
          && ((int) scandata[startbyte + 2] & 0xff) == 0xbf
          && ((int) scandata[startbyte + 3] & 0xff) == 0x16)
      {
        ibeacon ibeacon = new ibeacon();
        ibeacon.major = 0;
        ibeacon.minor = 0;
        ibeacon.proximityuuid = "00000000-0000-0000-0000-000000000000";
        ibeacon.txpower = -55;
        return ibeacon;
      } else if (((int) scandata[startbyte] & 0xff) == 0xad
          && ((int) scandata[startbyte + 1] & 0xff) == 0x77
          && ((int) scandata[startbyte + 2] & 0xff) == 0x00
          && ((int) scandata[startbyte + 3] & 0xff) == 0xc6)
      {

        ibeacon ibeacon = new ibeacon();
        ibeacon.major = 0;
        ibeacon.minor = 0;
        ibeacon.proximityuuid = "00000000-0000-0000-0000-000000000000";
        ibeacon.txpower = -55;
        return ibeacon;
      }
      startbyte++;
    }

    if (patternfound == false)
    {
      // this is not an ibeacon
      return null;
    }

    ibeacon ibeacon = new ibeacon();

    ibeacon.major = (scandata[startbyte + 20] & 0xff) * 0x100
        + (scandata[startbyte + 21] & 0xff);
    ibeacon.minor = (scandata[startbyte + 22] & 0xff) * 0x100
        + (scandata[startbyte + 23] & 0xff);
    ibeacon.txpower = (int) scandata[startbyte + 24]; // this one is signed
    ibeacon.rssi = rssi;

    // 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
    // uuid
    // 00 00 # major
    // 00 00 # minor
    // c5 # the 2's complement of the calibrated tx power

    // estimote:
    // 02 01 1a 11 07 2d 24 bf 16
    // 394b31ba3f486415ab376e5c0f09457374696d6f7465426561636f6e00000000000000000000000000000000000000000000000000

    byte[] proximityuuidbytes = new byte[16];
    system.arraycopy(scandata, startbyte + 4, proximityuuidbytes, 0, 16);
    string hexstring = bytestohexstring(proximityuuidbytes);
    stringbuilder sb = new stringbuilder();
    sb.append(hexstring.substring(0, 8));
    sb.append("-");
    sb.append(hexstring.substring(8, 12));
    sb.append("-");
    sb.append(hexstring.substring(12, 16));
    sb.append("-");
    sb.append(hexstring.substring(16, 20));
    sb.append("-");
    sb.append(hexstring.substring(20, 32));
    ibeacon.proximityuuid = sb.tostring();

    if (device != null)
    {
      ibeacon.bluetoothaddress = device.getaddress();
      ibeacon.name = device.getname();
    }

    return ibeacon;
  }

  private static string bytestohexstring(byte[] src)
  {
    stringbuilder stringbuilder = new stringbuilder("");
    if (src == null || src.length <= 0)
    {
      return null;
    }
    for (int i = 0; i < src.length; i++)
    {
      int v = src[i] & 0xff;
      string hv = integer.tohexstring(v);
      if (hv.length() < 2)
      {
        stringbuilder.append(0);
      }
      stringbuilder.append(hv);
    }
    return stringbuilder.tostring();
  }
}

五、开启蓝牙

mbluetoothadapter.enable();

六、开始扫描

mbluetoothadapter.startlescan(mlescancallback);

代码改自链接地址

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。