【问题标题】:Get SSID of disconnected WiFi network in Android using BroadcastReceiver?使用 BroadcastReceiver 在 Android 中获取断开连接的 WiFi 网络的 SSID?
【发布时间】:2017-02-02 08:39:33
【问题描述】:

我有以下广播接收器:

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 断开事件等怎么办

【问题讨论】:

    标签: android android-wifi ssid


    【解决方案1】:

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

    1. 您需要注册一个接收WifiManager.SCAN_RESULTS_AVAILABLE_ACTION 的接收器。
    2. 每当您进行 wifi 扫描时,将使用扫描结果调用此接收器,在这些结果中,您将拥有任何可用的路由器 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();
        }
    }
    

    【讨论】:

    • 你是对的,但是你收到这个列表后,可以将每个项目的bssid与断开的wifi进行比较。它可能不会在任何时候都找到它,但在很大程度上它会找到它。
    【解决方案2】:

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

    另请注意,在您收到断开连接信息后,您可能会立即接到另一个电话 onRecieve。来自spec

    CONNECTIVITY_ACTION

    [...]

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

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

    [...]

    【讨论】:

      猜你喜欢
      • 2014-05-27
      • 2020-02-20
      • 2012-05-15
      • 2011-12-03
      • 1970-01-01
      • 1970-01-01
      • 2014-02-18
      • 2021-02-05
      • 2021-02-16
      相关资源
      最近更新 更多