androidcellcellinfo

onCellInfoChanged() callback is always null


i am trying to get a list of all available cells the device can find. But i am stuck, as my CellInfo is always null and i don't figure why. Can someone give me a hint? There is pretty few info on onCellInfoChanged() at google.

MainActivity:

 CellListener cellListener = new CellListener(this);
 cellListener.start();

CellListener:

public class CellListener extends PhoneStateListener {

private static final String TAG = "CellListener";
private TelephonyManager telephonyManager = null;
private PhoneStateListener listener = null;
private String newCell = null;  
private int events = PhoneStateListener.LISTEN_CELL_LOCATION | PhoneStateListener.LISTEN_CELL_INFO;
private Context context = null;

public CellListener(Context context) {
    this.context = context;
}

public void start() {

    telephonyManager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
    CellLocation.requestLocationUpdate();

    telephonyManager.listen(this, events);
}

@Override
public void onCellInfoChanged(List<CellInfo> cellInfo) {
    Log.i("CellListener","onCellInfoChanged(List<CellInfo> cellInfo) ");
    super.onCellInfoChanged(cellInfo);

     if(cellInfo == null) return;     // this always null here

     for (CellInfo c : cellInfo) {          
        Log.i("CellListener"," c = "+c);
    }       
 }

 @Override
    public void onCellLocationChanged(CellLocation location) {
        if (!(location instanceof GsmCellLocation)) {
            return;
        }
        GsmCellLocation gsmCell = (GsmCellLocation) location;
        String operator = telephonyManager.getNetworkOperator();
        if (operator == null || operator.length() < 4) {
            return;
        }
        newCell = operator.substring(0, 3) + ':' + operator.substring(3) + ':'
                + gsmCell.getLac() + ':' + gsmCell.getCid();

        Log.i(TAG,"newCell = "+newCell);     
    }
}

Logcat:

11-18 14:50:23.806: I/CellListener(4953): newCell = 262:02:4311:99031735
11-18 14:50:23.814: I/CellListener(4953): onCellInfoChanged(List<CellInfo> cellInfo) 

As you can see both events (onCellInfoChanged & onCellLocationChanged) get triggered once and the latter is correctly returning the current cell the device is using.


Solution

  • The real reason you are only being called exactly once and with null as an argument is the following: there appears to be a rate-limiting setting in place by default, as can be observed in the "testing" app, which can be accessed by dialing *#*#INFO#*#* (i.e. *#*#4636#*#*).

    In the testing app, choose "Phone Information" and scroll down to the button CELLINFOLISTRATE xxxx, in your case presumably CELLINFOLISTRATE 2147483647. As 2147483647 == MAX_INT, this probably means no calls at all

    For me (stock android 6.0, nexus 6), there's the a choice between MAX_INT (one call with null), 0 and 1000.

    I'm not 100% sure what these values mean, but presumably the 0 stands for instant (and thus very many) calls, and 1000 for something like at least a second between calls. Keep in mind though, this is pure speculation.

    I will edit this answer as I find out more, for example by looking at the implementation of said testing app.