2

私たちが知っているように、Google は新しいアプリが Android 11 (API レベル 30) 以上をターゲットにする必要があるというポリシーを更新しました。下位のターゲット SDK を使用している場合、アプリは期待どおりに動作しますが、ターゲット SDK 30 を使用している場合、期待どおりに動作しません。

アプリには次の主な機能があります。

  • 利用可能な WiFi は、Android 6 から 11 (最新の Android バージョン) のリストに表示されます。
  • リスト項目をクリックした後、ユーザーはそれぞれの Wi-Fi に接続する必要があります。OPEN またはその他のいずれかです。
  • それぞれの WiFi に接続した後、キャプティブ ページがあればそのページにリダイレクトされます。キャプティブ ページは、アプリへの WebView になります。

要点を言えば、対象の 30 SDK で次の問題に直面しています。

  • 最新の提案wifi接続コード[1]を使用している場合、部分的に機能しています。1つの問題があります。すでに別のWiFi接続に接続していて、新しいWiFiに接続しようとしているとします。新しいWiFiに接続していませんが、私は新しいWifiに接続する必要があります。

ターゲットSDK 30を使用してアプリで使用しているコード(新しいWifiに接続していない)-

    val suggestion = WifiNetworkSuggestion.Builder()
        .setSsid(SSID) // SSID of network
        .setWpa2Passphrase(wifiPassword) // password is network is not open
        //.setIsAppInteractionRequired(true) // Optional (Needs location permission)
        .build()

    val suggestionsList = listOf(suggestion)

    val wifiManager =
        applicationContext.getSystemService(WIFI_SERVICE) as WifiManager

    if (status != WifiManager.STATUS_NETWORK_SUGGESTIONS_SUCCESS) {
        // do error handling here
        Log.e("NETWORK", "Error")
    }

    // Optional (Wait for post connection broadcast to one of your suggestions)
    val intentFilter =
        IntentFilter(WifiManager.ACTION_WIFI_NETWORK_SUGGESTION_POST_CONNECTION);

    val broadcastReceiver = object : BroadcastReceiver() {
        override fun onReceive(context: Context, intent: Intent) {
            Log.e("NETWORK", "broadcastReceiver")

            if (!intent.action.equals(WifiManager.ACTION_WIFI_NETWORK_SUGGESTION_POST_CONNECTION)) {
                return;
            }
            // do post connect processing here
            Log.e("NETWORK", "post connect")
        }
    };
    registerReceiver(broadcastReceiver, intentFilter)

