android中的ibeacon集合小于ios

问题描述

我在Android中使用beacon收集了ibeacon。但是在相同的环境和相同的时间。集合少于ios中的集合。在2分钟内。我可以收集1000多个ibeacon信息,但在oppo reno中只能收集400个,在华为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,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));
        } catch (remoteexception e) {
            e.printstacktrace();
        }
    }
    
}

代码初始化信标并收集信标。 didRangeBeaconsInRegion是信标回调。

解决方法

Android和iOS手机的接收器灵敏度都有很大差异,这极大地影响了检测到的设备的数量,尤其是在远距离时。 接收器灵敏度通常变化高达6dB(某些设备的接收器弱10dB),这会产生很大的影响。几年前,当我测试我的Huawei P9 Lite时,我感到震惊,发现它无法检测到10米外的信标。大多数手机可以检测40米或以上距离的信标。

记录这些变化在使用蓝牙信号电平进行大流行性接触追踪的时代赢得了新的兴趣。 Google has documented上的set of over 300 devices个变体。如您所见,与iPhone SE相比,华为设备的接收器通常要弱3dB。 (为公平起见,某些iOS设备(如iPhone 6)也是弱接收器。