我正在编写一个应用程序,需要在当前服务单元格更改时得到通知。所以我实现了一个PhoneStateListener来监听单元格位置的变化,并由以下函数启动:
public void start() {
if (mContext == null) {
Log.e(AutoWifi.LOGTAG, "Context in PhoneStateListener was null");
return;
}
if (this.mTM != null) {
this.mTM.listen(this, PhoneStateListener.LISTEN_CELL_LOCATION);
Log.v(AutoWifi.LOGTAG, "Registered listener for onCellInfoChanged and onCellLocationChanged");
} else {
// ...
}
}
mTM
是一个TelephonyManager
,它曾在侦听器CTOR中创建。相应的回调函数如下所示:
@Override
public void onCellLocationChanged(CellLocation location) {
Log.v(AutoWifi.LOGTAG, "onCellLocationChanged(CellLocation)");
super.onCellLocationChanged(location);
Log.v(AutoWifi.LOGTAG, "oclc:cid=" + ((GsmCellLocation) location).getCid()); // (1) (A)
this.refreshActiveCell(); // (B)
}
到现在为止一切正常。每次发生小区更改时都会调用处理程序,并且位置对象包含新单元的小区ID(对于GSM / UMTS / LTE网络)。但是,由于我还需要新服务单元格的MNC和MCC值(两者都不在CellLocation
对象中提供),我调用自己的refreshActiveCell()
函数使用getAllCellInfo
和{{ 1}}确定新的服务单元格,如下所示:
CellInfo.isRegistered
现在事情变得有些混乱:当一个小区从UMTS网络变为LTE时(MNC值发生变化),传递给public void refreshActiveCell() {
List<CellInfo> cells = this.mTM.getAllCellInfo();
this.mActiveCells.clear();
if (cells != null) {
for (final CellInfo ccell : cells) {
if (ccell.isRegistered() == true) {
this.mActiveCells.add(ccell);
}
}
}
CellInfo activecell = null;
if (this.mActiveCells.size() > 0) {
activecell = this.mActiveCells.get(0);
}
String cellidstr = "-/-";
if (activecell == null) {
cellidstr = "-/-";
} else {
if (activecell instanceof CellInfoGsm) {
final CellInfoGsm gcell = (CellInfoGsm) activecell;
cellidstr = Integer.toString(gcell.getCellIdentity().getCid());
} else if (activecell instanceof CellInfoWcdma) {
final CellInfoWcdma wcell = (CellInfoWcdma) activecell;
cellidstr = Integer.toString(wcell.getCellIdentity().getCid());
} else if (activecell instanceof CellInfoLte) {
final CellInfoLte lcell = (CellInfoLte) activecell;
cellidstr = Integer.toString(lcell.getCellIdentity().getCi());
} else {
cellidstr = "-/-";
}
}
Log.d(AutoWifi.LOGTAG, "activecell:" + cellidstr); // (2) (C)
// ...
}
回调函数的小区位置包含新的正确ci值LTE小区(在(1)处输出)。但是onCellLocationChanged
中的activecell
对象也应该代表新的服务小区(通过使用refreshActiveCell
和TelephonyManager.getAllCellInfo()
函数确定)仍然代表旧的UMTS小区(输出于(2))。
当从LTE到UMTS的小区改变时,会发生同样的事情。
我调试了应用程序并在几行中设置了断点:当在(A)或(B)设置断点时(被点击并且我继续使用应用程序)一切正常并且CellInfo.isRegistered
对象和单元格传递给回调函数的位置具有相同的单元ID。
在(C)处设置断点时(也是命中),上述问题再次发生。
所以我的问题是:为什么传递给activecell
的{{1}}对象中包含的单元格id(以及显然当前服务的单元格)与CellLocation
确定的单元格不同和onCellLocationChanged
?我不允许在回调函数处理程序中使用TelephonyManager.getAllCellInfo()
吗?还有另一种方法可以在CellInfo.isRegistered()
回调函数中获取新服务单元格(而不仅仅是单元格位置)的整个getAllCellInfo
对象吗?
BTW:我使用的是安卓5.1.1,API级别22和Android Studio的索尼智能手机。所以目前min-SDK也是22.在清单文件中我设置了权限:
CellInfo