ターゲット SDK 29 を使用してアプリで使用しているコード(これは期待どおりに動作していますが、ターゲット SDK は 28 または 29 である必要があります。それ以外の場合、インターネットはアプリケーションから機能しません)-

  private fun android10andMoreVersionsWithoutOuterInternet(
    scanResult: ScanResult,
    wifiSSID: String,
    wifiPassword: String,
    capabilities: String
) {
    // Android 10 (API level 29) -- Android Q (Android 10)
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
        val wifiManager =
            this.applicationContext.getSystemService(Context.WIFI_SERVICE) as WifiManager

        val wifiNetworkSpecifier = WifiNetworkSpecifier.Builder()
            .setSsid(wifiSSID)
            //.setSsidPattern(PatternMatcher(wifiSSID, PatternMatcher.PATTERN_PREFIX))
            .setWpa2Passphrase(wifiPassword)
            .build()

        val networkRequest = NetworkRequest.Builder()
            .addTransportType(NetworkCapabilities.TRANSPORT_WIFI)
            //.removeCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
            //.addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
            //.addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED)
            .setNetworkSpecifier(wifiNetworkSpecifier)
            .build()
        val connectivityManager =
            this.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager


        val networkCallback = object : ConnectivityManager.NetworkCallback() {
            override fun onAvailable(network: Network) {
                Log.d("NETWORK", "Network available")
                super.onAvailable(network)

                // To make sure that requests don't go over mobile data
                connectivityManager.bindProcessToNetwork(network)

                //unregister network callback
                //connectivityManager.unregisterNetworkCallback(this)
               // connectivityManager.bindProcessToNetwork(null)

                gotoNextScreen(scanResult, wifiManager)

            }

            override fun onUnavailable() {
                Log.d("NETWORK", "Network unavailable")
                super.onUnavailable()
            }

            override fun onLosing(network: Network, maxMsToLive: Int) {
                Log.d("NETWORK", "onLosing")
                super.onLosing(network, maxMsToLive)
            }

            override fun onLost(network: Network) {
                Log.d("NETWORK", "onLost")
                super.onLost(network)

                //connectivityManager.bindProcessToNetwork(null)
                //connectivityManager.unregisterNetworkCallback(this)
            }

        }
        connectivityManager.requestNetwork(networkRequest, networkCallback)
        val builder = NetworkRequest.Builder()
        builder.addTransportType(NetworkCapabilities.TRANSPORT_WIFI)
        connectivityManager.registerNetworkCallback(builder.build(), networkCallback)
        //connectivityManager.registerNetworkCallback(networkRequest, networkCallback) // For listen
    }

}
  • Android 9 の古い減価償却コードでは、すべてが期待どおりに機能しています。

    以下の Android 9 abd で使用されているコード(期待どおりに動作し、対象の SDK に影響を与えていません)-

     private fun android9AndPreviousVersion(
      scanResult: ScanResult,
      wifiSSID: String,
      wifiPassword: String,
      capabilities: String
       ) {
      val conf = WifiConfiguration()
      conf.SSID =
          "\"" + wifiSSID + "\"" // Please note the quotes. String should contain ssid in quotes
      conf.status = WifiConfiguration.Status.ENABLED
      conf.priority = 40
    
      if (Common.checkWifiType(capabilities) == "WEP") {
          Log.e("NETWORK", "Configuring WEP")
          conf.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE)
          conf.allowedProtocols.set(WifiConfiguration.Protocol.RSN)
          conf.allowedProtocols.set(WifiConfiguration.Protocol.WPA)
          conf.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.OPEN)
          conf.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.SHARED)
          conf.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP)
          conf.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.TKIP)
          conf.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP40)
          conf.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP104)
          if (wifiPassword.matches(Regex("^[0-9a-fA-F]+$"))) {
              conf.wepKeys[0] = wifiPassword
          } else {
              conf.wepKeys[0] = "\"" + wifiPassword + "\""
          }
          conf.wepTxKeyIndex = 0
      } else if (Common.checkWifiType(capabilities) == "WPA") {
          Log.e("NETWORK", "Configuring WPA")
          conf.allowedProtocols.set(WifiConfiguration.Protocol.RSN)
          conf.allowedProtocols.set(WifiConfiguration.Protocol.WPA)
          conf.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK)
          conf.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP)
          conf.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.TKIP)
          conf.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP40)
          conf.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP104)
          conf.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP)
          conf.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP)
          conf.preSharedKey = "\"" + wifiPassword + "\""
      } else {
          Log.e("NETWORK", "Configuring OPEN network")
          conf.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE)
      }
      val wifiManager =
          this.applicationContext.getSystemService(Context.WIFI_SERVICE) as WifiManager
      val networkId = wifiManager.addNetwork(conf)
      Log.e("NETWORK", "Add result $networkId")
    
      if (ActivityCompat.checkSelfPermission(
              this,
              Manifest.permission.ACCESS_FINE_LOCATION
          ) != PackageManager.PERMISSION_GRANTED
      ) {
          return
      }
    
      val list = wifiManager.configuredNetworks
      for (i in list) {
          if (i.SSID != null && i.SSID == "\"" + wifiSSID + "\"") {
              Log.e("NETWORK", "WifiConfiguration SSID " + i.SSID)
              val isDisconnected = wifiManager.disconnect()
              Log.e("NETWORK", "isDisconnected : $isDisconnected")
              val isEnabled = wifiManager.enableNetwork(i.networkId, true)
              Log.e("NETWORK", "isEnabled : $isEnabled")
              val isReconnected = wifiManager.reconnect()
              Log.e("NETWORK", "isReconnected : $isReconnected")
              break
          }
      }
      //val connectionInfo: WifiInfo = wifiManager.getConnectionInfo()
      gotoNextScreen(scanResult, wifiManager)
    

    }

結論:ターゲット SDK 30で利用可能な WiFi に接続するためにWifiNetworkSpecifierを使用している場合、接続できますが、私のインターネットはアプリでのみ機能します。ターゲット SDK 30で利用可能な WiFi に接続するために最新の提案 WiFiを使用している場合、新しい WiFi に接続できません。Android 10 および Android 11 デバイスでこの問題に直面しています。

解決策を教えてください。POC コードを確認してください[こちら]

4

1 に答える 1