44

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

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

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

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

4

4 回答 4

23

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

1.- 获取可用网络提供商列表(完整引用如何获取可用网络提供商列表?):

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

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

2.- 即使快速阅读NetworkSetting.javaINetworkQueryService 接口,也能让我们了解实现您的目标。

  • 在声明中连接服务。
/**
 * 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”,则将调用 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);
        }
    }
}

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

于 2013-05-26T00:21:52.407 回答
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);
    }

};
于 2012-05-05T07:39:04.933 回答
1

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

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

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

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

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

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

于 2015-01-30T15:52:01.253 回答
0

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

于 2012-05-04T18:48:56.840 回答