检索基站信息

26

有没有人知道如何在Android上获取GSM和CDMA的基站列表。

我一直在尝试使用Google Maps位置API: https://developers.google.com/maps/documentation/business/geolocation/

我想要获取以下这些字段的基站信息:

  • cellId:单元格的唯一标识符。在GSM中,这是Cell ID (CID);CDMA网络使用基站ID (BID)。
  • locationAreaCode:GSM网络的位置区域码 (LAC);CDMA网络使用网络ID (NID)。
  • mobileCountryCode:基站的移动国家码 (MCC)。
  • mobileNetworkCode:基站的移动网络代码。这是GSM的MNC,或者是CDMA的系统ID (SID)。
  • age:自此单元格成为主要单元格以来的毫秒数。如果age为0,则cellId表示当前测量。
  • signalStrength:以dBm为单位测量的无线电信号强度。
  • timingAdvance:定时提前值。

此代码并未特别获取基站信息。

TelephonyManager tel = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);

// Type of the network
int phoneTypeInt = tel.getPhoneType();
String phoneType = null;
phoneType = phoneTypeInt == TelephonyManager.PHONE_TYPE_GSM ? "gsm" : phoneType;
phoneType = phoneTypeInt == TelephonyManager.PHONE_TYPE_CDMA ? "cdma" : phoneType;
try {
  if (phoneType != null) {
    params.put("radioType", phoneType);
  }
} catch (Exception e) {}

/*
 * The below code doesn't work I think.
 */
JSONArray cellList = new JSONArray();
List<NeighboringCellInfo> neighCells = tel.getNeighboringCellInfo();
for (int i = 0; i < neighCells.size(); i++) {
  try {
    JSONObject cellObj = new JSONObject();
    NeighboringCellInfo thisCell = neighCells.get(i);
    cellObj.put("cellId", thisCell.getCid());
    cellList.put(cellObj);
  } catch (Exception e) {}
}
if (cellList.length() > 0) {
  try {
    params.put("cellTowers", cellList);
  } catch (JSONException e) {}
}

我设置了以下权限:

<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_UPDATES"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/>
<uses-permission android:name="android.permission.INTERNET"/>

请帮助我,谢谢。


4
"我的代码能够运行,但无法获取基站信息" 这个描述并不能够清晰地说明你的症状。请花时间详细解释哪些部分能够正常工作,哪些部分无法正常工作。 - CommonsWare
抱歉,英语不是我的母语。 当我在我的 Android 上运行代码(运营商为 Sprint)时,“tel.getNeighboringCellInfo();”总是返回 null。 - wf9a5m75
即使我在其他GSM网络的安卓手机上尝试这段代码,结果也是一样的。因此我的问题是如何获取基站信息。 - wf9a5m75
3个回答

12

我最近也遇到了这个问题,原因是

getNeighboringCellInfo

从API 23开始已经被弃用。为了解决这个问题,请使用类似下面的代码(实在很麻烦):

public static JSONArray getCellInfo(Context ctx){
        TelephonyManager tel = (TelephonyManager) ctx.getSystemService(Context.TELEPHONY_SERVICE);

        JSONArray cellList = new JSONArray();

// Type of the network
        int phoneTypeInt = tel.getPhoneType();
        String phoneType = null;
        phoneType = phoneTypeInt == TelephonyManager.PHONE_TYPE_GSM ? "gsm" : phoneType;
        phoneType = phoneTypeInt == TelephonyManager.PHONE_TYPE_CDMA ? "cdma" : phoneType;

        //from Android M up must use getAllCellInfo
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {



            List<NeighboringCellInfo> neighCells = tel.getNeighboringCellInfo();
            for (int i = 0; i < neighCells.size(); i++) {
                try {
                    JSONObject cellObj = new JSONObject();
                    NeighboringCellInfo thisCell = neighCells.get(i);
                    cellObj.put("cellId", thisCell.getCid());
                    cellObj.put("lac", thisCell.getLac());
                    cellObj.put("rssi", thisCell.getRssi());
                    cellList.put(cellObj);
                } catch (Exception e) {
                }
            }

        } else {
            List<CellInfo> infos = tel.getAllCellInfo();
            for (int i = 0; i<infos.size(); ++i) {
                try {
                    JSONObject cellObj = new JSONObject();
                    CellInfo info = infos.get(i);
                    if (info instanceof CellInfoGsm){
                        CellSignalStrengthGsm gsm = ((CellInfoGsm) info).getCellSignalStrength();
                        CellIdentityGsm identityGsm = ((CellInfoGsm) info).getCellIdentity();
                        cellObj.put("cellId", identityGsm.getCid());
                        cellObj.put("lac", identityGsm.getLac());
                        cellObj.put("dbm", gsm.getDbm());
                        cellList.put(cellObj);
                    } else if (info instanceof CellInfoLte) {
                        CellSignalStrengthLte lte = ((CellInfoLte) info).getCellSignalStrength();
                        CellIdentityLte identityLte = ((CellInfoLte) info).getCellIdentity();
                        cellObj.put("cellId", identityLte.getCi());
                        cellObj.put("tac", identityLte.getTac());
                        cellObj.put("dbm", lte.getDbm());
                        cellList.put(cellObj);
                    }

                } catch (Exception ex) {

                }
            }
        }

        return cellList;
    }

1
请注意,“已弃用”和“不再工作”是两个不同的概念——有许多已弃用的API仍然像以前一样工作,唯一的限制是它们缺乏对自从引入以来可能引入的新功能的支持(就像这个API一样,它从来没有任何适当的LTE支持)。然而,这些API的供应商支持程度却大相径庭。 - user149408

9

1
我明白了。那么,你知道除了getNeighboringCellInfo()之外还有其他获取小区列表的方法吗? - wf9a5m75
抱歉,我也是新手。 - Bernd Alpmoos
1
谢谢你,Bernd。我放弃尝试这个了。 - wf9a5m75

0

这不是你的手机不支持这些信息,而是与提供这些API调用相关的RIL C和Java的糟糕实现阻止了这一点。如果你设法进入服务模式菜单(这在不同的手机上有很大的差异),你将完全且立即地访问RSSI和大量其他类型的信号。你应该责怪谷歌(或你的OEM)没有解决这些问题并提供更好的访问RF相关变量。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接