中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

如何在android中獲取ibeacon列表

發布時間:2021-01-28 11:11:31 來源:億速云 閱讀:194 作者:Leah 欄目:移動開發

如何在android中獲取ibeacon列表?相信很多沒有經驗的人對此束手無策,為此本文總結了問題出現的原因和解決方法,通過這篇文章希望你能解決這個問題。

android獲取ibeacon列表,供大家參考,具體內容如下

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

因為涉及掃碼的時間。特意寫一個service實現獲取列表 可以根據掃描時間掃描出ibeacon列表
包含 uuid,設備名稱,單位(米),電量等。
請根據自己的項目進行改造代碼。

核心代碼如下:

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
}

看完上述內容,你們掌握如何在android中獲取ibeacon列表的方法了嗎?如果還想學到更多技能或想了解更多相關內容,歡迎關注億速云行業資訊頻道,感謝各位的閱讀!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

建水县| 德安县| 色达县| 宜章县| 洛扎县| 宾川县| 长沙市| 日照市| 信丰县| 轮台县| 巢湖市| 台北市| 青龙| 滨海县| 正蓝旗| 北碚区| 广宗县| 怀宁县| 靖州| 宁安市| 武邑县| 东台市| 旬阳县| 甘孜| 合川市| 新晃| 思南县| 衡山县| 襄城县| 南平市| 筠连县| 三门峡市| 云浮市| 长沙市| 孙吴县| 垣曲县| 元谋县| 隆化县| 洞口县| 平顺县| 攀枝花市|