2016-09-24 38 views
7

Mam następujący BroadcastRecevier:Uzyskaj identyfikator SSID odłączonej sieci Wi-Fi w systemie Android za pomocą BroadcastReceiver?

public class WiFiConnectionEventsReceiver extends BroadcastReceiver { 

    private static final String TAG = WiFiConnectionEventsReceiver.class.getSimpleName(); 

    @Override 
    public void onReceive(Context context, @NonNull Intent intent) { 
     Log.v(TAG, "action: " + intent.getAction()); 
     Log.v(TAG, "component: " + intent.getComponent()); 
     Bundle extras = intent.getExtras(); 
     if (extras != null) { 
      for (String key : extras.keySet()) { 
       Log.v(TAG, "key [" + key + "]: " + 
         extras.get(key)); 
      } 
     } else { 
      Log.v(TAG, "no extras"); 
     } 

     ConnectivityManager conMan = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); 
     NetworkInfo netInfo = conMan.getActiveNetworkInfo(); 
     if (netInfo != null && netInfo.getType() == ConnectivityManager.TYPE_WIFI) { 
      Log.d("NetworkInfo", "Have Wifi Connection"); 
      Log.d("NetworkInfo", netInfo.getExtraInfo()); 
      Log.d("NetworkInfo", netInfo.getTypeName()); 
     } 
     else { 
      Log.d("NetworkInfo", "Don't have Wifi Connection"); 
      Log.d("NetworkInfo", netInfo.getExtraInfo()); 
      Log.d("NetworkInfo", netInfo.getTypeName()); 
     } 

     WifiManager wifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE); 
     Log.d("WifiInfo", wifiManager.getConnectionInfo().toString()); 
    } 
} 

odbiera połączenie sieciowe i zdarzenia rozłączenia.

Po podłączeniu do sieci Wi-Fi mogę łatwo uzyskać identyfikator SSID sieci.

Ale chcę mieć możliwość uzyskania identyfikatora SSID sieci Wi-Fi również wtedy, gdy sieć jest rozłączona (bez konieczności przechowywania wcześniej podłączonych sieci, a następnie dopasowywania ich w ten sposób itd.). czy to możliwe?

Dzienniki kiedy WiFi łączy:

