我正在开发一个小应用来检查我所在地区的各种网络运营商的信号强度。我当前的运营商信号非常不稳定,我想研究其他GSM运营商的实力。
Sofar我一直在使用TelephonyManager和一个带有onSignalStrengthsChanged回调的PhoneStateListener来获取当前网络运营商的GSM信号强度,但似乎这个类只给我关于网络信号强度的信息。我的SIM卡。
我对测量所有可用运营商的GSM信号强度感兴趣。搜索网络给出了使用内部android类的模糊提示,但我还没有找到任何好的例子。
任何能够让我获得所有可用网络运营商列表及其信号强度的答案都会得到应用。
答案 0 :(得分:22)
也许这些引号和链接可以帮助您编写自己的解决方案:
1.-获取可用网络提供商列表(完整引用How to get a list of available network providers?):
由于Android是开源的,我最后看了一下这些来源 找到了一个名为 INetworkQueryService 的东西。我想你可以做到 与android设置实现相同,并与此进行交互 服务。通过NetworkSettings.java的一些指导:
- onCreate启动NetworkQueryService并绑定它。
- loadNetworksList()告诉服务查询网络运营商。
- 评估INetworkQueryServiceCallback,如果引发了事件“EVENT_NETWORK_SCAN_COMPLETED”,那么networksListLoaded将是 被称为迭代可用的网络。
2.-即使快速阅读NetworkSetting.java和INetworkQueryService interface,也能让我们了解实现目标。
/** * Service connection code for the NetworkQueryService. * Handles the work of binding to a local object so that we can make * the appropriate service calls. */ /** Local service interface */ private INetworkQueryService mNetworkQueryService = null; /** Service connection */ private final ServiceConnection mNetworkQueryServiceConnection = new ServiceConnection() { /** Handle the task of binding the local object to the service */ public void onServiceConnected(ComponentName className, IBinder service) { if (DBG) log("connection created, binding local service."); mNetworkQueryService = ((NetworkQueryService.LocalBinder) service).getService(); // as soon as it is bound, run a query. loadNetworksList(); } /** Handle the task of cleaning up the local binding */ public void onServiceDisconnected(ComponentName className) { if (DBG) log("connection disconnected, cleaning local binding."); mNetworkQueryService = null; } };
Intent intent = new Intent(this, NetworkQueryService.class); ... startService (intent); bindService (new Intent(this, NetworkQueryService.class), mNetworkQueryServiceConnection, Context.BIND_AUTO_CREATE);
private void loadNetworksList() { ... // delegate query request to the service. try { mNetworkQueryService.startNetworkQuery(mCallback); } catch (RemoteException e) { } displayEmptyNetworkList(false); }
/** * This implementation of INetworkQueryServiceCallback is used to receive * callback notifications from the network query service. */ private final INetworkQueryServiceCallback mCallback = new INetworkQueryServiceCallback.Stub() { /** place the message on the looper queue upon query completion. */ public void onQueryComplete(List<OperatorInfo> networkInfoArray, int status) { if (DBG) log("notifying message loop of query completion."); Message msg = mHandler.obtainMessage(EVENT_NETWORK_SCAN_COMPLETED, status, 0, networkInfoArray); msg.sendToTarget(); } };
private void networksListLoaded(List<OperatorInfo> result, int status) { ... if (status != NetworkQueryService.QUERY_OK) { ... displayNetworkQueryFailed(status); displayEmptyNetworkList(true); } else { if (result != null){ displayEmptyNetworkList(false); ... } else { displayEmptyNetworkList(true); } } }
我希望它有所帮助。我认为这是一个有趣的挑战,所以也许下次我有空余时间试一试。祝你好运!
答案 1 :(得分:2)
private final PhoneStateListener phoneStateListener = new PhoneStateListener() {
@Override
public void onCallForwardingIndicatorChanged(boolean cfi) {
super.onCallForwardingIndicatorChanged(cfi);
}
@Override
public void onCallStateChanged(int state, String incomingNumber) {
//checkInternetConnection();
String callState = "UNKNOWN";
switch (state) {
case TelephonyManager.CALL_STATE_IDLE:
callState = "IDLE";
break;
case TelephonyManager.CALL_STATE_RINGING:
callState = "Ringing (" + incomingNumber + ")";
break;
case TelephonyManager.CALL_STATE_OFFHOOK:
callState = "Offhook";
break;
}
Log.i("Phone Stats", "onCallStateChanged " + callState);
super.onCallStateChanged(state, incomingNumber);
}
@Override
public void onCellLocationChanged(CellLocation location) {
String cellLocationString = location.toString();
super.onCellLocationChanged(location);
}
@Override
public void onDataActivity(int direction) {
String directionString = "none";
switch (direction) {
case TelephonyManager.DATA_ACTIVITY_IN:
directionString = "IN";
break;
case TelephonyManager.DATA_ACTIVITY_OUT:
directionString = "OUT";
break;
case TelephonyManager.DATA_ACTIVITY_INOUT:
directionString = "INOUT";
break;
case TelephonyManager.DATA_ACTIVITY_NONE:
directionString = "NONE";
break;
default:
directionString = "UNKNOWN: " + direction;
break;
}
Log.i("Phone Stats", "onDataActivity " + directionString);
super.onDataActivity(direction);
}
@Override
public void onDataConnectionStateChanged(int state,int networktype) {
String connectionState = "Unknown";
switch (state ) {
case TelephonyManager.DATA_CONNECTED :
connectionState = "Connected";
break;
case TelephonyManager.DATA_CONNECTING:
connectionState = "Connecting";
break;
case TelephonyManager.DATA_DISCONNECTED:
connectionState = "Disconnected";
break;
case TelephonyManager.DATA_SUSPENDED:
connectionState = "Suspended";
break;
default:
connectionState = "Unknown: " + state;
break;
}
super.onDataConnectionStateChanged(state);
Log.i("Phone Stats", "onDataConnectionStateChanged "
+ connectionState);
}
@Override
public void onMessageWaitingIndicatorChanged(boolean mwi) {
super.onMessageWaitingIndicatorChanged(mwi);
}
@Override
public void onServiceStateChanged(ServiceState serviceState) {
String serviceStateString = "UNKNOWN";
switch (serviceState.getState()) {
case ServiceState.STATE_IN_SERVICE:
serviceStateString = "IN SERVICE";
break;
case ServiceState.STATE_EMERGENCY_ONLY:
serviceStateString = "EMERGENCY ONLY";
break;
case ServiceState.STATE_OUT_OF_SERVICE:
serviceStateString = "OUT OF SERVICE";
break;
case ServiceState.STATE_POWER_OFF:
serviceStateString = "POWER OFF";
break;
default:
serviceStateString = "UNKNOWN";
break;
}
Log.i("Phone Stats", "onServiceStateChanged " + serviceStateString);
super.onServiceStateChanged(serviceState);
}
@Override
public void onSignalStrengthChanged(int asu) {
Log.i("Phone Stats", "onSignalStrengthChanged " + asu);
setSignalLevel( asu);
super.onSignalStrengthChanged(asu);
}
private void setSignalLevel(int level) {
int sLevel = (int) ((level / 31.0) * 100);
Log.i("signalLevel ", "" + sLevel);
}
};
答案 2 :(得分:1)
由于我没有50个声望点,这是我搜索主题的结果:
亚历杭德罗科罗拉多州的解决方案似乎很好。但问题是用于实现它的类是为Android系统应用程序保留的,即使用与系统相同的签名密钥签名的应用程序。
怎么可能?我找到了两种方法来实现这一目标。
第一个是询问任何制造商的工作,并签署他们的NDA,但是,这不是一个非常好的解决方案。特别是当使用此密钥实现和签名的应用程序仅适用于来自compagny的设备...
第二个,更令人愉快,但我警告你,这并不容易,就是制作自己的ROM。您必须创建应用程序,将其插入ROM的/ system / app /目录并重新编译,以使用新系统刷新设备。但是有一个问题我还没有回答,是无法识别ROM签名的问题。 我认为避免此问题的最佳方法是在您将要使用的恢复中添加您的ROM签名密钥。
这就是我在这一点上,也许你会发现这些研究很有用,我希望如此! 如果我为你们找到更多的信息,我会稍后回来。再见。
答案 3 :(得分:0)
创建一个PhoneStateListener并处理onSignalStrengthChanged回调。当您的应用初始化时,它应该给您初始通知。这是1.x.在2.x中,有关于此的开放issue。