2011-06-28 14 views
7

Czy istnieje sposób zwrócenia wartości ustawienia sieci komórkowej Androida dla "korzystania tylko z sieci 2G"?Wykrywanie ustawienia "używaj tylko sieci 2G"

Opracowywana aplikacja mierzy szybkość Internetu w określonej lokalizacji, ale aby było to istotne, musi wiedzieć, czy użytkownik celowo ogranicza mobilny internet do 2G.

Przyjrzałem się ConnectivityManager, ale zawiera on tylko informacje o ustawieniach danych tła lub wszystkich sieciach. Iteracja nich wynika, że ​​pomimo ustawienie jest włączone, HSPA i UMTS powrócić true dla isAvailable():

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

jest jedyną wskazówkę znalazłem pośród tego wszystkiego, że netInfo.getReason() powraca „connectionDisabled” na HSPA i UMTS, gdy ustawienie jest włączony. Problem polega na tym, że gdy ustawienie jest wyłączone, te typy sieci niekoniecznie pojawiają się na liście. Nie wydaje mi się, aby użyć porównania łańcuchów specjalnie dla HSPA i UMTS dla "connectionDisabled".

Jaki jest właściwy sposób rozwiązania tego problemu?

+0

Zanim ktokolwiek zacznie próbować uzyskać sensowne informacje z powyższego fragmentu, nie przejmuj się; Próbowałem. Wydaje się, że zarówno gdy włączony jest tryb "tylko 2G" lub gdy jedynym dostępnym sygnałem jest GPRS, sieci 3G zwracają "connectionDisabled". Innymi słowy, 'getReason()' nie dostarcza żadnych użytecznych informacji. –

+0

[Problem z systemem Android nr 8753 rozwiązuje ten problem] (http://code.google.com/p/android/issues/detail?id=8753) Wypróbowałem podaną tutaj sugestię, ale na testowanych urządzeniach: Setting.Secure.getInt() 'zawsze zwraca' 1', niezależnie od aktualnego ustawienia lub stanu łączności. –

+0

Kontynuacja: numer 8753 sugeruje, że ustawienie "Settings.Secure.NETWORK_PREFERENCE" odzwierciedla to ustawienie. To ustawienie jest nieudokumentowane, ale wydaje się odzwierciedlać preferencję typu "TYPE_WIFI" w stosunku do "TYPE_MOBILE", gdy oba połączenia są dostępne i nie jest tym, czego szukam. –

Odpowiedz

5

Dla małego podzbioru urządzeń (specjalnie dla LG Optimus 2X Speed, LG-P990), odpowiedź wydaje się być:

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

gdzie " Używaj tylko sieci 2G”ustawienie jest określona jako:

  • 0 oznacza ustawienie jest wyłączone
  • 1 wskazuje, że ustawienie jest włączone
  • -1 wskazuje ustawienie nie jest ustawiony (kilka urządzeń?)

Jak odkryłem to? Zebrałem wszystkie pary klucz/wartość z Settings.Secure przy użyciu następujących:

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(); 
    } 
} 

ja porównaniu wyników między włączanie i wyłączanie ustawienia, i na pewno wystarczy mam:

07-08 00:15: 20,991: DEBUG/MojaApl (13813): kursor: 5154, preferred_network_mode, 1

nie należy używać kolumny indeksu (5154 w powyższym przykładzie), a ja zauważyłem, że zmienia się między przełączania ustawień.

Chociaż jest to skorelowane z some documentation for Settings.Secure I found online, ta wartość nie jest przestrzegana przez wszystkie telefony.

Jeśli urządzenie zwróci -1, być może lista par klucz-wartość ujawni, które ustawienie jest potrzebne. Proszę o komentarz, jeśli go spotkasz!

+1

Zauważyłem, że urządzenia HTC i Samsung nie wyświetlają konkretnej opcji dla preferowania sieci 2G, i zamiast tego pozwalają użytkownikowi wybrać pomiędzy GSM (2G/2.5G) lub WCDMA (3G/4G) lub oba. Jeszcze nie znalazłem tego ustawienia. –

0

O ile wiem, nie ma udokumentowanego sposobu uzyskania wartości dla tego ustawienia. Ale istnieje klasa Use2GOnlyCheckBoxPreference, którą można wykorzystać jako przykład. Używa klas wewnętrznych Phone i PhoneFactory do uzyskania bieżącej wartości ustawienia prefer_2g.

Za pomocą refleksji można używać klas Phone i PhoneFactory. Ale z tego powodu jest to nieudokumentowane i odbywa się na własne ryzyko. Oto odpowiedni kod z 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

Jeśli dobrze rozumiem, aby uzyskać dostęp do 'Telefon' i' PhoneFactory', muszę pracować ze źródłem SDK, co oznacza, że ​​nie będzie działać, chyba że możesz wdrożyć własną dystrybucję Androida. [Próbowałem uzyskać 'getDefaultPhone()' poprzez odbicie Java] (http://stackoverflow.com/questions/2143754/can-a-telephony-phone-object-be-instantiated-through-the-sdk) before , ale telefon musi być zrootowany. Czy brakuje mi sztuczki, żeby to zadziałało? –

+0

Tak, masz rację. Okazuje się, że nie można używać 'PhoneFactory' z aplikacji innej firmy. – inazaruk

+0

To przyzwyczajenie (co najmniej 5 lat później), ponieważ PhoneFactory.makeDefaultPhone() musi być wywoływana wcześniej niż PhoneFactory.getDefaultPhone() – BamsBamx

Powiązane problemy