web-dev-qa-db-ja.com

Android:利用可能なすべてのネットワークオペレーターのGSM信号強度を取得する方法

私は、私の地域のさまざまなネットワーク事業者の信号強度を確認する小さなアプリに取り組んでいます。私の現在のオペレーター信号は非常に不安定であり、他のGSMオペレーターの強さを調べたいと思います。

これまでのところ、現在のネットワークオペレータのGSM信号強度を取得するためにonSignalStrengthsChangedコールバックでTelephonyManagerとPhoneStateListenerを使用してきましたが、このクラスはSIMカードに接続されたネットワークの信号強度に関する情報のみを提供するようです。

使用可能なすべてのオペレーターのGSM信号強度の測定に興味があります。ネットを検索すると、内部Androidクラスを使用することについてのあいまいなヒントが得られましたが、これに関する良い例はまだ見つかりませんでした。

利用可能なすべてのネットワークオペレータとその信号強度のリストを取得するために私を移動できる答えは評価されます。

41
The Schwartz

これらの引用符とリンクは、独自のソリューションをコーディングするのに役立つ可能性があります。

1.-利用可能なネットワークプロバイダーのリストを取得するには(引用 利用可能なネットワークプロバイダーのリストを取得するには? 完全に):

Androidはオープンソースであるため、ソースを見て、最終的にINetworkQueryServiceと呼ばれるものを見つけました。 Android設定の実装と同じことを行い、このサービスと対話します。NetworkSettings.Javaを介したいくつかのガイダンス:

  • onCreateはNetworkQueryServiceを開始し、バインドします。
  • loadNetworksList()は、ネットワークオペレーターを照会するようにサービスに指示します。
  • INetworkQueryServiceCallbackが評価され、イベント「EVENT_NETWORK_SCAN_COMPLETED」が発生した場合、networksListLoadedが呼び出されて、利用可能なネットワークを反復処理します。

2.- NetworkSetting.Java および INetworkQueryServiceインターフェイス をすばやく読んでも、目標を達成するためのアイデアが得られます。

  • 宣言でサービスを接続します。
/**
 * 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);
        }
    }
}

役に立てば幸いです。面白い挑戦だと思うので、次回は空いた時間に試してみたいと思います。幸運を!

23
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
Sandeep

私には50の評判ポイントがないので、以下は主題に関する私の検索の結果です。

アレハンドロコロラドの解決策は良いようです。しかし問題は、それを達成するために使用されるクラスがAndroidシステムアプリケーション、つまりシステムと同じ署名キーで署名されたアプリのために予約されていることです。

どうしてそれが可能でしょうか?私はこれを達成する2つの方法を見つけました。

最初の方法は、どのメーカーの会社にも仕事を依頼し、NDAに署名することですが、それは本当に良い解決策ではありません。特に、このキーで実装および署名されたアプリは、会社のデバイスでのみ機能します...

2番目の方法は、はるかに楽しいですが、簡単なことではありませんが、独自のROMを作成することを警告します。アプリケーションを作成し、ROM=の/ system/app /ディレクトリに挿入し、新しいシステムでデバイスをフラッシュするために再コンパイルする必要があります。しかし、質問がありますまだ回答されていませんが、認識されないROM署名の問題です。この問題を回避する最善の方法は、Recovery youにROM使用します。

この時点で私はここにいます。これらの研究が役に立つかもしれません。私はあなたたちのためにいくつかの詳細情報を見つけた場合、後で戻ってきます。またね.

1
eduine

phoneStateListenerを作成し、onSignalStrengthChangedコールバックを処理します。アプリが初期化されると、最初の通知が表示されます。これは1.xにあります。 2.xでは、未解決の issue があります。

0