2016/12/03

Android で Wi-Fi Access Point との接続状態変化をイベントとして取得する

2016/12/02

Android で Wi-Fi Access Point との接続を切断する


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

### 接続切断の方法は2種類ある
Wi-Fi Access Point との接続を切断するには `WifiManager.disconnect()` もしくは  `WifiManager.disableNetwork()` を使用します。

`WifiManager.disconnect()` を使用した場合、状態は "Saved"日本語だと「保存済み」 になります。
`WifiManager.disableNetwork()` を使用した場合、状態は "Disabled"日本語だと「無効」になります。
"Disabled" といっても、登録してあるパスワード等が消えてしまったわけではありません。 設定画面から "Connect" をクリックしたり、 `WifiManager.enableNetwork()` を使用することでパスワード入力無しに再接続することが可能です。 ### 違いはあるようで無い では何が違うのかというと、**自動で** 再接続するかどうかのようです。 "Saved" の場合、何らかのタイミングで OS が再接続を試みる可能性がありますが、"Disabled" の場合はユーザーもしくは、`android.permission.CHANGE_WIFI_STATE` パーミッションを持ったアプリが意思を持って接続しない限り再接続されません。 ただし、後述のようにデバイスを再起動した場合は "Disabled" でも再接続されるので、完全に無効化するわけではないようです。 > 参考 > > [Android - What´s the difference between WifiManager disableNetwork() and disconnect() - Stack Overflow](http://stackoverflow.com/questions/30094055/android-what%C2%B4s-the-difference-between-wifimanager-disablenetwork-and-disconn) また、"Saved" もどのタイミングで再接続されるのかは不定のようです。 上記のサイトでは `WifiManager.disconnect()` を呼んでから数秒後に再接続されたとありますが、 私の Nexus 7 (2012)Android 4.4.4 では 一度 "Saved" 状態になると自動で再接続はされませんでした一度 Wi-Fi の圏外に出る等いろいろやってみたのですが。 ただし、デバイスを再起動すると接続されます。これは "Disabled" でも同じ。 結局、私の Nexus 7 では、これらの違いがよくわかりませんでした。 コードで Wi-Fi の接続を制御したい場合、勝手に再接続されることはあまり想定しないと思われるので、 `WifiManager.disableNetwork()` を使っておくのが無難でしょう。 ### コード1 `WifiManager.disconnect()` を使用する方法です。 ```java // Activity 等の Context 内で WifiManager wm = (WifiManager) getSystemService(WIFI_SERVICE); boolean succeeded = wm.disconnect(); ``` ### コード2 `WifiManager.disableNetwork()` を使用する方法です。 引数として Network ID が必要ですので、 `WifiManager.getConnectionInfo()` を使用して接続している Access Point の情報を取得します。 ```java // Activity 等の Context 内で WifiManager wm = (WifiManager) getSystemService(WIFI_SERVICE); WifiInfo wifiInfo = wm.getConnectionInfo(); boolean succeeded = wm.disableNetwork(wifiInfo.getNetworkId()); ``` 未接続状態でも `wifiInfo` は `null` にならず、Network ID が `-1` のインスタンスが返ってきます。 > 参考 > > [穀風: Android で 接続している Wi-Fi Access Point の情報を取得する](https://kokufu.blogspot.jp/2016/11/android-access-point.html) ### パーミッション `WifiManager.disconnect()` や `WifiManager.disableNetwork()` を実行するには `android.permission.CHANGE_WIFI_STATE` パーミッションを AndroidManifest.xml で設定する必要があります。 ```xml ``` また、 `WifiManager.getConnectionInfo()` を実行するには `android.permission.ACCESS_WIFI_STATE` パーミッションを AndroidManifest.xml で設定する必要があります。 ```xml ```
2016/11/30

Android で Wi-Fi Access Point に接続する


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

### コード
Wi-Fi Access Point に接続するには `WifiManager.enableNetwork()` を使用します。

既に登録済みの Access Point に接続する場合は、`WifiManager.getConfiguredNetworks()` を使って `WifiConfiguration` を取得します。

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

// targetSsid が既に登録済みの場合
WifiConfiguration targetConfig = null;
for (WifiConfiguration config : wm.getConfiguredNetworks()) {
    if (config.SSID.equals('"' + targetSsid + '"')) { // Quote を取る方向の方が正しいかもしれないが、わかりやすさ重視で
        targetConfig = config;
        break;
    }
}
if (targetConfig != null) {
    wm.enableNetwork(targetConfig.networkId, true);
} else {
    // 登録されてなかった
}
```

まだ登録されていない Access Point の場合は `WifiManager.addNetwork()` で登録してから使用します。

> 参考
>
> [穀風: Android で Wi-Fi Access Point を登録する](http://kokufu.blogspot.jp/2016/11/android-wi-fi-access-point_26.html)

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

// targetSsid が未登録の場合は新規登録を先に行う
// 以下は WPA の例
WifiConfiguration targetConfig = new WifiConfiguration();
targetConfig.allowedKeyManagement.set(KeyMgmt.WPA_PSK);
targetConfig.SSID = '"' + targetSsid + '"';
targetConfig.preSharedKey = '"' + password + '"';

// 以下を実行しても targetConfig.networkId は更新されないので
// 返り値の networkId を使う
int networkId = wm.addNetwork(targetConfig);

if (networkId != -1) {
    wm.enableNetwork(networkId, true);
} else {
    // 登録失敗
}
```


### パーミッション
`WifiManager.enableNetwork()` を実行するには `android.permission.CHANGE_WIFI_STATE` パーミッションを AndroidManifest.xml で設定する必要があります。

