LoginSignup
7
10

More than 3 years have passed since last update.

Android の Wi-Fi まわりのことメモ

Last updated at Posted at 2020-04-03

WiFi まわりのことを扱う機会があったので、復習がてら整理してみる。

パーミッション取得

  • AndroidManifest.xml に追加

OS、 targetSDK によって必要な権限が異なる。詳しくは公式ドキュメント参照。
以下は一例。

AndroidManifest.xml
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
  • 権限取得処理実装

必要なタイミングで権限をユーザーに求める処理を呼び出す。

activity
private val PERMISSIONS_REQUEST_CODE_ACCESS_COARSE_LOCATION = 0

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    なんかボタン.setOnClickListener {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
            requestPermissions(arrayOf(Manifest.permission.ACCESS_COARSE_LOCATION), PERMISSIONS_REQUEST_CODE_ACCESS_COARSE_LOCATION)
        } else {
            // 許可済みの処理
        }
    }
}

override fun onRequestPermissionsResult(requestCode: Int, @NonNull permissions: Array<String>, @NonNull grantResults: IntArray) {
    if (requestCode != PERMISSIONS_REQUEST_CODE_ACCESS_COARSE_LOCATION) {
        return
    }
    if (grantResults.size > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
        // 許可済みの処理
    }
}

WiFi をスキャンする

activity
    val wifiManager = applicationContext.getSystemService(Context.WIFI_SERVICE) as WifiManager

    val wifiScanReceiver = object : BroadcastReceiver() {
        override fun onReceive(context: Context, intent: Intent) {
            val success = intent.getBooleanExtra(WifiManager.EXTRA_RESULTS_UPDATED, false)
            if (success) {
                scanSuccess()
            } else {
                scanFailure()
            }
        }
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        // startScan() が呼ばれると SCAN_RESULTS_AVAILABLE_ACTION がブロードキャストされる
        registerReceiver(wifiScanReceiver, IntentFilter(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION))

        val success = wifiManager.startScan()
        if (!success) {
            scanFailure()
        }
    }

    private fun scanSuccess() {
        // スキャン成功処理
    }

    private fun scanFailure() {
        // スキャン失敗処理
    }

WiFi に接続する

なんかボタン.setOnClickListener {

    val connectScanResult: ScanResult = 接続したいWiFi ScanResult

    // 既に保存されている WiFi の設定情報を取得
    var configuredNetworks: List<WifiConfiguration>?
    try {
        configuredNetworks = wifiManager.configuredNetworks
    } catch (e: Exception) {
        configuredNetworks = null
    }

    var networkId = -1
    if (configuredNetworks != null) {
        for (configuredNetwork: WifiConfiguration in configuredNetworks) {
            // "(ダブルクォーテーション) が前後についているので除外している
            val normalizedSsid = configuredNetwork.SSID.substring(1, configuredNetwork.SSID.length - 1)

            // すでに接続情報があるかチェックする
            if (connectScanResult.SSID.equals(normalizedSsid)) {
                networkId = configuredNetwork.networkId
                break
            }
        }
    }
    if (networkId < 0) {
        // 接続情報がないので作る
        val configuration = WifiConfiguration().apply {
            SSID = "\"$connectScanResult.SSID\""

            // 設定する前に一回クリアする(よくわかってない・・・)
            allowedProtocols.clear()
            allowedProtocols.set(WifiConfiguration.Protocol.RSN)
            allowedProtocols.set(WifiConfiguration.Protocol.WPA)

            allowedAuthAlgorithms.clear()

            allowedPairwiseCiphers.clear()
            allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP)
            allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.TKIP)

            allowedGroupCiphers.clear()
            allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP)
            allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP)

            // 設定する
            // connectScanResult.capabilities に "WEP"、"PSK" などが含まれるかどうかで設定方法が変わる
            allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE)

            allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.OPEN)
            allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.SHARED)

            allowedGroupCiphers.clear()
            allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP40)
            allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP104)

            wepKeys[0] = "\"接続する WiFi のパスワード\""
            wepTxKeyIndex = 0
        }
        networkId = wifiManager.addNetwork(configuration)
    }
    if (networkId < 0) {
        Toast.makeText(this, "接続できませんでした", Toast.LENGTH_SHORT).show()
        return
    }
    if (wifiManager.enableNetwork(networkId, true)) {
        Toast.makeText(this, connectScanResult.SSID + "に接続しました。", Toast.LENGTH_SHORT).show()
    } else {
        Toast.makeText(this, "接続できませんでした", Toast.LENGTH_SHORT).show()
    }
}

接続中のネットワークの SSID を取得する

val wifiManager = applicationContext.getSystemService(Context.WIFI_SERVICE) as WifiManager

if (wifiManager.connectionInfo.networkId != -1) {
    // ネットワーク接続中
    // ※ ここで取得できる SSID は先頭と末尾に "(ダブルクォーテーション) が前後についている
    // https://developer.android.com/reference/android/net/wifi/WifiInfo#getSSID()
    val ssid = wifiManager.connectionInfo.ssid
} else {
    // ネットワークに接続されていない
}

参考

7
10
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
10