Android:如何获取所有可用网络运营商的 GSM 信号强度

Posted

技术标签:

【中文标题】Android:如何获取所有可用网络运营商的 GSM 信号强度【英文标题】:Android: How do I get GSM signal strength for all available network operators 【发布时间】:2012-05-14 07:49:47 【问题描述】:

我正在开发一个小应用程序来检查我所在地区各种网络运营商的信号强度。我现在运营商的信号很不稳定,想看看其他运营商的实力。

到目前为止,我一直在使用 TelephonyManager 和带有 onSignalStrengthsChanged 回调的 PhoneStateListener 来获取当前网络运营商的 GSM 信号强度,但似乎这个类只为我提供了有关连接到的网络的信号强度的信息我的 SIM 卡。

我对测量所有可用运营商的 GSM 信号强度感兴趣。搜索网络已经给出了关于使用内部 android 类的模糊提示,但我还没有找到任何好的例子。

任何可以让我继续获取所有可用网络运营商及其信号强度列表的答案都值得赞赏。

【问题讨论】:

好用又简单tutorial 嗨,你得到这个问题的答案了吗?如果你得到了,请举一些例子?我需要和你一样的要求.. 我知道这是一个旧线程,但你完成了你的应用程序吗?可以在哪里下载吗? 您好@Schwartz,我正在寻找相同的要求。你找到解决方案了吗?如果您可以建议,任何付费/免费 API。 【参考方案1】:

也许这些引用和链接可以帮助您编写自己的解决方案:

1.- 获取可用网络提供商的列表(完整引用 How to get a list of available network providers?):

由于 Android 是开源的,我查看了源代码,最后 找到了一个名为 INetworkQueryService 的东西。我想你可以做到 与 android 设置实现相同并与之交互 服务。通过 NetworkSettings.java 的一些指导:

onCreate 启动 NetworkQueryService 并绑定它。 loadNetworksList() 告诉服务查询网络运营商。 INetworkQueryServiceCallback 已评估,如果引发事件“EVENT_NETWORK_SCAN_COMPLETED”,networkListLoaded 将 调用以迭代可用的网络。

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;
    
;
onCreate 启动 NetworkQueryService 并绑定它。
Intent intent = new Intent(this, NetworkQueryService.class);
...
startService (intent);
bindService (new Intent(this, NetworkQueryService.class), mNetworkQueryServiceConnection,
                        Context.BIND_AUTO_CREATE);
loadNetworksList() 告诉服务查询网络运营商。
private void loadNetworksList() 
...    
// delegate query request to the service.
try 
    mNetworkQueryService.startNetworkQuery(mCallback);
 catch (RemoteException e) 


displayEmptyNetworkList(false); 

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();
    
;
如果引发“EVENT_NETWORK_SCAN_COMPLETED”事件,将调用networkListLoaded 以遍历可用网络。
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);
        
    

我希望它有所帮助。我认为这是一个有趣的挑战,所以下次有空的时候我会尝试一下。祝你好运!

【讨论】:

如何导入INetworkQueryService之类的项目?我找不到日食识别的路径。 今天不能尝试,抱歉,但是如果import com.android.phone.INetworkQueryService 不起作用,您可以复制代码并使用相同的原则创建自己的解决方案(基本上,这就是我想说的在我的回答中)。 这正是我所做的:我从头开始创建了一个 Activity 并使用了您建议的代码。但是,很多引用的类,例如INetworkQueryServiceNetworkQueryService 都无法识别,eclipse 找不到它们的导入并且明显的猜测(例如import com.android.phone.INetworkQueryService)导致The import com.android.phone cannot be resolved。你有什么建议? 在我能想象的范围内,你不能import com.android.phone,但你可以访问源代码。我在回答中的建议是创建自己的解决方案,复制和修改它以满足您的需求。 我尝试这样做有一个多月,我不知道这个假设是如何设置为正确答案的(或 175 分)。有人试过吗?工作了吗?我不能拥有 NetworkQueryService 的实例,因为它是一个内部类,为此我应该使用一个包含该类实例的对象,顺便说一下,我不知道在哪里找到它或者是否真的有可能被发现。请帮我搜索一下。【参考方案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);
    

;

【讨论】:

感谢您的回复,但此代码将“仅”提供有关订阅网络的信息,我也对该地区其他提供商的信号强度感兴趣。 表示当您搜索网络时,列表中显示的运营商,您想知道所有显示的运营商网络强度..我是对的吗??? 没错,我想查看所有可能的网络运营商的列表以及我目前所在的信号强度。【参考方案3】:

由于我没有 50 点声望点,以下是我对该主题的搜索结果:

Alejandro Colorado 的解决方案似乎是一个不错的解决方案。但问题是用于实现它的类是为android系统应用程序保留的,即使用与系统相同的签名密钥签名的应用程序。

这怎么可能?我找到了两种方法来实现这一点。

第一个是在任何制造商公司找一份工作,并签署他们的 NDA,但是,这不是一个很好的解决方案。尤其是使用此密钥实施和签名的应用程序只能在公司的设备上运行...

第二个,更有趣,但我警告你,这并不容易,是制作你自己的 ROM。您必须创建应用程序,将其插入 ROM 的 /system/app/ 目录并重新编译它以使用新系统刷新您的设备。但是有一个问题我还没有回答,是无法识别的ROM签名的问题。 我认为避免此问题的最佳方法是将您的 ROM 签名密钥添加到您将使用的恢复中。

这就是我现在所处的位置,也许您会发现这些研究有用,我希望如此! 如果我为你们找到更多信息,我稍后会回来。再见。

【讨论】:

【参考方案4】:

创建一个 PhoneStateListener 并处理 onSignalStrengthChanged 回调。当您的应用程序初始化时,它应该会给您一个初始通知。这是在 1.x 中。在 2.x 中,有一个开放的issueabout this。

【讨论】:

感谢您的快速答复。如上所述,我已经尝试过,它只给了我当前网络运营商信号的信号强度。我对所有可用运营商及其当前信号强度的完整列表感兴趣。 我从未尝试过这些我会搜索,如果我找到任何答案,我会在这里发布。 whar 的意思是“我对所有可用运营商及其当前信号强度的完整列表感兴趣。”? 完整列表表示手机当前位置的所有可用网络运营商。

以上是关于Android:如何获取所有可用网络运营商的 GSM 信号强度的主要内容,如果未能解决你的问题,请参考以下文章

以编程方式获取网络运营商的时间(android)

如何在Android AIR上获取可用网络列表?

Android:获取附近的所有蜂窝运营商及其信号强度

java 手机网络工具类,用于获取android_id,网络类型,以及SIM卡的唯一识别码,运营商

获取 Android 上的所有总空间和可用空间

赵雅智_android获取本机运营商,手机号部分能获取