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 也是弱接收器)。