```xml
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
```

また、 `WifiManager.getConfiguredNetworks()` を実行するには `android.permission.ACCESS_WIFI_STATE` パーミッションを AndroidManifest.xml で設定する必要があります。

```xml
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
```

2016/11/26

Android で登録済みの Wi-Fi Access Point を登録解除する

Android で Wi-Fi Access Point を登録する


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

Wi-Fi Access Point を登録する方法です。

2016/11/25

Android で Wi-Fi ScanResult を WifiConfiguration に変換する方法

2016/11/24

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

2016/11/09

Android で付近の Wi-Fi Access Point を検索して一覧を取得する

2016/11/08

Android 6.0 以降で WifiManager.getScanResults() を普通に実行しても結果が空のリストになってしまう

2016/11/07

Android で 接続している Wi-Fi Access Point の情報を取得する


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

現在接続している Wi-Fi Access Point の情報を取得する方法です。

Access Point の情報は `WifiInfo` にまとまっているので、これを取得します。

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


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

WifiInfo wifiInfo = wm.getConnectionInfo();

// 取得できる情報
// SSID
// BSSID
// Hidden SSID
// Ip Address
// MAC Address
// Frequency 
// RSSI
// Link Speed
// Network ID
// Supplicant State
```

接続していない場合、 `null` が返ってくる**のではなく**、`SupplicantState` が `INACTIVE` なインスタンスが返ってきます。


### パーミッション
このコードを実行するには `android.permission.ACCESS_WIFI_STATE` パーミッションを AndroidManifest.xml で設定する必要があります。

```xml

```

2016/10/27

Android で Wi-Fi の接続状態を確認する

2016/10/26

Android で登録済みの Wi-Fi Access Point 一覧を取得する

2016/10/20

Android で Wi-Fi 機能の有効・無効の変化をイベントとして取得する

2016/10/19

Android で Wi-Fi 機能を有効・無効にする


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

Wi-Fi 機能の有効・無効を切り替えるには、`WifiManager.setWifiEnabled()` を実行します。

### コード
```java
// Activity 等の Context 内で
WifiManager wm = (WifiManager) getSystemService(WIFI_SERVICE);

// 有効にする
wm.setWifiEnabled(true);

// 無効にする
wm.setWifiEnabled(false);
```

### パーミッション
このコードを実行するには `android.permission.CHANGE_WIFI_STATE` パーミッションを AndroidManifest.xml で設定する必要があります。

```xml

```

### 現実的な実装
実際は、以下のように Wi-Fi の状態を確認してから使用することが多くなると思います以下のコードを実行する場合は、`android.permission.ACCESS_WIFI_STATE` パーミッションも設定する必要があります。

```java
// Click する度に On/OFF を切り替える
@Override
public void onClick(View v) {
    WifiManager wm = (WifiManager) getSystemService(WIFI_SERVICE);
    
    if (wm.isWifiEnabled()) {
        // Wi-Fi が有効な場合は無効にする
        wm.setWifiEnabled(false);
    } else {
        // 有効にしている最中は意味がないので、状態を確認
        // ただし、WIFI_STATE_ENABLING 中に setWifiEnabled() を呼んでも問題はない
        if (wm.getWifiState() != WifiManager.WIFI_STATE_ENABLING) {
            wm.setWifiEnabled(true)
        }
    }
}
```

参考
[穀風: Android で Wi-Fi 機能が現在有効かどうか調べる](http://kokufu.blogspot.jp/2016/10/android-wi-fi_60.html)

Android で Wi-Fi 機能が現在有効かどうか調べる


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

Wi-Fi 機能の ON/OFF を調べます。
また、Wi-Fi の ON/OFF 切り替え時には状態があり、より正確な制御をするためには、状態を確認する必要があります。

### コード

```java
// Activity 等の Context 内で

// Wi-Fi ON/OFF の取得
WifiManager wm = (WifiManager) getSystemService(WIFI_SERVICE);
boolean isWifiEnabled = wm.isWifiEnabled();

// 状態の取得
// WifiManager.WIFI_STATE_DISABLED
// WifiManager.WIFI_STATE_DISABLING
// WifiManager.WIFI_STATE_ENABLED
// WifiManager.WIFI_STATE_ENABLING
// WifiManager.WIFI_STATE_UNKNOWN
int wifiState = wm.getWifiState()
```

### パーミッション
このコードを実行するには `android.permission.ACCESS_WIFI_STATE` パーミッションを AndroidManifest.xml で設定する必要があります。

```xml

```

### isWifiEnabled と wifiState との関係
`android.net.wifi.WifiManager` のソースコードAndroid 7.0 Nougatは以下のようになっています。
つまり、Wi-Fi の変化時、`isWifiEnabled` は `false` であり、細かい状態を `wifiState` から取得しなければなりません。

```java
public boolean isWifiEnabled() {
    return getWifiState() == WIFI_STATE_ENABLED;
}
```


### GUI上での表示
GUI 上では Wi-Fi の設定から確認可能な項目です。

設定 → 無線とネットワーク → Wi-Fi

Android の Wi-Fi 実装に関する情報のまとめ

ここ数日、Android の Wi-Fi まわりの実装をしていて、その際に必要になった情報をまとめておこうと思います。

Android で Wi-Fi 機能が備わっているか調べる


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

ハードウェアとして Wi-Fi 機能が備わっているか調べる方法です。

### コード

```java
// Activity 等の Context 内で
PackageManager pm = getPackageManager();
boolean hasWifi = pm.hasSystemFeature(PackageManager.FEATURE_WIFI);
```

### パーミッション
特別なパーミッションは必要ありません