2016/11/24

Android の Wi-Fi Access Point を表す ScanResult, WifiConfiguration, WifiInfo の違い


> この記事は [Android の Wi-Fi 実装に関する情報のまとめ](http://kokufu.blogspot.jp/2016/10/android-wi-fi_19.html) の一部として書かれました

Android の Wi-Fi Access Point を表す情報は複数あります。
具体的には以下の4種類。

- [android.net.wifi.ScanResult](https://developer.android.com/reference/android/net/wifi/ScanResult.html)
- [android.net.wifi.WifiConfiguration](https://developer.android.com/reference/android/net/wifi/WifiConfiguration.html)
- [android.net.wifi.WifiInfo](https://developer.android.com/reference/android/net/wifi/WifiInfo.html)
- [android.net.NetworkInfo](https://developer.android.com/reference/android/net/NetworkInfo.html)

これらは同じような情報を持ちつつ用途が異なるので、ここで整理しておこうと思います。
(ただ、NetworkInfo は少し特殊なので、あえてタイトルには入れませんでした。)



### ScanResult
名前の如く、周辺の Access Point をスキャンした結果です。
周波数や電波強度等、ハードウェアよりの情報が多く含まれます。

```java
// Activity 等の Context の中で
WifiManager wm = (WifiManager) getSystemService(WIFI_SERVICE);
List scanResults = wm.getScanResults();
``` 

`ScanResult` の主なデータは以下です。
```
SSID : my-ssid
wifiSsid : my-ssid
BSSID : aa:bb:cc:dd:ee:ff
capabilities : [WPA-PSK-CCMP][WPA2-PSK-CCMP][WPS][ESS]
frequency : 2437
level : -93
timestamp : 713047320153
```

> 参考
>
> [穀風: Android で付近の Wi-Fi Access Point を検索して一覧を取得する](https://kokufu.blogspot.jp/2016/11/android-wi-fi-access-point.html)


### WifiConfiguration
保存済み、もしくはこれから新規追加する Access Point の情報です。
接続に使用する情報のため、パスワード等を持っているのが特徴です。

新規追加の際は自分で情報をセットする必要があります。
具体的な方法は後述します。

```java
// Activity 等の Context の中で
WifiManager wm = (WifiManager) getSystemService(WIFI_SERVICE);

// 保存済みの取得
List wifiConfigurations = wm.getConfiguredNetworks();


// 新規追加
WifiConfiguration newWifiConfiguration = new WifiConfiguration();
// ここで接続に必要な情報をセットする
wm.addNetwork(newWifiConfiguration);
```

`WifiConfiguration` の主なデータは以下です。
```
SSID : my-ssid
BSSID : aa:bb:cc:dd:ee:ff
networkId : 1
status : CURRENT or ENABLED or DISABLED
その他、暗号化に関する情報、パスワード等
```

> 参考
>
> [穀風: Android で登録済みの Wi-Fi Access Point 一覧を取得する](http://kokufu.blogspot.jp/2016/10/android-wi-fi-access-point.html)
>
> [穀風: Android で Wi-Fi ScanResult を WifiConfiguration に変換する方法](http://kokufu.blogspot.jp/2016/11/android-wi-fi-scanresult.html)

### WifiInfo
現在接続している Access Point の情報です。
接続状態を持つだけでなく、Scan Result のようなハードウェアよりの情報も持っています。

```java
// Activity 等の Context 内で
WifiManager wm = (WifiManager) getSystemService(WIFI_SERVICE);
WifiInfo wifiInfo = wm.getConnectionInfo();
```

`WifiInfo` の主なデータは以下です。
```
SSID : my-ssid
BSSID : aa:bb:cc:dd:ee:ff
NetworkId : 1
IpAddress : 192.168.0.1
MAC Address : 00:11:22:33:44
Frequency : 2437
RSSI : 
LinkSpeed : 
SupplicantState :
```

> 参考
>
> [穀風: Android で 接続している Wi-Fi Access Point の情報を取得する](http://kokufu.blogspot.jp/2016/11/android-access-point.html)
>
> [穀風: Android で Wi-Fi の接続状態を確認する](http://kokufu.blogspot.jp/2016/10/android-wi-fi-access-point_27.html)


### NetworkInfo
少々毛色は違いますが、[android.net.NetworkInfo](https://developer.android.com/reference/android/net/NetworkInfo.html) も Wi-Fi の状態を表します。

実際、AOSP の内部では [com.android.settingslib.wifi.AccessPoint](https://android.googlesource.com/platform/frameworks/base/+/android-7.0.0_r19/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java) というクラス普通には Android Framework の内部でしか使用できませんを用意し、Access Point を統一的に扱えるようにしていますが、NetworkInfo もストアされる情報に含まれています。

```java
// Activity 等の Context 内で
ConnectivityManager connectivityManager =
        (ConnectivityManager) getSystemService(CONNECTIVITY_SERVICE);

NetworkInfo networkInfo = connectivityManager.getActiveNetworkInfo();
if (networkInfo != null && networkInfo.getType() == ConnectivityManager.TYPE_WIFI) {
        NetworkInfo.State networkState = networkInfo.getState();
}
```

Access Point の情報という意味では、このクラスの State を参照することが多いでしょう。

> 参考
>
> [穀風: Android で Wi-Fi の接続状態を確認する](http://kokufu.blogspot.jp/2016/10/android-wi-fi-access-point_27.html)


### WifiConfiguration の新規作成
`ScanResult`, `WifiInfo` はデータを利用するだけですが、 `WifiConfiguration` は自分で作成しなければなりません。
変換ユーティリティ等が用意されていれば良いのですが、少なくとも AOSP で公式に用意はしていないようです。

Android Framework の中では [com.android.settings.wifi.WifiConfigController](https://android.googlesource.com/platform/packages/apps/Settings/+/android-7.0.0_r19/src/com/android/settings/wifi/WifiConfigController.java) の中に `getConfig()` というメソッドがあり、この中で他の情報からの変換をおこなっています。

このあたりの実装が、もう少し汎用的で public だと良かったのですが、残念ながら外から普通に使用することは出来ません。

さほど複雑なことはしていないので、自力で実装するのが良いでしょう。
具体的には以下を参考にしてください。

> 参考
>
> [穀風: Android で Wi-Fi ScanResult を WifiConfiguration に変換する方法](http://kokufu.blogspot.jp/2016/11/android-wi-fi-scanresult.html)

0 件のコメント: