每 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;
}
}
代码已简化。
问候
最大值
美好的一天,
我想连续(每 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;
}
}
代码已简化。
问候 最大值