android 中的 ibeacon collections 小于 ios
ibeacon collections in android is less than ios
我在 android 中用 beacon 收集了 ibeacon。但是在相同的环境和相同的时间。 collections 小于 ios。 2 分钟后。我可以收集 1000 多个 ibeacon 信息,但在 oppo reno 中只有 400 个,在 huawei p40 中只有 150 个。
android和ios有区别吗?
下面是我的代码
package org.altbeacon.beaconreference;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import android.Manifest;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.pm.PackageManager;
import android.os.Build;
import android.os.Bundle;
import android.os.RemoteException;
import android.util.Log;
import android.widget.EditText;
import android.widget.TextView;
import org.altbeacon.beacon.AltBeacon;
import org.altbeacon.beacon.Beacon;
import org.altbeacon.beacon.BeaconConsumer;
import org.altbeacon.beacon.BeaconManager;
import org.altbeacon.beacon.BeaconParser;
import org.altbeacon.beacon.RangeNotifier;
import org.altbeacon.beacon.Region;
class BeaconLocationData {
public Map<String, Map<String, String>> locations =new HashMap<>();
public BeaconLocationData() {
initLocationData();
}
private void initLocationData() {
Map<String, String> minorLocations = new HashMap<>();
minorLocations.put("16101", "a-6");
minorLocations.put("10101", "A-1");
locations.put("10001", minorLocations);
}
public String getLocationMsg(String major, String minor) {
String location;
// location = locations.get(major).get(minor);
Map<String,String> minorMap = locations.get(major);
if (minorMap == null || minorMap.size() == 0) {
return "no location";
}
location = minorMap.get(minor);
if (location == null || location.equals("")) {
return "no location";
}
return location;
}
}
public class RangingActivity extends Activity implements BeaconConsumer {
protected static final String TAG = "RangingActivity";
private static final long DEFAULT_FOREGROUND_SCAN_PERIOD = 1000L;
private static final long DEFAULT_FOREGROUND_BETWEEN_SCAN_PERIOD = 0;
private static final int PERMISSION_REQUEST_COARSE_LOCATION = 1;
private BeaconManager beaconManager = BeaconManager.getInstanceForApplication(this);
public static final String IBEACON_FORMAT = "m:2-3=0215,i:4-19,i:20-21,i:22-23,p:24-24";
public static final String FILTER_UUID = "fda50693-a4e2-4fb1-afcf-c6eb07647825";
public BeaconLocationData beaconLocationData;
private TextView textView;
private void initBeacon() {
beaconManager = BeaconManager.getInstanceForApplication(this);
beaconManager.setForegroundBetweenScanPeriod(DEFAULT_FOREGROUND_BETWEEN_SCAN_PERIOD);
beaconManager.setForegroundScanPeriod(DEFAULT_FOREGROUND_SCAN_PERIOD);
beaconManager.getBeaconParsers().add(new BeaconParser().setBeaconLayout(IBEACON_FORMAT));
beaconManager.bind(this);
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_ranging);
requestLocationPermissions();
initBeacon();
initData();
textView = findViewById(R.id.textView);
}
@Override
protected void onDestroy() {
super.onDestroy();
}
@Override
protected void onPause() {
super.onPause();
beaconManager.unbind(this);
}
@Override
protected void onResume() {
super.onResume();
// beaconManager.getBeaconParsers().add(new BeaconParser().
// setBeaconLayout("m:2-3=beac,i:4-19,i:20-21,i:22-23,p:24-24,d:25-25"));
// beaconManager.bind(this);
}
private void requestLocationPermissions() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
// Android M Permission check
if (this.checkSelfPermission(Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
final AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("This app needs location access");
builder.setMessage("Please grant location access so this app can detect beacons.");
builder.setPositiveButton(android.R.string.ok, null);
builder.setOnDismissListener(new DialogInterface.OnDismissListener() {
@Override
public void onDismiss(DialogInterface dialog) {
requestPermissions(new String[]{Manifest.permission.ACCESS_COARSE_LOCATION}, PERMISSION_REQUEST_COARSE_LOCATION);
}
});
builder.show();
}
}
}
private int count = 0;
@Override
public void onRequestPermissionsResult(int requestCode,
String permissions[], int[] grantResults) {
switch (requestCode) {
case PERMISSION_REQUEST_COARSE_LOCATION: {
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
Log.d(TAG, "coarse location permission granted");
} else {
final AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("Functionality limited");
builder.setMessage("Since location access has not been granted, this app will not be able to discover beacons when in the background.");
builder.setPositiveButton(android.R.string.ok, null);
builder.setOnDismissListener(new DialogInterface.OnDismissListener() {
@Override
public void onDismiss(DialogInterface dialog) {
}
});
builder.show();
}
return;
}
}
}
private void initData() {
beaconLocationData = new BeaconLocationData();
}
@Override
public void onBeaconServiceConnect() {
Log.i(TAG, "onBeaconServiceConnect: ");
beaconManager.addRangeNotifier(new RangeNotifier() {
@Override
public void didRangeBeaconsInRegion(Collection<Beacon> collection, Region region) {
Log.i(TAG, "didRangeBeaconsInRegion: "+collection.size());
// updateTextViewMsg("进入didRangeBeaconsInRegion方法");
if (collection.size() > 0) {
List<Beacon> beacons = new ArrayList<>();
for (Beacon beacon : collection) {
if (beacon.getId1().toString().equalsIgnoreCase(FILTER_UUID)){
Log.i(TAG, "FIND UUID: " + FILTER_UUID);
Log.i(TAG, "MAJOR: " + beacon.getId2().toString());
Log.i(TAG, "MINOR: " + beacon.getId3().toString());
count++;
runOnUiThread(new Runnable() {
@Override
public void run() {
textView.setText("beacon:"+count);
}
});
beacons.add(beacon);
}
}
if (beacons.size() > 0) {
Collections.sort(beacons, new Comparator<Beacon>() {
public int compare(Beacon arg0, Beacon arg1) {
return arg1.getRssi()-arg0.getRssi();
}
});
Beacon nearBeacon = beacons.get(0);
String major = nearBeacon.getId2().toString();
String minor = nearBeacon.getId3().toString();
String location = beaconLocationData.getLocationMsg(major, minor);
Log.i(TAG, "didRangeBeaconsInRegion: "+ beacons.toString() );
}
}
}
});
try {
beaconManager.startRangingBeaconsInRegion(new Region(FILTER_UUID, null, null, null));
} catch (RemoteException e) {
e.printStackTrace();
}
}
}
代码初始化信标和收集信标。 didRangeBeaconsInRegion
是信标回调。
Android 和 iOS 手机的接收器灵敏度差异很大,这会极大地影响检测到的设备数量,尤其是在远距离时。
接收器灵敏度通常变化高达 6dB(某些设备的接收器弱 10dB),这会产生巨大影响。几年前,当我测试我的华为 P9 Lite 时,我感到震惊,发现它无法检测到 10 米以外的信标。大多数手机可以检测到 40 米或更远的信标。
在使用蓝牙信号水平进行大流行接触者追踪的时代,记录这些变化引起了新的兴趣。 Google has documented variations on a set of over 300 devices。如您所见,与 iPhone SE 相比,华为设备的接收器通常弱 3dB。 (公平地说,一些 iOS 设备如 iPhone 6 也是弱接收器)。
我在 android 中用 beacon 收集了 ibeacon。但是在相同的环境和相同的时间。 collections 小于 ios。 2 分钟后。我可以收集 1000 多个 ibeacon 信息,但在 oppo reno 中只有 400 个,在 huawei p40 中只有 150 个。 android和ios有区别吗?
下面是我的代码
package org.altbeacon.beaconreference;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import android.Manifest;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.pm.PackageManager;
import android.os.Build;
import android.os.Bundle;
import android.os.RemoteException;
import android.util.Log;
import android.widget.EditText;
import android.widget.TextView;
import org.altbeacon.beacon.AltBeacon;
import org.altbeacon.beacon.Beacon;
import org.altbeacon.beacon.BeaconConsumer;
import org.altbeacon.beacon.BeaconManager;
import org.altbeacon.beacon.BeaconParser;
import org.altbeacon.beacon.RangeNotifier;
import org.altbeacon.beacon.Region;
class BeaconLocationData {
public Map<String, Map<String, String>> locations =new HashMap<>();
public BeaconLocationData() {
initLocationData();
}
private void initLocationData() {
Map<String, String> minorLocations = new HashMap<>();
minorLocations.put("16101", "a-6");
minorLocations.put("10101", "A-1");
locations.put("10001", minorLocations);
}
public String getLocationMsg(String major, String minor) {
String location;
// location = locations.get(major).get(minor);
Map<String,String> minorMap = locations.get(major);
if (minorMap == null || minorMap.size() == 0) {
return "no location";
}
location = minorMap.get(minor);
if (location == null || location.equals("")) {
return "no location";
}
return location;
}
}
public class RangingActivity extends Activity implements BeaconConsumer {
protected static final String TAG = "RangingActivity";
private static final long DEFAULT_FOREGROUND_SCAN_PERIOD = 1000L;
private static final long DEFAULT_FOREGROUND_BETWEEN_SCAN_PERIOD = 0;
private static final int PERMISSION_REQUEST_COARSE_LOCATION = 1;
private BeaconManager beaconManager = BeaconManager.getInstanceForApplication(this);
public static final String IBEACON_FORMAT = "m:2-3=0215,i:4-19,i:20-21,i:22-23,p:24-24";
public static final String FILTER_UUID = "fda50693-a4e2-4fb1-afcf-c6eb07647825";
public BeaconLocationData beaconLocationData;
private TextView textView;
private void initBeacon() {
beaconManager = BeaconManager.getInstanceForApplication(this);
beaconManager.setForegroundBetweenScanPeriod(DEFAULT_FOREGROUND_BETWEEN_SCAN_PERIOD);
beaconManager.setForegroundScanPeriod(DEFAULT_FOREGROUND_SCAN_PERIOD);
beaconManager.getBeaconParsers().add(new BeaconParser().setBeaconLayout(IBEACON_FORMAT));
beaconManager.bind(this);
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_ranging);
requestLocationPermissions();
initBeacon();
initData();
textView = findViewById(R.id.textView);
}
@Override
protected void onDestroy() {
super.onDestroy();
}
@Override
protected void onPause() {
super.onPause();
beaconManager.unbind(this);
}
@Override
protected void onResume() {
super.onResume();
// beaconManager.getBeaconParsers().add(new BeaconParser().
// setBeaconLayout("m:2-3=beac,i:4-19,i:20-21,i:22-23,p:24-24,d:25-25"));
// beaconManager.bind(this);
}
private void requestLocationPermissions() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
// Android M Permission check
if (this.checkSelfPermission(Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
final AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("This app needs location access");
builder.setMessage("Please grant location access so this app can detect beacons.");
builder.setPositiveButton(android.R.string.ok, null);
builder.setOnDismissListener(new DialogInterface.OnDismissListener() {
@Override
public void onDismiss(DialogInterface dialog) {
requestPermissions(new String[]{Manifest.permission.ACCESS_COARSE_LOCATION}, PERMISSION_REQUEST_COARSE_LOCATION);
}
});
builder.show();
}
}
}
private int count = 0;
@Override
public void onRequestPermissionsResult(int requestCode,
String permissions[], int[] grantResults) {
switch (requestCode) {
case PERMISSION_REQUEST_COARSE_LOCATION: {
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
Log.d(TAG, "coarse location permission granted");
} else {
final AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("Functionality limited");
builder.setMessage("Since location access has not been granted, this app will not be able to discover beacons when in the background.");
builder.setPositiveButton(android.R.string.ok, null);
builder.setOnDismissListener(new DialogInterface.OnDismissListener() {
@Override
public void onDismiss(DialogInterface dialog) {
}
});
builder.show();
}
return;
}
}
}
private void initData() {
beaconLocationData = new BeaconLocationData();
}
@Override
public void onBeaconServiceConnect() {
Log.i(TAG, "onBeaconServiceConnect: ");
beaconManager.addRangeNotifier(new RangeNotifier() {
@Override
public void didRangeBeaconsInRegion(Collection<Beacon> collection, Region region) {
Log.i(TAG, "didRangeBeaconsInRegion: "+collection.size());
// updateTextViewMsg("进入didRangeBeaconsInRegion方法");
if (collection.size() > 0) {
List<Beacon> beacons = new ArrayList<>();
for (Beacon beacon : collection) {
if (beacon.getId1().toString().equalsIgnoreCase(FILTER_UUID)){
Log.i(TAG, "FIND UUID: " + FILTER_UUID);
Log.i(TAG, "MAJOR: " + beacon.getId2().toString());
Log.i(TAG, "MINOR: " + beacon.getId3().toString());
count++;
runOnUiThread(new Runnable() {
@Override
public void run() {
textView.setText("beacon:"+count);
}
});
beacons.add(beacon);
}
}
if (beacons.size() > 0) {
Collections.sort(beacons, new Comparator<Beacon>() {
public int compare(Beacon arg0, Beacon arg1) {
return arg1.getRssi()-arg0.getRssi();
}
});
Beacon nearBeacon = beacons.get(0);
String major = nearBeacon.getId2().toString();
String minor = nearBeacon.getId3().toString();
String location = beaconLocationData.getLocationMsg(major, minor);
Log.i(TAG, "didRangeBeaconsInRegion: "+ beacons.toString() );
}
}
}
});
try {
beaconManager.startRangingBeaconsInRegion(new Region(FILTER_UUID, null, null, null));
} catch (RemoteException e) {
e.printStackTrace();
}
}
}
代码初始化信标和收集信标。 didRangeBeaconsInRegion
是信标回调。
Android 和 iOS 手机的接收器灵敏度差异很大,这会极大地影响检测到的设备数量,尤其是在远距离时。 接收器灵敏度通常变化高达 6dB(某些设备的接收器弱 10dB),这会产生巨大影响。几年前,当我测试我的华为 P9 Lite 时,我感到震惊,发现它无法检测到 10 米以外的信标。大多数手机可以检测到 40 米或更远的信标。
在使用蓝牙信号水平进行大流行接触者追踪的时代,记录这些变化引起了新的兴趣。 Google has documented variations on a set of over 300 devices。如您所见,与 iPhone SE 相比,华为设备的接收器通常弱 3dB。 (公平地说,一些 iOS 设备如 iPhone 6 也是弱接收器)。