Android: get CellID and RSS for Base Station and Neigboring Cells

ndrizza picture ndrizza · Mar 22, 2013 · Viewed 14.9k times · Source

I'm trying to get the following data:

  • Base station: CellID and RSS (recognition which one is the base station)
  • For all neigbouring stations: CellID and RSS

There are various APIs and it looks like i'd have to use different APIs telephonyManager and PhoneStateListener. I'm a littlebit confused, as I think this should be available in one interface. Also I think that it should be possible to poll the CellID of the current Base Station instead of having to listen to State Changes to determine int, since the Neighbouring Cell Stations cal also be polled from the telephonyManager.

Can you tell me how I can get the data specified above?

Answer

ndrizza picture ndrizza · Mar 23, 2013

New skool-way: API 17 much nicer and cleaner, but still too new.

List<CellInfo> cellInfos = (List<CellInfo>) this.telephonyManager.getAllCellInfo();

for(CellInfo cellInfo : cellInfos)
{
    CellInfoGsm cellInfoGsm = (CellInfoGsm) cellInfo;

    CellIdentityGsm cellIdentity = cellInfoGsm.getCellIdentity();
    CellSignalStrengthGsm cellSignalStrengthGsm = cellInfoGsm.getCellSignalStrength();

    Log.d("cell", "registered: "+cellInfoGsm.isRegistered());
    Log.d("cell", cellIdentity.toString());         
    Log.d("cell", cellSignalStrengthGsm.toString());
}

The old API doesn't provide a very satisfying solution. But here's the old-skool way:

this.telephonyManager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
this.phoneStateListener = setupPhoneStateListener();
this.telephonyManager.listen(phoneStateListener, PhoneStateListener.LISTEN_CELL_LOCATION);
this.telephonyManager.listen(phoneStateListener, PhoneStateListener.LISTEN_DATA_CONNECTION_STATE);
this.telephonyManager.listen(phoneStateListener, PhoneStateListener.LISTEN_SIGNAL_STRENGTHS);

// This part is used to listen for properties of the neighboring cells
List<NeighboringCellInfo> neighboringCellInfos = this.telephonyManager.getNeighboringCellInfo();
for(NeighboringCellInfo neighboringCellInfo : neighboringCellInfos)
{
    neighboringCellInfo.getCid();
    neighboringCellInfo.getLac();
    neighboringCellInfo.getPsc();
    neighboringCellInfo.getNetworkType();
    neighboringCellInfo.getRssi();

    Log.d("cellp",neighboringCellInfo.toString());
}

public PhoneStateListener setupPhoneStateListener()
{
    return new PhoneStateListener() {

        /** Callback invoked when device cell location changes. */
        @SuppressLint("NewApi")
        public void onCellLocationChanged(CellLocation location)
        {
            GsmCellLocation gsmCellLocation = (GsmCellLocation) location;
            gsmCellLocation.getCid();
            gsmCellLocation.getLac();
            gsmCellLocation.getPsc();

            Log.d("cellp", "registered: "+gsmCellLocation.toString());
        }

        /** invoked when data connection state changes (only way to get the network type) */
        public void onDataConnectionStateChanged(int state, int networkType)
        {
            Log.d("cellp", "registered: "+networkType);
        }

        /** Callback invoked when network signal strengths changes. */
        public void onSignalStrengthsChanged(SignalStrength signalStrength)
        {
            Log.d("cellp", "registered: "+signalStrength.getGsmSignalStrength());
        }

    };
}
  • Don't forget to set all the necessary permissions The problem with this solution is, that I don't get any neighboring cell info, eventhough i setup:

    uses-permission android:name="android.permission.ACCESS_COARSE_UPDATES"

(note that i'm using a Samsung phone and it's a known issue that Samsung phones don't support the listing of neighboring cells)