android - 使用 altBeacon 库的所有信标都不会在 Android 中显示

标签 android baseadapter ibeacon-android altbeacon android-ibeacon

我正在使用 AltBEacon Android library用于开发Android 设备的 iBeacon 应用。我正在扫描信标,但是,只找到了 四分之二的信标(有时是 1/4)。

我将mBeaconManager.setForegroundScanPeriod(5000l); 增加到 5 秒,但结果仍然相同。我不确定我用于绑定(bind)详细信息以查看的 CustomAdapter 是否错误,或者问题与移动设备有关(我正在使用 Galaxy Note II - Android 4.4.2 (KitKat))? 谁能找出我的错误?

另一个问题是从设备到信标的距离计算返回不正确(当我距离大约 0.5 米时,它返回 3-6 米)

我做错了什么?

注意:我已经检查过 Beacon 的 UUID、Major、Minors 是否有任何错误。我增加了扫描时间。这些都不起作用。

下面是开始监控和测距的Fragment:

public class FragmentScanBeacons extends Fragment implements BeaconConsumer{

    public static Region mRegion = new Region("Server", Identifier.parse("Here is my UUID"), null, null);
    private BeaconManager mBeaconManager;

    private BeaconBaseAdapter beaconBaseAdapter;

    private ListView beaconsListLv;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mBeaconManager = BeaconManager.getInstanceForApplication(getActivity());

        //BEACON PARSER
        mBeaconManager.getBeaconParsers().add(new BeaconParser().setBeaconLayout("m:2-3=0215,i:4-19,i:20-21,i:22-23,p:24-24"));
        //mBeaconManager.debug = true;
        beaconBaseAdapter = new BeaconBaseAdapter(getActivity());
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

        View view = inflater.inflate(R.layout.fragment_beacons, container, false);

        //UI
        beaconsListLv = (ListView) view.findViewById(R.id.beaconsListView);

        //Set Adapter
        beaconsListLv.setAdapter(beaconBaseAdapter);

        //Check for bluetooth and Scan for Beacon
        verifyBluetooth();

        //Start Monitoring and Ranging
        mBeaconManager.bind(this);

        return view;
    }

    @Override
    public void onResume() {
        super.onResume();
        if(mBeaconManager.isBound(this)){
            mBeaconManager.setBackgroundMode(false);
        }
    }

    @Override
    public void onPause() {
        super.onPause();
        if(mBeaconManager.isBound(this)){
            mBeaconManager.setBackgroundMode(true);
        }
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        mBeaconManager.unbind(this);
    }

    @Override
    public void onBeaconServiceConnect() {
        try {

            //Scan lasts for SCAN_PERIOD time
            mBeaconManager.setForegroundScanPeriod(1000l);
            //mBeaconManager.setBackgroundScanPeriod(0l);

            //Wait every SCAN_PERIOD_INBETWEEN time
            mBeaconManager.setForegroundBetweenScanPeriod(0l);

            //Update default time with the new one
            mBeaconManager.updateScanPeriods();
        }
        catch (RemoteException e){
            e.printStackTrace();
        }

        //Set Monitoring
        mBeaconManager.setMonitorNotifier(new MonitorNotifier() {
            @Override
            public void didEnterRegion(Region region) {
                Log.d("TEST", "ENTERED beacon region");

                //Start Raning as soon as you detect a beacon
                try {
                    mBeaconManager.startRangingBeaconsInRegion(mRegion);
                }
                catch (RemoteException e) {
                    e.printStackTrace();
                }
            }

            @Override
            public void didExitRegion(Region region) {
                Log.d("TEST", "EXITED beacon region");
            }

            @Override
            public void didDetermineStateForRegion(int state, Region region) {
                Log.d("TEST", "SWITCHED from seeing/not seeing beacon to state " + state);
            }
        });

        //Set Ranging
        mBeaconManager.setRangeNotifier(new RangeNotifier() {
            @Override
            public void didRangeBeaconsInRegion(final Collection<Beacon> beacons, Region region) {
                if (beacons != null && beacons.size() > 0) {
                    getActivity().runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            beaconBaseAdapter.initAll(beacons);
                        }
                    });
                }
            }
        });

        try {
            //Start Monitoring
            mBeaconManager.startMonitoringBeaconsInRegion(mRegion);
        }
        catch (RemoteException e) {
            e.printStackTrace();
        }

    }

    @Override
    public Context getApplicationContext() {
        return getActivity().getApplicationContext();
    }

    @Override
    public void unbindService(ServiceConnection serviceConnection) {
        getActivity().unbindService(serviceConnection);
    }

    @Override
    public boolean bindService(Intent intent, ServiceConnection serviceConnection, int mode) {
        return getActivity().bindService(intent, serviceConnection, mode);
    }
}

