2016-09-24 133 views
7

我有以下BroadcastRecevier:使用BroadcastReceiver獲取Android中斷開的WiFi網絡的SSID?

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

它接收的網絡連接和斷開事件。

當它連接到WiFi網絡時,我能夠輕鬆獲得網絡的SSID。

但我希望能夠在網絡斷開連接時獲得WiFi網絡的SSID(無需存儲先前連接的網絡,然後將它們與之匹配等)。這可能嗎?

登錄時的WiFi連接:

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 

日誌時,無線網絡斷開連接(注未知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 

我想這個信息的原因是我希望能夠跟蹤用戶在每個網絡上的WiFi使用情況 - 連接和斷開時間。

沒有斷開連接的網絡的SSID,我能想到做到這一點的唯一方法是這樣的:

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 

然而,上述做法感到片狀,例如,如果什麼某種原因,無線網絡斷線事件被遺漏等

回答

0

這是不可能的。當調用onReceive時,連接已經丟失,當前信息顯示沒有連接。

另請注意,在您收到斷開連接信息後,您可能會再次致電onRecieve。從spec

CONNECTIVITY_ACTION

[...]

如果是這樣,這是從斷開網絡故障切換的結果的連接,那麼FAILOVER_CONNECTION布爾額外設置爲true。

對於連接丟失,如果連接管理器試圖連接(或已經連接)到另一個網絡,新網絡的NetworkInfo也作爲額外的傳遞。這使得廣播的任何接收者都知道他們不一定告訴用戶沒有數據通信是可能的。相反,接收器應該很快就會有另一個廣播,表明故障轉移嘗試成功(並且仍然存在總體數據連接),或者故障轉移嘗試失敗,這意味着所有連接都已丟失。

[...]

1

你絕對可以做到這一點,通過使用比你嘗試過什麼不同的方法。

  1. 您需要註冊一個收聽WifiManager.SCAN_RESULTS_AVAILABLE_ACTION的接收器。
  2. 無論何時您進行無線掃描,該接收器都將被調用掃描結果,在這些結果中,您將擁有任何可用的路由器ssid(不管其連接狀態如何)
  3. 然後,您需要匹配斷開連接您使用掃描列表在代碼中找到的wifi。

添加此權限,您的清單,不要忘記,如果你使用的棉花糖,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" /> 

這是MainActivty,結果在廣播接收器接收。

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

我會建議使用這樣的事情。然而,這不能保證它是一個斷開,先前已連接的是現在顯示的可用wifis只有一個。 –

+0

你是對的,但你收到這個清單後,你可以斷開無線網絡比較每個項目的BSSID。它可能不是在任何時候都找到它,但大部分會的。 – Dus

0

一旦連接丟失,就會丟失。

,你能做到這一點的唯一方法,就是在當時記錄它,或存儲它使用類似共享偏好,這樣你就可以再拿到最後連接的無線網絡的名稱。

使用suggestion here並不能保證你看到最後連接的wifi,因爲不能保證wifi仍然可用,特別是當連接丟失時。