Android:如何获取所有可用网络运营商的 GSM 信号强度
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/10454388/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Android: How do I get GSM signal strength for all available network operators
提问by The Schwartz
I am working on a little app to check the signal strength of various network operators in my area. My current operators signal is quite unstable and I want to look into the strength of other GSM operators.
我正在开发一个小应用程序来检查我所在地区的各种网络运营商的信号强度。我目前的运营商信号很不稳定,我想看看其他 GSM 运营商的强度。
Sofar I've been using the TelephonyManager and a PhoneStateListener with the onSignalStrengthsChanged call back to get the GSM Signal strength of the current network operator, but it seems that this class only gives me info on the signal strength of the network attached to my SIM card.
到目前为止,我一直在使用 TelephonyManager 和 PhoneStateListener 以及 onSignalStrengthsChanged 回调来获取当前网络运营商的 GSM 信号强度,但似乎这个类只提供了有关连接到我的 SIM 卡的网络的信号强度的信息.
I'm interested in measurement of GSM signal strength of ALL available operators. Searching the net has given vague hints on using internal android classes, but I've not yet found any good examples on this.
我对测量所有可用运营商的 GSM 信号强度感兴趣。搜索网络已经给出了使用内部 android 类的模糊提示,但我还没有找到任何好的例子。
Any answer that can move me on to get a list of all available network operators and their signal strength are appreaciated.
任何可以让我获得所有可用网络运营商及其信号强度列表的答案都得到了认可。
回答by Alejandro Colorado
Maybe these quotes and links can help you code your own solution:
也许这些引用和链接可以帮助您编写自己的解决方案:
1.- To get a list of available network providers (quoting How to get a list of available network providers?in full):
1.- 获取可用网络提供商的列表(完整引用如何获取可用网络提供商的列表?):
Since Android is open source I had a look at the sources and finally found something called INetworkQueryService. I guess you can do the same as the android settings implementation and interact with this service. Some guidance through NetworkSettings.java:
- onCreate starts the NetworkQueryService and binds it.
- loadNetworksList() tells the service to query for network operators.
- INetworkQueryServiceCallback is evaluated and if the event "EVENT_NETWORK_SCAN_COMPLETED" was raised, networksListLoaded will be called to iterate over the available Networks.
由于 Android 是开源的,我查看了源代码,终于找到了一个叫做INetworkQueryService 的东西。我猜你可以像android设置实现一样做,并与这个服务交互。通过 NetworkSettings.java 的一些指导:
- onCreate 启动 NetworkQueryService 并绑定它。
- loadNetworksList() 告诉服务查询网络运营商。
- 评估 INetworkQueryServiceCallback 并且如果引发事件“EVENT_NETWORK_SCAN_COMPLETED”,则将调用networksListLoaded 以遍历可用网络。
2.- Even a quick read to NetworkSetting.javaand INetworkQueryService interface, gives us an idea to achieve your goal.
2.- 即使快速阅读NetworkSetting.java和INetworkQueryService interface,也能让我们了解实现您的目标。
- Connect the service in declaration.
- 在声明中连接服务。
/** * 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; } };
/** * 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; } };
- onCreate starts the NetworkQueryService and binds it.
- onCreate 启动 NetworkQueryService 并绑定它。
Intent intent = new Intent(this, NetworkQueryService.class); ... startService (intent); bindService (new Intent(this, NetworkQueryService.class), mNetworkQueryServiceConnection, Context.BIND_AUTO_CREATE);
Intent intent = new Intent(this, NetworkQueryService.class); ... startService (intent); bindService (new Intent(this, NetworkQueryService.class), mNetworkQueryServiceConnection, Context.BIND_AUTO_CREATE);
- loadNetworksList() tells the service to query for network operators.
- loadNetworksList() 告诉服务查询网络运营商。
private void loadNetworksList() { ... // delegate query request to the service. try { mNetworkQueryService.startNetworkQuery(mCallback); } catch (RemoteException e) { } displayEmptyNetworkList(false); }
private void loadNetworksList() { ... // delegate query request to the service. try { mNetworkQueryService.startNetworkQuery(mCallback); } catch (RemoteException e) { } displayEmptyNetworkList(false); }
- INetworkQueryServiceCallback is evaluated:
- 评估 INetworkQueryServiceCallback:
/** * 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(); } };
/** * 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(); } };
- If the event "EVENT_NETWORK_SCAN_COMPLETED" was raised, networksListLoaded will be called to iterate over the available Networks.
- 如果引发事件“EVENT_NETWORK_SCAN_COMPLETED”,则将调用networksListLoaded 以遍历可用网络。
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); } } }
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); } } }
I hope it helps. I think it's an interesting challenge so maybe I'll give it a try next time I have some spare time. Good luck!
我希望它有帮助。我认为这是一个有趣的挑战,所以下次我有空的时候也许会尝试一下。祝你好运!
回答by Sandeep
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);
}
};
回答by eduine
As I have no 50 reputation points, here is the result of my searches about the subject :
由于我没有 50 点声望,以下是我对该主题的搜索结果:
The solution of Alejandro Colorado seems to be the good one. But the problem is that the classes used to achieve it are reserved for android system applications, i.e. apps which are signed with the same signature key as the system.
亚历杭德罗科罗拉多的解决方案似乎是好的。但问题是用于实现它的类是为安卓系统应用程序保留的,即使用与系统相同的签名密钥签名的应用程序。
How could it be possible? I found two way to achieve this.
怎么可能?我找到了两种方法来实现这一目标。
The first one is to ask a job at any manufacturer compagny, and sign their NDA, but eh, that's not a really good solution. Especially as the app implemented and signed with this key will only work on devices from the compagny...
第一个是在任何制造商公司找一份工作,然后签署他们的 NDA,但是,呃,这不是一个很好的解决方案。特别是因为使用此密钥实现和签名的应用程序只能在公司的设备上运行...
The second one, much more enjoyable, but i warn you, it's not gonna be easy, is to make your own ROM. You'll have to create your application, insert it in the /system/app/ directory of your ROM and recompile it to flash your device with your new system. But there's a question i've not answered yet, is the problem of unrecognised ROM signature. I think the best way to avoid this problem is to add your ROM signing key in the Recovery you'll be using.
第二个,更有趣,但我警告你,这并不容易,是制作你自己的 ROM。您必须创建您的应用程序,将其插入到您的 ROM 的 /system/app/ 目录中并重新编译它以使用您的新系统刷新您的设备。但是有一个我还没有回答的问题,是无法识别的 ROM 签名问题。我认为避免此问题的最佳方法是在您将使用的恢复中添加您的 ROM 签名密钥。
That's where i am at this point, maybe you could find these research usefull, i hope so! I'll come back later if i find some more informations for you guys. Bye.
这就是我现在所处的位置,也许你会发现这些研究有用,我希望如此!如果我为你们找到更多信息,我会稍后再回来。再见。
回答by Krishnakant Dalal
create a PhoneStateListener and handle the onSignalStrengthChanged callback. When your app is initialized, it should give you an initial notification. This is in 1.x. in 2.x, there's an open issueabout this.
创建一个 PhoneStateListener 并处理 onSignalStrengthChanged 回调。当您的应用程序初始化时,它应该给您一个初始通知。这是在 1.x 中。在 2.x 中,有一个关于此的未决问题。