当前位置: 移动技术网 > IT编程>移动开发>Android > Android检测IBeacon热点的方法

Android检测IBeacon热点的方法

2019年08月01日  | 移动技术网IT编程  | 我要评论

nagi sho,叶亚馨,tokyo hot n0617

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);

代码改自链接地址

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

如对本文有疑问,请在下面进行留言讨论,广大热心网友会与你互动!! 点击进行留言回复

相关文章:

验证码:
移动技术网