V/WiFiConnectionEventsReceiver: action: android.net.conn.CONNECTIVITY_CHANGE 
V/WiFiConnectionEventsReceiver: component: ComponentInfo{com.example.test/com.example.test.WiFiConnectionEventsReceiver} 
V/WiFiConnectionEventsReceiver: key [networkInfo]: [type: WIFI[], state: CONNECTED/CONNECTED, reason: (unspecified), extra: "SKY123”, roaming: false, failover: false, isAvailable: true] 
V/WiFiConnectionEventsReceiver: key [networkType]: 1 
V/WiFiConnectionEventsReceiver: key [inetCondition]: 100 
V/WiFiConnectionEventsReceiver: key [extraInfo]: "SKY123” 
D/NetworkInfo: Have Wifi Connection 
D/NetworkInfo: "SKY123” 
D/NetworkInfo: WIFI 
D/WifiInfo: SSID: SKY123, BSSID: 10:40:03:ad:6x:c9, MAC: 02:00:00:00:00:00, Supplicant state: COMPLETED, RSSI: -79, Link speed: 43Mbps, Frequency: 2412MHz, Net ID: 1, Metered hint: false, score: 60 

Dzienniki gdy rozłącza WiFi (uwaga nieznany SSID):

V/WiFiConnectionEventsReceiver: action: android.net.conn.CONNECTIVITY_CHANGE 
V/WiFiConnectionEventsReceiver: component: ComponentInfo{com.example.test/com.example.test.WiFiConnectionEventsReceiver} 
V/WiFiConnectionEventsReceiver: key [networkInfo]: [type: WIFI[], state: DISCONNECTED/DISCONNECTED, reason: (unspecified), extra: <unknown ssid>, roaming: false, failover: false, isAvailable: true] 
V/WiFiConnectionEventsReceiver: key [networkType]: 1 
V/WiFiConnectionEventsReceiver: key [inetCondition]: 0 
V/WiFiConnectionEventsReceiver: key [extraInfo]: <unknown ssid> 
V/WiFiConnectionEventsReceiver: key [noConnectivity]: true 
D/NetworkInfo: Don't have Wifi Connection 
D/NetworkInfo: id 
D/NetworkInfo: MOBILE 
D/WifiInfo: SSID: <unknown ssid>, BSSID: <none>, MAC: 02:00:00:00:00:00, Supplicant state: COMPLETED, RSSI: -127, Link speed: -1Mbps, Frequency: -1MHz, Net ID: -1, Metered hint: false, score: 0 

Powodem Chciałbym to info jest chcę, aby móc śledzić wykorzystanie sieci Wi-Fi przez użytkownika w każdej sieci - czasy połączenia i rozłączenia.

Bez SSID sieci odłączonym, jedynym sposobem można myślę, aby to zrobić jest coś jak:

if (WiFi network ABC disconnected) 
    if (if previous stored connection for WiFi network ABC has no disconnection time) 
     set WiFI network ABC disconnection time to now 

Jednak powyższe podejście czuje łuszcząca się, na przykład, co zrobić, jeśli z jakiegoś powodu WiFi Brakuje zdarzenia odłączenia itp.

Odpowiedz

0

To nie jest możliwe. Po wywołaniu onReceive połączenie jest już utracone, a bieżące informacje pokazują, że nie ma połączenia.

Pamiętaj również, że możesz otrzymać kolejne połączenie z numerem onRecieve zaraz po otrzymaniu informacji o rozłączeniu. Od spec:

CONNECTIVITY_ACTION

[...]

Jeśli jest to połączenie, które było wynikiem braku nad z odłączonym sieci, wówczas FAILOVER_CONNECTION logiczna dodatkowo jest ustawiona na wartość true.

W przypadku utraty łączności, jeśli menedżer połączeń próbuje się połączyć (lub jest już podłączony) do innej sieci, NetworkInfo dla nowej sieci jest również przekazywana jako dodatkowa. Dzięki temu każdy odbiorca transmisji wie, że nie powinien koniecznie mówić użytkownikowi, że ruch danych nie będzie możliwy. Zamiast tego odbiornik powinien wkrótce oczekiwać kolejnej emisji, co oznacza, że ​​próba przełączenia powiodła się (i nadal istnieje ogólna łączność danych) lub że próba przełączenia awaryjnego nie powiodła się, co oznacza, że ​​utracono wszystkie połączenia.

[...]

1

Można na pewno to zrobić, używając innego podejścia niż to, co próbowałem.

  1. Musisz zarejestrować odbiornik, który słucha WifiManager.SCAN_RESULTS_AVAILABLE_ACTION.
  2. Za każdym razem, gdy wykonujesz skanowanie wifi, odbiornik zostanie wywołany z wynikami skanowania, w tych wynikach będzie dostępny dowolny router ssid (niezależnie od statusu połączenia)
  3. Musisz wtedy dopasować rozłączony Wi-Fi znalezione w kodzie z listą skanowania.

dodać to uprawnienia do manifestu, i nie zapomnij, jeśli używasz marshmallow, request permission for the location.

<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /> 
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" /> 
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /> 

To MainActivty wyniki są odbierane w odbiorniku transmisji.

public class MainActivity extends AppCompatActivity { 

    private WifiManager mWifiManager; 
    private List<ScanResult> mScanResults; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 

     mWifiManager = (WifiManager) getApplicationContext().getSystemService(Context.WIFI_SERVICE); 
     if (mWifiManager.isWifiEnabled() || 
       (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2 && mWifiManager.isScanAlwaysAvailable())) { 
      registerReceiver(mReceiver, new IntentFilter(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION)); 
     } 
    } 

    private BroadcastReceiver mReceiver = new BroadcastReceiver() { 

     @Override 
     public void onReceive(Context context, Intent intent) { 
      String action = intent.getAction(); 
      if (action.equalsIgnoreCase(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION)) { 
       mScanResults = mWifiManager.getScanResults(); 
       for (ScanResult result : mScanResults) { 
        Log.i(getClass().getSimpleName(), "wifi Ssid : " + result.SSID); 
       } 
      } 
     } 
    }; 

    @Override 
    protected void onDestroy() { 
     try { 
      unregisterReceiver(mReceiver); 
     } catch (Exception e) { 
      e.printStackTrace(); 
     } 
     super.onDestroy(); 
    } 
} 
+0

Proponuję użyć czegoś takiego. Nie jest to jednak gwarancja, że ​​jest to połączenie niepołączone, tylko jedno, które zostało wcześniej połączone, a które jest teraz widoczne na dostępnych żonach. –

+0

Masz rację, ale po otrzymaniu tej listy możesz porównać bssid każdego przedmiotu z odłączonym wifi. Może go nie znaleźć przez cały czas, ale w dużej mierze będzie. – Dus

0

Po utracie połączenia jest ono utracone.

Jedynym sposobem, w jaki można to zrobić, jest zalogowanie się w tym czasie lub zapisanie go przy użyciu takich samych preferencji, aby można było wtedy uzyskać nazwę ostatnio podłączonego wifi.

Korzystanie z suggestion here nie gwarantuje, że widzisz ostatnio podłączone wifi, ponieważ nie ma gwarancji, że wifi jest nadal dostępne, szczególnie w przypadku utraty połączenia.