问题
Currently I am trilaterating my Android with the cells in my network. It is even more accurate than I thought it would be. But not as accurate as I want it to be. So I want to involve more towers than I get from getNeighboringCellInfo. I want to get the Cell ID and signal strength of every tower in range. Of every network operater. Is there a way to "ping" the towers, so they answer with cellID, Lac and signalstrength? Somehow this has to be possible. And can I scan the 2G and 3G (and 4G) parallel? Or can I switch between them programmatically? Any suggestions? Hope I'm clear enough...
回答1:
Seems TelephonyManager
and getNeighboringCellInfo()
are what you are looking for.
Here's a example, which is easy and straight forward:
/* first you wanna get a telephony manager by asking the system service */
TelephonyManager tm = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
/* then you can query for all the neighborhood cells */
List<NeighboringCellInfo> neighbors = tm.getNeighboringCellInfo();
/* here's something you can get from NeighboringCellInfo */
for (NeighboringCellInfo n : neighbors) {
Log.v("CellInfo", "" + n.getCid());
Log.v("CellInfo", "" + n.getLac());
Log.v("CellInfo", "" + n.getPsc());
Log.v("CellInfo", "" + n.getRssi());
}
Make sure you include all the permissions required, such as ACCESS_COARSE_LOCATION
or READ_PHONE_STATE
, depending on what API you'll be using, in your manifest file, or it'll simply crash.
Oh btw this only works for 2G. 3G or above doesn't support this kind of operation.
回答2:
As of now, this is the proper way of getting neighbouring cell information:
TelephonyManager telephonyManager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
List<CellInfo> cellInfoList = telephonyManager.getAllCellInfo();
for (int i = 0; i < cellInfoList.size(); i++) {
if (cellInfoList.get(i) instanceof CellInfoWcdma) {
CellInfoWcdma cellInfoWcdma = (CellInfoWcdma) cellInfoList.get(i);
/* Get LAC, strength etc. here */
} else if (cellInfoList.get(i) instanceof CellInfoGsm) {
CellInfoGsm cellInfoGsm = (CellInfoGsm) cellInfoList.get(i);
/* Get LAC, strength etc. here */
} else if (cellInfoList.get(i) instanceof CellInfoLte) {
CellInfoLte cellInfoLte = (CellInfoLte) cellInfoList.get(i);
/* Get TAC, strength etc. here */
} else if (cellInfoList.get(i) instanceof CellInfoCdma) {
CellInfoCdma cellInfoCdma = (CellInfoCdma) cellInfoList.get(i);
/* Get strength etc. here */
}
}
Now,
You can find LAC as
cellInfoWcdma.getCellIdentity().getLac()
, similarly forcellInfoGsm
andcellInfoLte
. Note that CDMA does not contain LAC. Also note that LTE has TAC instead of LAC which are similar except their terminology.You can find strength as
cellInfoWcdma.getCellSignalStrength().getLevel()
. Similar is for LTE, GSM and CDMA. Note that you cangetLevel
,getDbm
orgetAsuLevel
, whatever you are interested in.For CID, you can get it as
cellInfoWcdma.getCellIdentity().getCid()
, similarly for LTE and GSM. Note that LTE hasgetCi
instead ofgetCid
. Also note that it is not available for CDMA.If you're interested in MCC and MNC, you can get it as
cellInfoWcdma.getCellIdentity().getMccString()
for API Level >= 28, else usecellInfoWcdma.getCellIdentity().getMcc()
. Note, you cannot get MCC and MNC for CDMA.
You can make your own model class and store what all values you need by making their objects (where I have commented). Store those objects in a list. Don't forget to add permissions to Manifest.
来源:https://stackoverflow.com/questions/12491256/getting-cid-lac-and-signal-strength-of-all-cell-towers-in-range