每 0.5 秒保存一次可见 iBeacon 的 ID 和 RSSI

Saving ID and RSSI of visible iBeacons every 0.5seconds

美好的一天,

我想连续(每 0.5 秒)扫描 Android 中的 iBeacon,并将此时间戳的 ID 和 RSSI 保存在文件中。

您知道什么是实施扫描的最明智的方法吗?

谢谢

我将从 Android Beacon Library reference app here. Out of the box, this will allow you to scan every 1 second using the RangingActivity 开始。

然后您可以通过向该方法添加两行来修改该代码以每 0.5 秒扫描一次:

@Override
public void onBeaconServiceConnect() {
  ...

  beaconManager.setForegroundScanPeriod(500l);
  beaconManager.updateScanPeriods();

  ...
}

然后你可以通过修改这个方法将结果写入文件:

public void didRangeBeaconsInRegion(Collection<Beacon> beacons, Region region) {
  ...

           File file = new File(RangingActivity.this.getFilesDir(), "scanned-beacons.txt");
           FileWriter fw = null;
           try {
               fw = new FileWriter(file);
               for (Beacon beacon : beacons) {
                   StringBuilder line = new StringBuilder();
                   line.append(System.currentTimeMillis()); // timestamp
                   line.append(",");
                   line.append(beacon.toString());
                   line.append(",");
                   line.append(beacon.getRssi());
                   fw.write(line.toString());
               }
           } catch (IOException e) {
               e.printStackTrace();
           }
           finally {
               if (fw != null) {
                   try {
                       fw.close();
                   } catch (IOException e1) {
                       e1.printStackTrace();
                   }
               }
           }

  ...
}

对于使用 Android 信标库不支持的 SensorTag 或 BLE 设备的所有人。

我就是这样做的:

我在这里搜索名称为"SensorTag"的BLE设备。

public class MainActivity extends AppCompatActivity {
    private LeDeviceListAdapter mLeDeviceListAdapter;
    private BluetoothAdapter mBluetoothAdapter;
    private boolean mScanning;
    private Handler mHandler;

    private static final int REQUEST_ENABLE_BT = 1;
    // Stops scanning after 0.2 seconds.
    private static final long SCAN_PERIOD = 200;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mHandler = new Handler();



        // 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);
        mBluetoothAdapter = bluetoothManager.getAdapter();




    }


    private void scanLeDevice(final boolean enable) {
        if (enable) {
            // Stops scanning after a pre-defined scan period.
            mHandler.postDelayed(new Runnable() {
                @Override
                public void run() {
                    mScanning = false;
                    mBluetoothAdapter.stopLeScan(mLeScanCallback);
                    mLeDeviceListAdapter.printBeacons();

                }
            }, SCAN_PERIOD);

            mScanning = true;
            mBluetoothAdapter.startLeScan(mLeScanCallback);
        } else {
            mScanning = false;
            mBluetoothAdapter.stopLeScan(mLeScanCallback);
        }

    }

    // Adapter for holding devices found through scanning.
    private class LeDeviceListAdapter {
        private ArrayList<Beacon> mLeDevices;


        public LeDeviceListAdapter() {
            super();
            mLeDevices = new ArrayList<Beacon>();

        }

        public  void printBeacons() {
            for (int i = 0; i< mLeDevices.size(); i++) {
                System.out.println("Beacon " + mLeDevices.get(i).address + ", Signal: " + mLeDevices.get(i).rssi +", Timestamp: " + mLeDevices.get(i).timestamp);
            }
        }

        public boolean test( Beacon beacon) {
            for(int i = 0; i< mLeDevices.size(); i++){
                if (mLeDevices.get(i).address.equalsIgnoreCase(beacon.address)){
                    return true;
                }
            }
            return false;
        }




        public void addDevice(Beacon beacon) {
            if(!test(beacon)) {
                mLeDevices.add(beacon);
            }
            else{
                for(int i =0; i<mLeDevices.size(); i++){
                    if(mLeDevices.get(i).address.equalsIgnoreCase(beacon.address)){
                        mLeDevices.set(i, beacon);
                    }
                }
            }
        }

        public Beacon getDevice(int position) {
            return mLeDevices.get(position);
        }

        public void clear() {
            mLeDevices.clear();
        }


        public int getCount() {
            return mLeDevices.size();
        }


        public Object getItem(int i) {
            return mLeDevices.get(i);
        }


        public long getItemId(int i) {
            return i;
        }




    }

    // Device scan callback.
    private BluetoothAdapter.LeScanCallback mLeScanCallback =
            new BluetoothAdapter.LeScanCallback() {

                @Override
                public void onLeScan(final BluetoothDevice device, final int rssi, byte[] scanRecord) {
                    runOnUiThread(new Runnable() {
                        @Override
                        public void run() {

                            if(device.getName()!= null || device.getName() == "SensorTag"){
                                Beacon beacon = new Beacon(device.getAddress(), rssi, System.currentTimeMillis());
                                mLeDeviceListAdapter.addDevice(beacon);

                            }




                        }
                    });
                }
            };






    @Override
    protected void onPause() {
        super.onPause();
        scanLeDevice(false);
        mLeDeviceListAdapter.clear();
    }

    protected void onResume() {
        super.onResume();

        // Ensures Bluetooth is enabled on the device.  If Bluetooth is not currently enabled,
        // fire an intent to display a dialog asking the user to grant permission to enable it.
        if (!mBluetoothAdapter.isEnabled()) {
            if (!mBluetoothAdapter.isEnabled()) {
                Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
                startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);
            }
        }

        // Initializes list view adapter.
        mLeDeviceListAdapter = new LeDeviceListAdapter();
        //setListAdapter(mLeDeviceListAdapter);
        Timer timer = new Timer();
        TimerTask task = new TimerTask() {
            @Override
            public void run() {
                scanLeDevice(true);
                mLeDeviceListAdapter.clear();
            }
        };

        //start new Scan Period every second
        timer.scheduleAtFixedRate(task, 0 , 1000);

    }

}

}

这就是 class 信标,它代表一个具有地址、rssi 和信标最后一次出现的时间戳的信标。

 public class Beacon {
    public String address;
    public int rssi;
    public long timestamp;

    public Beacon(String address, int rssi, long timestamp){
        this.address = address;
        this.rssi = rssi;
        this.timestamp=timestamp;
    }


}

代码已简化。

问候 最大值