cloudending
cloudending

Reputation: 105

ibeacon collections in android is less than ios

I collect ibeacon with beacon in android. But in same environment and same time. the collections is less than in ios. In 2 minutes. I can collect 1000+ ibeacon info but only 400 in oppo reno and 150 in huawei p40. Is there any diffrences between android and ios?

below is my code

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();
        }
    }
    
}

the code init beacon and collect beacon. didRangeBeaconsInRegion is the beacon callback.

Upvotes: 1

Views: 46

Answers (1)

davidgyoung
davidgyoung

Reputation: 64941

Both Android and iOS phones have large variations in receiver sensitivity which greatly affect the number of devices detected, especially at far distances. Receiver sensitivity typically varies by up to 6dB (some devices have receivers 10dB weaker) which has a huge effect. I was shocked when I tested my Huawei P9 Lite a few years ago, and found it unable to detect a beacon more than 10 meters away. Most phones can detect beacons 40 meters away or more.

Documenting these variations has earned new interest in the era of using bluetooth signal levels for pandemic contact tracing. Google has documented variations on a set of over 300 devices. As you can see, Huawei devices are typically 3dB weaker receivers compared with, say, the iPhone SE. (To be fair, some iOS devices like the iPhone 6 are also weak receivers).

Upvotes: 1

Related Questions