Android - Can find estimotes but cannot access their data

Hi guys!
i've just started coding for android and estimote. Everything works great
up til the moment in which i want to work with individual estimotes. I can
get all the beacons in range (that wasn't to hard with ListBeaconsActivity
as example). My problem starts when im trying to add dynamically elements
to the app depending on the number of estimotes present.

What i used was the following:

adapter = new LeDeviceListAdapter(getActivity());
beaconManager = new BeaconManager(getActivity());

beaconManager.setRangingListener(new BeaconManager.RangingListener() {
@Override
public void onBeaconsDiscovered(Region region, List<Beacon>
beacons) {
Log.d(TAG, "Ranged beacons FB_onCreate: " + beacons);
adapter.replaceWith(beacons);
Log.d(TAG, "adapters found: " + adapter.getCount());
}
});

This was called in onCreateView and adapter is declared as a class
variable. Sadly when i call later on the adapter.getCount() its always 0. I
also tried putting it in the runOnUiThread but i got the same results.

Could this be because this code is running in a Fragment?

The whole Fragment code is as follows:

package com.example.beacon;

import java.util.Collections;
import java.util.List;

import com.estimote.sdk.Beacon;
import com.estimote.sdk.BeaconManager;
import com.estimote.sdk.Region;

import android.app.Fragment;
import android.content.Intent;
import android.os.Bundle;
import android.os.RemoteException;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

public class FragmentBeacon extends Fragment {

private static final String TAG = MainActivity.class.getSimpleName();
private static final String ESTIMOTE_PROXIMITY_UUID = "B9407F30-F5F8-466E-AFF9-25556B57FE6D";
private static final Region ALL_ESTIMOTE_BEACONS = new Region("regionId",
        ESTIMOTE_PROXIMITY_UUID, null, null);

private BeaconManager beaconManager;
public LeDeviceListAdapter adapter = null;

public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
}

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

    adapter = new LeDeviceListAdapter(getActivity());
    beaconManager = new BeaconManager(getActivity());

    beaconManager.setRangingListener(new BeaconManager.RangingListener() {
        @Override
        public void onBeaconsDiscovered(Region region, List<Beacon> beacons) {
            Log.d(TAG, "Ranged beacons FB_onCreate: " + beacons);
            adapter.replaceWith(beacons);
            Log.d(TAG, "adapters found: " + adapter.getCount());
        }
    });

    beaconManager.connect(new BeaconManager.ServiceReadyCallback() {
        @Override
        public void onServiceReady() {
            try {
                beaconManager.startRanging(ALL_ESTIMOTE_BEACONS);
            } catch (RemoteException e) {
                Log.e(TAG, "Cannot start ranging", e);
            }
        }
    });

    Log.d(TAG, "Adapters found2: " + adapter.getCount());
    View rootView = inflater.inflate(R.layout.fragment_beacon, container,
            false);

    TextView[] pairs = new TextView[adapter.getCount()];
    for (int l = 0; l < adapter.getCount(); l++) {
        pairs[l] = new TextView(getActivity());
        pairs[l].setTextSize(15);

        pairs[l].setId(l);
        pairs[l].setText((l + 1) + ": something");
        ((ViewGroup) rootView).addView(pairs[l]);
    }

    return rootView;
}
@Override
public void onStop() {

    // Should be invoked in #onStop.
    try {
        beaconManager.stopRanging(ALL_ESTIMOTE_BEACONS);
    } catch (RemoteException e) {
        Log.e(TAG, "Cannot stop but it does not matter now", e);
    }
    super.onStop();
}

@Override
public void onDestroy() {

    // When no longer needed. Should be invoked in #onDestroy.
    beaconManager.disconnect();
    super.onDestroy();
}

}

Do not use here LeDeviceListAdapter, it is used only for ListView.

thanks wiktor! i changed it to
public List<Beacon> adapter;

and still its 0. i cant get the value of elements in the vecinity.

Ok. tried again.
Did the following just in case

try{
System.arraycopy(beacons, 0, beaconList, 0, beacons.size());
}
catch(Exception e){
Log.e(TAG, "ERROR COPYING ARRAY!!");
Log.e(TAG, e.toString());
}

and it went down the hatch to the exception. There HAS to be an easier way to get the data out.

Its starting to get frustrating. Please some guidance!

Beacon ranging is asynchronous operation. When you try to access beacons in onCreateView from the list, it is still empty. It will be filled with beacons later in time. You should build UI when onBeaconsDiscovered returns beacons.

So how would i check that if i can't find the docs for this?

It is documented in docs (http://estimote.github.io/Android-SDK/JavaDocs/). Check docs on BeaconManager class.

For the record i solved it.

I think it had NOTHING to do with the BeaconManager class. I had to use an adapter for the RangingListener. I actually DID use the LeDiviceListAdapter but only with the stuff i need.

The class EstimoteAdapter is just a renamed LeDeviceListAdapter but with no listeners whatsover.

Here is the used methods for the record:

private EstimoteAdapter EstimoteAdapter;

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    Log.d(TAG, "Entering onCreate");
    // Configure verbose debug logging.
    L.enableDebugLogging(true);

    // Configure BeaconManager.
    beaconManager = new BeaconManager(getActivity());
    System.out.println("Permissions and Service: "
            + beaconManager.checkPermissionsAndService());

}
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    View rootView = inflater.inflate(R.layout.fragment_main, container, false);
    final ListView listview = (ListView) rootView.findViewById(R.id.listEstimotes);
    EstimoteAdapter = new EstimoteAdapter(getActivity());
    listview.setAdapter(EstimoteAdapter);


    beaconManager.setRangingListener(new BeaconManager.RangingListener() {
        @Override
        public void onBeaconsDiscovered(Region region,
                final List<Beacon> beacons) {
            // Note that results are not delivered on UI thread.

            // Note that beacons reported here are already sorted by
            // estimated
            // distance between device and beacon.
            getActivity().runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    EstimoteAdapter.replaceWith(beacons);
                    //adapter.notifyDataSetChanged();
                };
            });
            Log.d(TAG, "Found beacons: " + beacons.size());

// Toast.makeText(getActivity(),
// "Found beacons: " + beacons.size(), Toast.LENGTH_LONG)
// .show();

        }
    });

    connectToService();

    return rootView;
}

private void connectToService() {
    System.out.println("connectToService");

    // Log.d(TAG,"beaconList size: "+beaconList.size());
    beaconManager.connect(new BeaconManager.ServiceReadyCallback() {

        @Override
        public void onServiceReady() {
            System.out.println("Init connect");
            try {
                beaconManager.startRanging(ALL_ESTIMOTE_BEACONS_REGION);

            } catch (RemoteException e) {
                Toast.makeText(
                        getActivity(),
                        "Cannot start ranging, something terrible happened",
                        Toast.LENGTH_LONG).show();
                Log.e(TAG, "Cannot start ranging", e);
            }
        }
    });
}