使用BroadcastReceiver获取Android中已断开连接的WiFi网络的SSID?

时间:2016-09-24 16:25:37

标签: android android-wifi ssid

我有以下BroadcastRecevier:

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

WiFi断开连接时记录(注意未知的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

然而,上述方法感觉不稳定,例如,如果由于某种原因错过了WiFi断开连接事件等等

2 个答案:

答案 0 :(得分:1)

你可以通过使用与你尝试过的方法不同的方法来做到这一点。

  1. 您需要注册一个收听WifiManager.SCAN_RESULTS_AVAILABLE_ACTION的接收器。
  2. 每当您进行无线扫描时,将使用扫描结果调用此接收器,在这些结果中,您将拥有任何路由器可用的ssid(无论其连接状态如何)
  3. 然后,您需要将代码中找到的断开连接的wifi与扫描列表进行匹配。
  4. 将此权限添加到您的清单中,如果您使用的是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" />
    

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

答案 1 :(得分:0)

这是不可能的。当调用onReceive时,连接已经丢失,当前信息显示没有连接。

另请注意,在收到断开连接信息后,您可能会再次拨打onRecieve。来自spec

  

CONNECTIVITY_ACTION

     

[...]

     

如果这是从断开连接的网络故障转移的结果,则FAILOVER_CONNECTION布尔额外设置为true。

     

如果连接丢失,如果连接管理器尝试连接(或已连接)到另一个网络,则新网络的NetworkInfo也会作为额外网络传递。这使得广播的任何接收者都知道他们不一定会告诉用户没有数据流量是可能的。相反,接收方应该很快就会看到另一个广播,指示故障转移尝试成功(因此仍然存在整体数据连接),或者故障转移尝试失败,这意味着所有连接都已丢失。

     

[...]