首页 > 系统 > Android > 正文

android获取ibeacon列表的方法

2019-10-21 21:36:31
字体:
来源:转载
供稿:网友

android获取ibeacon列表,供大家参考,具体内容如下

最近公司有需要做ibeacon需求。

因为涉及扫码的时间。特意写一个service实现获取列表 可以根据扫描时间扫描出ibeacon列表 
包含 uuid,设备名称,单位(米),电量等。 
请根据自己的项目进行改造代码。

核心代码如下:

 

/** * * <ibeaon服务> * * @author fulushan * @date 创建时间:2018年4月5日 下午11:34:04 */public class IbeaconService extends Service {  private static final String TAG = IbeaconService.class.getName();  ArrayList<IBeaconClass.iBeacon> mLeDevices;  private boolean mScanning;  private final static int DATA_COMPLETE = 0;  private final static int DATA_FAIL = 1;  /**搜索BLE终端*/  private BluetoothAdapter mBluetoothAdapter;  // Stops scanning after 10 seconds.  private static long SCAN_PERIOD = 10000;  ResponseResult responseResult = new ResponseResult();  public class IbeaconBinder extends Binder{    public ResponseResult getResponseResult(){      return responseResult;    }  }  @Override  public IBinder onBind(Intent arg0) {    // TODO Auto-generated method stub    return null;  }  @Override  public void onStart(Intent intent, int startId) {    super.onStart(intent, startId);    if (intent != null) {      SCAN_PERIOD = intent.getIntExtra("time",10)*1000;      mLeDevices = new ArrayList<>();      //开启一个新的线程,如果使用Service,会导致ANR问题,Service本身也会阻塞      new Thread(new IbeaconRunnable()).start();    }  }  @Override  public void onDestroy() {    super.onDestroy();    stopUpdateService();    scanLeDevice(false);  }  class IbeaconRunnable implements Runnable {    Message message = handler.obtainMessage();    public void run() {      try {        //获取蓝牙数据        //开始判断        // Use this check to determine whether BLE is supported on the device. Then you can        // selectively disable BLE-related features.        if (!getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE)) {          message.what = DATA_FAIL;          responseResult.setStatus(BlueToothEnum.BLU_SERVICE_UNAVAI.getCode());          responseResult.setMsg(BlueToothEnum.BLU_SERVICE_UNAVAI.getMsg());          message.obj = responseResult;          handler.sendMessage(message);          return;        }        if(Build.VERSION.SDK_INT<JELLY_BEAN_MR2){          responseResult.setStatus(BlueToothEnum.BLU_SERVICE_UNAVAI.getCode());          responseResult.setMsg(BlueToothEnum.BLU_SERVICE_UNAVAI.getMsg());          message.obj = responseResult;          handler.sendMessage(message);          return;        }        // Initializes a Bluetooth adapter. For API level 18 and above, get a reference to        // BluetoothAdapter through BluetoothManager.        final BluetoothManager bluetoothManager =            (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {          mBluetoothAdapter = bluetoothManager.getAdapter();        }        if(!mBluetoothAdapter.isEnabled()){          responseResult.setStatus(BlueToothEnum.BLU_SERVICE_UNAVAI.getCode());          responseResult.setMsg(BlueToothEnum.BLU_SERVICE_UNAVAI.getMsg());          message.obj = responseResult;          handler.sendMessage(message);          return;        }        // Checks if Bluetooth is supported on the device.        if (mBluetoothAdapter == null) {          responseResult.setStatus(BlueToothEnum.BLU_SERVICE_UNAVAI.getCode());          responseResult.setMsg(BlueToothEnum.BLU_SERVICE_UNAVAI.getMsg());          message.obj = responseResult;          handler.sendMessage(message);          return;        }        //开启蓝牙        mBluetoothAdapter.enable();        scanLeDevice(true);      } catch (Exception ex) {        ex.printStackTrace();        message.what = DATA_FAIL;        //下载失败        handler.sendMessage(message);      }    }  }  @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR2)  private void scanLeDevice(final boolean enable) {    if (enable) {      // Stops scanning after a pre-defined scan period.      handler.postDelayed(new Runnable() {        @RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR2)        @Override        public void run() {          LogUtil.e(TAG,"scanLeDeviceStop");          mScanning = false;          mBluetoothAdapter.stopLeScan(mLeScanCallback);          Message message = handler.obtainMessage();          message.what = DATA_COMPLETE;          responseResult.setStatus(BlueToothEnum.SUCCESS.getCode());          responseResult.setMsg(BlueToothEnum.SUCCESS.getMsg());          responseResult.setData(mLeDevices);          message.obj = responseResult;          //数据数据完毕 更新数据列表          handler.sendMessage(message);        }      }, SCAN_PERIOD);      mScanning = true;      mBluetoothAdapter.startLeScan(mLeScanCallback);    } else {      mScanning = false;      mBluetoothAdapter.stopLeScan(mLeScanCallback);    }  }  public void addDevice(IBeaconClass.iBeacon device) {    if(device==null)      return;    for(int i=0;i<mLeDevices.size();i++){      String btAddress = mLeDevices.get(i).bluetoothAddress;      if(btAddress.equals(device.bluetoothAddress)){        mLeDevices.add(i+1, device);        mLeDevices.remove(i);        return;      }    }    mLeDevices.add(device);  }  // Device scan callback.  private BluetoothAdapter.LeScanCallback mLeScanCallback =      new BluetoothAdapter.LeScanCallback() {        @Override        public void onLeScan(final BluetoothDevice device, int rssi, byte[] scanRecord) {          final IBeaconClass.iBeacon ibeacon = IBeaconClass.fromScanData(device,rssi,scanRecord);           LogUtil.e(TAG,"onLeScan");           addDevice(ibeacon);           if(!mScanning){             LogUtil.e(TAG,"!mScanning");           }        }      };  private Handler handler = new Handler() {    @Override    public void handleMessage(Message msg) {      switch (msg.what) {        case DATA_COMPLETE:          EventBus.getDefault().post(new BlueTeethEvent(responseResult));          //停止服务          stopUpdateService();          break;        case DATA_FAIL:          responseResult.setStatus(BlueToothEnum.OTHER_ERROR.getCode());          responseResult.setMsg(BlueToothEnum.OTHER_ERROR.getMsg());          EventBus.getDefault().post(new BlueTeethEvent(responseResult));          stopUpdateService();          break;        default:          // stopService(updateIntent);          // stopService(updateIntent);          // stopService(new Intent(UpdateService.this,UpdateService.class));          break;      }    }  };  private void stopUpdateService() {    Intent updateIntent = new Intent(getBaseContext(),IbeaconService.class);    updateIntent.setAction(ServiceHelper.IBEACON_SERVICE);    updateIntent.setPackage(getBaseContext().getPackageName());//这里你需要设置你应用的包名    stopService(updateIntent);  }}

调用方式:

/*** 开启蓝牙服务UpdateService*/  public static void startIbeacon(Context context,int time) {    Intent intent = new Intent(context,IbeaconService.class);    intent.putExtra("time", time);//扫描ibeacon时间    intent.setAction(IBEACON_SERVICE);    intent.setPackage(context.getPackageName());//这里你需要设置你应用的包名    context.startService(intent);  }

其中IBeacon类

 

/** * 代码改自https://github.com/RadiusNetworks/android-ibeacon-service/blob/master/src/main/java/com/radiusnetworks/ibeacon/IBeacon.java * @author gvzhang * */public class IBeaconClass {  static public class iBeacon implements Serializable{    public String beaconName;    public int major;    public int minor;    public String uuid;    public String bluetoothAddress;    public int txPower;    public int rssi;    public double distance;  }  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.uuid = "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.uuid = "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;    iBeacon.distance = calculateAccuracy(iBeacon.txPower,iBeacon.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.uuid = sb.toString();    if (device != null) {      iBeacon.bluetoothAddress = device.getAddress();      iBeacon.beaconName = 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();   }  /**   * 估算用户设备到ibeacon的距离   *   * @param txPower   * @param rssi   * @return   */  public static double calculateAccuracy(int txPower, double rssi) {    if (rssi == 0) {      return -1.0; // if we cannot determine accuracy, return -1.    }    double ratio = rssi * 1.0 / txPower;    if (ratio < 1.0) {      return Math.pow(ratio, 10);    } else {      double accuracy = (0.89976) * Math.pow(ratio, 7.7095) + 0.111;      return accuracy;    }  }}

缺少的类请自己补全。请根据自己的项目进行改造代码。

{  "msg": "获取数据成功",  "data": [{      "uuid": "11111",      "beaconName": "设备A",      "distance": 0.56    },    {      "uuid": "2222",      "beaconName": "设备B",      "distance": 1.56    }  ],  "status": 100}

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


注:相关教程知识阅读请移步到Android开发频道。
发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表