2011-06-28 12 views
7

¿Hay alguna manera de devolver el valor de la configuración de red móvil de Android para "usar solo redes 2G"?Detección de la configuración "Usar solo redes 2G"

La aplicación que se está desarrollando mide la velocidad de Internet en un lugar determinado, pero para que esto sea relevante, debe saber si el usuario está restringiendo deliberadamente Internet móvil a 2G.

He echado un vistazo a ConnectivityManager, pero solo proporciona información sobre la configuración de datos en segundo plano o todas las redes. Iteración a través de las revela que a pesar del entorno siendo activada, HSPA y UMTS vuelven true para isAvailable():

for (NetworkInfo netInfo : cm.getAllNetworkInfo()) { 
    Log.i(TAG, netInfo.getSubtypeName() + ": " + netInfo.isAvailable()); 
} 

La única pista que he encontrado en medio de todo esto es que netInfo.getReason() devuelve "connectionDisabled" en HSPA y UMTS cuando el ajuste está habilitado. El problema es que cuando la configuración está desactivada, esos tipos de red no aparecen necesariamente en la lista. No me parece correcto utilizar una comparación de cadenas específicamente en HSPA y UMTS para "connectionDisabled".

¿Cuál es la forma correcta de abordar esto?

+0

Antes de que nadie intente obtener información significativa del fragmento de arriba, no se moleste; He intentado. Parece que tanto cuando el modo "2G solo" está habilitado o cuando la única señal disponible es GPRS, las redes 3G devuelven "connectionDisabled". En otras palabras, 'getReason()' no proporciona ninguna información útil. –

+0

[La edición de Android # 8753 soluciona esto.] (Http://code.google.com/p/android/issues/detail?id=8753) He intentado con la sugerencia que se describe allí, pero en los dispositivos probados, ' Setting.Secure.getInt() 'siempre devuelve' 1', independientemente de la configuración real o el estado de conectividad. –

+0

Seguimiento: número 8753 sugiere que 'Settings.Secure.NETWORK_PREFERENCE' refleja esta configuración. La configuración no está documentada, pero parece reflejar la preferencia de 'TYPE_WIFI' sobre' TYPE_MOBILE' cuando ambas conexiones están disponibles, y no es lo que estoy buscando. –

Respuesta

5

Para un pequeño subconjunto de dispositivos (en concreto para el LG Optimus 2X velocidad, LG-P990), la respuesta parece ser:

int enabled = Settings.Secure.getInt(getContentResolver(), 
     "preferred_network_mode", -1); 
Log.d("MYAPP", "2G only enabled: " + enabled); 

Cuando el " utilizar sólo redes 2G" se especifica entorno como:

  • 0 indica el ajuste está desactivado
  • 1 indica que la configuración está habilitada
  • -1 indica el ajuste no se ha establecido algunos dispositivos (?)

Cómo descubrí esto? Reuní todos los pares clave/valor de Settings.Secure utilizando la siguiente:

ContentResolver cr = getContentResolver(); 
Cursor cursor = cr.query(Settings.Secure.CONTENT_URI, null, null, null, null); 
if (cursor.moveToFirst()) { 
    while (!cursor.isAfterLast()) { 
     Log.d("MYAPP", "cursor: " 
       + cursor.getString(0) + ", " 
       + cursor.getString(1) + ", " 
       + cursor.getString(2)); 
     cursor.moveToNext(); 
    } 
} 

He comparado los resultados entre la activación y desactivación del ajuste, y por supuesto que tengo:

07-08 00:15: 20.991: DEBUG/MIAPL (13813): cursor: 5154, preferred_network_mode, 1

NO utilice la columna de índice (5154 en el ejemplo anterior), ya que me he dado cuenta que cambia entre alternar el ajuste.

Aunque esto se correlaciona con some documentation for Settings.Secure I found online, este valor no es respetado por todos los teléfonos.

Si su dispositivo devuelve -1, quizás al enumerar los pares de valores clave se revelará la configuración que necesita. Por favor comente si lo encuentra!

+1

Me he dado cuenta de que los dispositivos HTC y Samsung no muestran una opción específica para preferir redes 2G, y en su lugar, permita que el usuario elija entre GSM (2G/2.5G) o WCDMA (3G/4G) o ambos. No he encontrado la configuración para esto todavía. –

0

Por lo que puedo decir, no hay una forma documentada de obtener valor para esa configuración. Pero hay una clase Use2GOnlyCheckBoxPreference que se puede utilizar como ejemplo. Utiliza las clases internas Phone y PhoneFactory para obtener el valor actual de la configuración prefer_2g.

Puede usar las clases Phone y PhoneFactory mediante reflexión. Pero por causa esto no está documentado y es bajo su propio riesgo. Aquí está el código relevante de Use2GOnlyCheckBoxPreference:

import com.android.internal.telephony.Phone; 
import com.android.internal.telephony.PhoneFactory; 

public class Use2GOnlyCheckBoxPreference extends CheckBoxPreference { 

    private Phone mPhone; 
    private MyHandler mHandler; 

    public Use2GOnlyCheckBoxPreference(Context context, AttributeSet attrs, int defStyle) { 
     super(context, attrs, defStyle); 
     mPhone = PhoneFactory.getDefaultPhone(); 
     mHandler = new MyHandler(); 
     mPhone.getPreferredNetworkType(
       mHandler.obtainMessage(MyHandler.MESSAGE_GET_PREFERRED_NETWORK_TYPE)); 
    } 

    private class MyHandler extends Handler { 

     private static final int MESSAGE_GET_PREFERRED_NETWORK_TYPE = 0; 

     @Override 
     public void handleMessage(Message msg) { 
      switch (msg.what) { 
       case MESSAGE_GET_PREFERRED_NETWORK_TYPE: 
        handleGetPreferredNetworkTypeResponse(msg); 
        break; 
      } 
     } 

     private void handleGetPreferredNetworkTypeResponse(Message msg) { 
      AsyncResult ar = (AsyncResult) msg.obj; 

      if (ar.exception == null) { 
       int type = ((int[])ar.result)[0]; 
       Log.i(LOG_TAG, "get preferred network type="+type); 
       setChecked(type == Phone.NT_MODE_GSM_ONLY); 
      } else { 
       // Weird state, disable the setting 
       Log.i(LOG_TAG, "get preferred network type, exception="+ar.exception); 
       setEnabled(false); 
      } 
     } 
    } 
} 
+0

Si entiendo correctamente, para acceder a 'Phone' y' PhoneFactory', necesito trabajar con la fuente del SDK, lo que significa que no funcionará a menos que pueda implementar su propia distribución de Android. [He intentado obtener 'getDefaultPhone()' a través de la reflexión de Java] (http://stackoverflow.com/questions/2143754/can-a-telephony-phone-object-be-instantiated-through-the-sdk) antes , pero el teléfono debe estar rooteado. ¿Me estoy perdiendo un truco para hacer que esto funcione? –

+0

Sí, estás en lo cierto. Resulta que no puede usar 'PhoneFactory' desde una aplicación de terceros. – inazaruk

+0

Esto no funcionará (al menos 5 años después), porque PhoneFactory.makeDefaultPhone() debe llamarse antes que PhoneFactory.getDefaultPhone() – BamsBamx

Cuestiones relacionadas