2017年6月15日星期四

Android Decode eNB & cell id from ci

TelephonyManager tm = (TelephonyManage) Context.getSystemService(Context.TELEPHONY_SERVICE)
List<CellInfo> mCellInfo = tm.getALLCellInfo();
CellIdentityLte cellid = cellInfo.getCellIdentity();
String cellidHex = DecToHex(cellid.getCi());
String eNBHex = cellidHex.substring(0, cellidHex.length() - 2);
String lcidHex = cellidHex.substring(cellidHex.length() - 2);
int eNB = HexToDec(eNBHex);
int localCellid = exToDec(lcidHex);


// Decimal -> hexadecimal
 public String DecToHex(int dec){
    return String.format("%x", dec);
}

// hex -> decimal
public int HexToDec(String hex){
    return Integer.parseInt(hex, 16);
}

Android Get LTE signal strength

Use PhoneStateListener:

PhoneStateListener _psl = new PhoneStateListener() {
    public void onSignalStrengthsChanged(SignalStrength signalStrength) {
        Log.v("DEBUG_JOB", "onSignalStrengthsChanged");
        getLteDbm(signalStrength);
    }
};
TelephonyManager telephonyManager = (TelephonyManager)context.getSystemService(Context.TELEPHONY_SERVICE);
telephonyManager.listen(_psl, PhoneStateListener.LISTEN_SIGNAL_STRENGTHS);

There are three methods that I found:

First: When Build.VERSION.SDK_INT  >= 17, use getAllCellInfo() methods of TelephonyManager class. But on some mobile device, getAllCellInfo() always return null.

public int getLteDbm(SignalStrength signalStrength) {
    int rsrp = 0;
    TelephonyManager telephonyManager = (TelephonyManager)context.getSystemService(Context.TELEPHONY_SERVICE);
    List<CellInfo> mCellInfo = telephonyManager.getAllCellInfo();
    if (mCellInfo != null && mCellInfo.size() != 0) {
        int index = 0;
        for (CellInfo cellInfo : mCellInfo) {
            if (cellInfo.isRegistered() && cellInfo instanceof CellInfoLte) {
                Log.v("DEBUG_JOB", "[" + index + "]==CellInfoLte");
                CellInfoLte x = (CellInfoLte) cellInfo;
                CellSignalStrengthLte cstr = x.getCellSignalStrength();
                if (cstr != null) {
                    rsrp = cstr.getDbm();
                    Log.v("DEBUG_JOB", "RSRP=" + rsrp);
                }
                CellIdentityLte cellid = x.getCellIdentity();
                int pci = cellid.getPci();
                Log.v("DEBUG_JOB", "PCI=" + pci);
                Log.v("DEBUG_JOB", "CI=" + cellid.getCi());
            }
            index++;
        }
    }
    return  rsrp;
}

======================================================================
Second: Use split string on SignalStrength to get mLteRsrp value. But different mobile device got different position of mLteRsrp value.

public int getLteDbm(SignalStrength signalStrength) {
    String ssignal = signalStrength.toString();
    String[] parts = ssignal.split(" ");
    int rsrp = parts.length >= 9 ? Integer.parseInt(parts[9]) : -1; // some devices is 11
    return rsrp;
}

======================================================================
Last: Use the hidden getLteRsrp() method of the SignalStrength class.

public int getLteDbm(SignalStrength signalStrength) {
    int rsrp = 0;
    try {
        rsrp = (Integer) signalStrength.getClass().getMethod("getLteRsrp").invoke(signalStrength);
    } catch (Exception ex) {
        Log.v("Error", "getLteDbm=" + ex.getMessage());
    }
    return rsrp;
}