web-dev-qa-db-fra.com

Android: comment obtenir la puissance du signal GSM pour tous les opérateurs de réseau disponibles

Je travaille sur une petite application pour vérifier la puissance du signal de divers opérateurs de réseau dans ma région. Le signal de mon opérateur actuel est assez instable et je veux examiner la force des autres opérateurs GSM.

Sofar J'ai utilisé le TelephonyManager et un PhoneStateListener avec le rappel onSignalStrengthsChanged pour obtenir la force du signal GSM de l'opérateur de réseau actuel, mais il semble que cette classe ne me donne que des informations sur la force du signal du réseau connecté à ma carte SIM .

Je suis intéressé par la mesure de la force du signal GSM de TOUS les opérateurs disponibles. La recherche sur le net a donné de vagues indications sur l'utilisation des classes internes Android, mais je n'ai pas encore trouvé de bons exemples à ce sujet.

Toute réponse qui peut m'amener à obtenir une liste de tous les opérateurs de réseau disponibles et la force de leur signal est appréciée.

41
The Schwartz

Peut-être que ces citations et ces liens peuvent vous aider à coder votre propre solution:

1.- Pour obtenir une liste des fournisseurs de réseau disponibles (en citant Comment obtenir une liste des fournisseurs de réseau disponibles? en entier):

Depuis Android est open source, j'ai jeté un œil aux sources et j'ai finalement trouvé quelque chose appelé INetworkQueryService . Je suppose que vous pouvez faites la même chose que l'implémentation des paramètres Android Android et interagissez avec ce service. Quelques conseils via NetworkSettings.Java:

  • onCreate démarre le NetworkQueryService et le lie.
  • loadNetworksList () indique au service de rechercher des opérateurs de réseau.
  • INetworkQueryServiceCallback est évalué et si l'événement "EVENT_NETWORK_SCAN_COMPLETED" a été déclenché, networksListLoaded sera appelé pour itérer sur les réseaux disponibles.

2.- Même une lecture rapide de NetworkSetting.Java et interface INetworkQueryService , nous donne une idée pour atteindre votre objectif.

  • Connectez le service en déclaration.
/**
 * 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 démarre le NetworkQueryService et le lie.
Intent intent = new Intent(this, NetworkQueryService.class);
...
startService (intent);
bindService (new Intent(this, NetworkQueryService.class), mNetworkQueryServiceConnection,
                        Context.BIND_AUTO_CREATE);
  • loadNetworksList () indique au service de rechercher des opérateurs de réseau.
private void loadNetworksList() {
...    
// delegate query request to the service.
try {
    mNetworkQueryService.startNetworkQuery(mCallback);
} catch (RemoteException e) {
}

displayEmptyNetworkList(false); 
}
  • INetworkQueryServiceCallback est évalué:
/**
 * 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();
    }
};
  • Si l'événement "EVENT_NETWORK_SCAN_COMPLETED" a été déclenché, networksListLoaded sera appelé pour itérer sur les réseaux disponibles.
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);
        }
    }
}

J'espère que ça aide. Je pense que c'est un défi intéressant alors je vais peut-être essayer la prochaine fois que j'ai du temps libre. Bonne chance!

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

Comme je n'ai pas 50 points de réputation, voici le résultat de mes recherches sur le sujet:

La solution d'Alejandro Colorado semble être la bonne. Mais le problème est que les classes utilisées pour y parvenir sont réservées aux applications système Android, c'est-à-dire aux applications qui sont signées avec la même clé de signature que le système.

Comment serais-ce t'il possible? J'ai trouvé deux façons d'y parvenir.

La première consiste à demander un emploi à n'importe quelle entreprise de fabrication et à signer leur NDA, mais eh, ce n'est pas vraiment une bonne solution. D'autant plus que l'application implémentée et signée avec cette clé ne fonctionnera que sur les appareils de l'entreprise ...

Le second, beaucoup plus agréable, mais je vous préviens, ça ne va pas être facile, c'est de faire votre propre ROM. Vous devrez créer votre application, l'insérer dans le répertoire/system/app/de votre ROM et la recompiler pour flasher votre appareil avec votre nouveau système. Mais il y a une question que j'ai pas encore répondu, est le problème de la signature non reconnue ROM. Je pense que la meilleure façon d'éviter ce problème est d'ajouter votre ROM clé de signature dans la récupération que vous vais utiliser.

Voilà où j'en suis à ce stade, peut-être pourriez-vous trouver ces recherches utiles, je l'espère! Je reviendrai plus tard si je trouve plus d'informations pour vous. Au revoir.

1
eduine

créez un PhoneStateListener et gérez le rappel onSignalStrengthChanged. Lorsque votre application est initialisée, elle devrait vous envoyer une notification initiale. C'est en 1.x. dans 2.x, il y a un problème ouvert à ce sujet.

0