这是自定义适配器:

public class BeaconBaseAdapter extends BaseAdapter {

    private Context myContext;

    private LayoutInflater inflater;

    public static ArrayList<Beacon> beacons;

    public BeaconBaseAdapter(Context context) {
        this.myContext = context;
        this.inflater = LayoutInflater.from(context);
        this.beacons = new ArrayList<Beacon>();
    }

    public void initAll(Collection<Beacon> newBeacons) {
        this.beacons.clear();
        this.beacons.addAll(newBeacons);
        notifyDataSetChanged();
    }

    @Override
    public int getCount() {
        return beacons.size();
    }

    @Override
    public Beacon getItem(int position) {
        return beacons.get(position);
    }

    @Override
    public long getItemId(int position) {
        return position;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {

        if (convertView == null) {
            convertView = inflater.inflate(R.layout.beacon_list_row, null);
            convertView.setTag(new ViewHolder(convertView));
        }

        bind(getItem(position), position, convertView);
        return convertView;
    }


    private void bind(Beacon beacon, int position, View view) {
        ViewHolder holder = (ViewHolder) view.getTag();

        holder.manufacturerTextView.setText("Manufacturer: " + beacon.getManufacturer());
        holder.idOneTextView.setText("UUID: " + beacon.getId1());
        holder.idTwoTextView.setText("Major: " + beacon.getId2());
        holder.idThreeTextView.setText("Minor: " + beacon.getId3());
        holder.txPowerTextView.setText("TX-Power: " + beacon.getTxPower());
        holder.rssiTextView.setText("RSSI: " + beacon.getRssi());
        holder.distanceTextView.setText(String.format("DISTANCE: (%.2f m)", beacon.getDistance()));
        holder.nameTextView.setText("Bluetooth Name: " + beacon.getBluetoothName());
        holder.addressTextView.setText("Bluetooth Adrs: " + beacon.getBluetoothAddress());
    }

    static class ViewHolder {
        final TextView nameTextView;
        final TextView manufacturerTextView;
        final TextView idOneTextView;
        final TextView idTwoTextView;
        final TextView idThreeTextView;
        final TextView txPowerTextView;
        final TextView rssiTextView;
        final TextView distanceTextView;
        final TextView addressTextView;

        ViewHolder(View view) {
            nameTextView = (TextView) view.findViewWithTag("name");
            manufacturerTextView = (TextView) view.findViewWithTag("manufacturer");
            idOneTextView = (TextView) view.findViewWithTag("id_one");
            idTwoTextView = (TextView) view.findViewWithTag("id_two");
            idThreeTextView = (TextView) view.findViewWithTag("id_three");
            txPowerTextView = (TextView) view.findViewWithTag("tx_power");
            rssiTextView = (TextView) view.findViewWithTag("rssi");
            distanceTextView = (TextView) view.findViewWithTag("distance");
            addressTextView = (TextView) view.findViewWithTag("address");
        }
    }
}

最佳答案

一些想法:

  1. 尝试使用现成的信标检测程序,例如 Locate ,它在底层使用相同的 Android Beacon 库。如果程序可靠地检测到您的信标,则可能是您提到的自定义代码存在问题。

  2. 确保您的信标传输频率足够高。基线传输频率为 10 赫兹,但具有默认设置的库将可靠地拾取传输频率至少为 1 赫兹的信标。按照您的描述增加 mBeaconManager.setForegroundScanPeriod(); 应该会有所帮助,但是如果信标仅以 0.1 Hz 的频率传输,那么您仍然会遇到您描述的问题。

  3. 某些 Android 设备具有组合的 Wi-Fi/蓝牙芯片,可防止这两种 radio 同时可靠运行。尝试禁用 Wi-Fi,看看是否会得到相同的结果。

关于android - 使用 altBeacon 库的所有信标都不会在 Android 中显示,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27964761/

相关文章:

java - Android TimeZone.getAvailableIDs() 产生奇怪的字符串

android - 自定义 ListView 不显示数据

java - 将 ActionBar 添加到 Android API 级别 8 应用程序?

android - 没有测试结果

java - 无法将数据从 firebase 添加到字符串数组

java - 如何从 adapter.java 中的 ListView 设置 Onclick ImageView

android - onBeaconServiceConnect 未调用

Android BLE Beacon 扫描

java - 带有单选按钮的 Android Action Down

android - 不在后台监控时提示位置权限?