Telephony Manager Extention CellID

Hi

Is there anyone that have successfully used the telephony manager extention to retrieve the cell ID? If so, please can you share how to do this?

Hi. Thanks for your response. It would seem that LAC and CellID functionality was removed from the extension.

Is there another way to get the Cellid?

I was asking Gemini, if it still is possible to get that information and below is the answer.
I can implement it in July after my vacations

Taifun


Yes, it is still possible to get cell ID and LAC programmatically in Android, but the methods have evolved, and some older APIs are deprecated.

Here's a breakdown:

  1. Deprecated APIs (avoid for new development):
  • GsmCellLocation.getCid() and GsmCellLocation.getLac(): These methods are deprecated. While they might still work on older Android versions or for GSM networks specifically, they are not reliable across all network types (CDMA, WCDMA, LTE, NR) and may not be supported in future Android releases. Using them will result in lint warnings and potentially crashes on newer Android versions.
  1. Modern Approach (Recommended):
    The current and recommended way to get cell information, including cell ID and LAC (or their equivalents for newer networks), is through the TelephonyManager class and its getAllCellInfo() method.
  • TelephonyManager.getAllCellInfo(): This method returns a List objects. Each CellInfo object represents a serving or neighboring cell and can be cast to more specific types based on the network technology:
    • CellInfoGsm: For GSM (2G) networks. You can then get CellIdentityGsm to retrieve getCid() and getLac().
    • CellInfoWcdma: For WCDMA (3G) networks. You can get CellIdentityWcdma to retrieve getCid() and getLac().
    • CellInfoLte: For LTE (4G) networks. You can get CellIdentityLte to retrieve getCi() (Cell Identity) and getTac() (Tracking Area Code, which is the LTE equivalent of LAC).
    • CellInfoNr: For NR (5G) networks. You can get CellIdentityNr to retrieve getNci() (New Radio Cell Identity) and getTac().
  • Permissions: To access cell information, your app will need ACCESS_FINE_LOCATION or ACCESS_COARSE_LOCATION permissions. For Android Q (API level 29) and higher, you also need to handle background location access if you want to get cell info when your app is not in the foreground.

Example (Conceptual):

import android.Manifest;
import android.content.Context;
import android.content.pm.PackageManager;
import android.telephony.CellInfo;
import android.telephony.CellInfoGsm;
import android.telephony.CellInfoLte;
import android.telephony.CellInfoNr;
import android.telephony.CellInfoWcdma;
import android.telephony.TelephonyManager;
import androidx.core.content.ContextCompat;

import java.util.List;

public class CellInfoHelper {

    public static void getCellDetails(Context context) {
        TelephonyManager telephonyManager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);

        if (telephonyManager == null) {
            // Handle error: TelephonyManager not available
            return;
        }

        if (ContextCompat.checkSelfPermission(context, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
            // Request permissions if not granted
            // This would typically be handled in your Activity/Fragment
            return;
        }

        List<CellInfo> cellInfoList = telephonyManager.getAllCellInfo();

        if (cellInfoList != null) {
            for (CellInfo cellInfo : cellInfoList) {
                if (cellInfo.isRegistered()) { // Check if this is the serving cell
                    if (cellInfo instanceof CellInfoGsm) {
                        CellInfoGsm cellInfoGsm = (CellInfoGsm) cellInfo;
                        int cid = cellInfoGsm.getCellIdentity().getCid();
                        int lac = cellInfoGsm.getCellIdentity().getLac();
                        System.out.println("GSM Cell - CID: " + cid + ", LAC: " + lac);
                    } else if (cellInfo instanceof CellInfoWcdma) {
                        CellInfoWcdma cellInfoWcdma = (CellInfoWcdma) cellInfo;
                        int cid = cellInfoWcdma.getCellIdentity().getCid();
                        int lac = cellInfoWcdma.getCellIdentity().getLac();
                        System.out.println("WCDMA Cell - CID: " + cid + ", LAC: " + lac);
                    } else if (cellInfo instanceof CellInfoLte) {
                        CellInfoLte cellInfoLte = (CellInfoLte) cellInfo;
                        int ci = cellInfoLte.getCellIdentity().getCi();
                        int tac = cellInfoLte.getCellIdentity().getTac();
                        System.out.println("LTE Cell - CI: " + ci + ", TAC: " + tac);
                    } else if (cellInfo instanceof CellInfoNr) {
                        CellInfoNr cellInfoNr = (CellInfoNr) cellInfo;
                        long nci = cellInfoNr.getCellIdentity().getNci();
                        int tac = cellInfoNr.getCellIdentity().getTac();
                        System.out.println("NR Cell (5G) - NCI: " + nci + ", TAC: " + tac);
                    }
                }
            }
        }
    }
}

Important Considerations:

  • Network Type: Cell ID and LAC are terms primarily associated with GSM and WCDMA networks. For LTE and NR, the corresponding identifiers are Cell Identity (CI) and Tracking Area Code (TAC), or New Radio Cell Identity (NCI) and TAC respectively. The getAllCellInfo() method handles these different types.
  • Device and ROM Variations: While the getAllCellInfo() API is the standard, some older devices or custom ROMs might have inconsistencies in the data they provide or might not support all CellInfo subtypes.
  • Serving Cell vs. Neighboring Cells: getAllCellInfo() can return information about both the serving cell (the one your device is currently connected to) and neighboring cells. You'll typically filter for isRegistered() to identify the serving cell.
  • Privacy and Permissions: Accessing cell information is considered sensitive. Always request the necessary permissions (e.g., ACCESS_FINE_LOCATION) and explain to the user why your app needs this information.
  • Background Access: If your app needs to retrieve cell ID and LAC in the background, you'll need to handle background location permissions appropriately, which has stricter requirements on newer Android versions.

In summary, while the older GsmCellLocation methods are deprecated, the TelephonyManager.getAllCellInfo() API provides a robust and modern way to retrieve cell ID and LAC (or their equivalents) programmatically on Android devices, provided you have the necessary location permissions.

1 Like

Much obliged