【问题标题】:Android Q Wifi connection via WifiNetworkSpecifier lose connection immediately after connection established通过 WifiNetworkSpecifier 的 Android Q Wifi 连接在建立连接后立即失去连接
【发布时间】:2020-06-24 20:46:51
【问题描述】:

我目前正在尝试连接到 wifi 网络。我使用了下面的代码。

        WifiNetworkSpecifier specifier = new WifiNetworkSpecifier.Builder()
                .setSsid(ssid)
                .setBssid(MacAddress.fromString(bssid))
                .setWpa2Passphrase(password)
                .build();

        NetworkRequest request = new NetworkRequest.Builder()
                .addTransportType(NetworkCapabilities.TRANSPORT_WIFI)
                .setNetworkSpecifier(specifier)
                .build();

        ConnectivityManager manager = (ConnectivityManager) context.getApplicationContext().getSystemService(Context.CONNECTIVITY_SERVICE);

        manager.requestNetwork(request, new ConnectivityManager.NetworkCallback() {

            @Override
            public void onAvailable(@NonNull Network network) {
                ConnectivityManager.setProcessDefaultNetwork(network);
                super.onAvailable(network);
                NetworkInfo info = manager.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
                if (info != null && info.isConnectedOrConnecting()) {
                    if (!emitter.isDisposed()) {
                        emitter.onSuccess(true);
                    }
                } else {
                    if (!emitter.isDisposed()) {
                        emitter.onError(new RuntimeException("OS Disconnected"));
                    }
                }

            }

            @Override
            public void onUnavailable() {
                super.onUnavailable();
                if (!emitter.isDisposed()) {
                    emitter.onError(new RuntimeException("Could not connect Wifi"));
                }
            }
        });
    });

问题: 上面的代码在 Pixel 手机和诺基亚上运行良好,但在 Oneplus 设备上,我得到 toast connection success toast 并且在这个 wifi 断开后立即。 wifi 符号在状态栏中非常短暂地可见。在下一刻,Wifi-Symbol 消失了,系统对话框再次可见,连接到 wifi。

已授予以下权限,并且已授予位置权限,并且在设备中也已启用。

 <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <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_FINE_LOCATION"/>
    <uses-permission android:name="android.permission.CHANGE_NETWORK_STATE"/>
    <uses-permission android:name="android.permission.INTERNET"/>

当我调试回调时,它正在执行此顺序中的方法:

  1. onAvailable()
  2. onCapabilitiesChanged()
  3. onBlockedStatusChanged(阻止:假)
  4. onCapabilitiesChanged()
  5. onLost()

我已经提到了这些 Android Q, programmatically connect to different WiFi AP for internet
WiFi Network Connection keeps disconnecting on Android Q Wifi Network Request Api connection issue in android 10 (Q) Android Q, WifiNetworkSpecifier loosing Wifi immediately after connection is established

我无法找到解决方案。

我在网络请求中是否缺少任何导致断开连接的内容。或任何其他赞赏的解决方案。

谢谢。

【问题讨论】:

  • 呃。您是否有表现出这种行为的特定 OnePlus 模型(或多个模型)?
  • 我尝试了 4 种不同的型号,其中 3 台搭载 android 10 操作系统的 OnePlus 6t 设备和一台搭载 android 10 的 OnePlus 7 pro 都表现相同。
  • 这个问题发生在我身上,让我很沮丧。我正在使用三星s10进行测试,我搜索了很多,一无所获。然后我尝试了另一个设备,发现它很有魅力。我寻找三星 S10 设备是否有问题,似乎自 Android 10 更新以来报告了很多问题。如果您使用的是 S10,请查看以下链接,(第三种解决方案适用于我):thedroidguy.com/…
  • 我也有同样的问题。我在三星 S9+ 和 Galaxy S6 平板电脑上进行了测试。两者都有相同的问题。连接到选定的 wifi ssid(在说明符中输入),回调转到 onAvailable 并“已连接”,但立即断开连接。两者都是 API 29。(Q,10)根据众多 SO 答案,我尝试了许多请求修饰符的组合。我使用了 3 个不同的 wifi 连接,2 个在路由器上(wep 和 wpa),一个来自 D1 mini AP。到目前为止,没有任何效果。到目前为止,文档、在线论坛和 SO 上的所有研究都没有取得任何进展。

标签: android wifi android-10.0 android-connectivitymanager


【解决方案1】:

截至 2020 年 9 月,此问题似乎仍未在某些设备上得到解决,一加 6、诺基亚手机等似乎正在展示这种成功连接循环。同时,如果您有一个 iOT 设备,您的应用程序正在尝试自动连接但失败了,您可以在 onFail() 中尝试此操作,以关闭连接对话框并将您的用户优雅地带到 wifi 页面以手动连接。

        connectivityManager.bindProcessToNetwork(null);
        connectivityManager.unregisterNetworkCallback(networkCallback);
        AlertDialog.Builder alert = new AlertDialog.Builder(...);
        alert.setTitle(...);
        alert.setMessage(...);
        alert.setPositiveButton("OK",
          new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface dialog, int id) {
              Intent intent = new Intent(Settings.ACTION_WIFI_SETTINGS);
              intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
              context.startActivity(intent);
            }
          });
        alert.show();
      }

【讨论】:

  • 我正在使用诺基亚手机进行测试,并且遇到了这种连接循环。但是,只有当我调用 connectivityManager.unregisterNetworkCallback(networkCallback) 时才会发生这种情况。如果我不取消注册回调,手机将保持连接到 WiFi。不太清楚为什么......
【解决方案2】:

谈话迟到了,但是,您是否尝试过在找到可用网络时拨打connectivityManager.bindProcessToNetwork(network)

根据您的问题代码,这是我的意思的示例:

WifiNetworkSpecifier specifier = new WifiNetworkSpecifier.Builder()
                .setSsid(ssid)
                .setBssid(MacAddress.fromString(bssid))
                .setWpa2Passphrase(password)
                .build();

        NetworkRequest request = new NetworkRequest.Builder()
                .addTransportType(NetworkCapabilities.TRANSPORT_WIFI)
                .setNetworkSpecifier(specifier)
                .build();

        ConnectivityManager manager = (ConnectivityManager) context.getApplicationContext().getSystemService(Context.CONNECTIVITY_SERVICE);

        manager.requestNetwork(request, new ConnectivityManager.NetworkCallback() {

            @Override
            public void onAvailable(@NonNull Network network) {
                super.onAvailable(network);

                // This is the new line of code
                ConnectivityManager.bindProcessToNetwork(network);

                NetworkInfo info = manager.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
                if (info != null && info.isConnectedOrConnecting()) {
                    if (!emitter.isDisposed()) {
                        emitter.onSuccess(true);
                    }
                } else {
                    if (!emitter.isDisposed()) {
                        emitter.onError(new RuntimeException("OS Disconnected"));
                    }
                }

            }
...
}

【讨论】:

  • ConnectivityManager.bindProcessToNetwork(network);解决了我的问题
【解决方案3】:

如果您尝试连接到无法访问互联网的网络,而不是

NetworkRequest request = new NetworkRequest.Builder()
 .addTransportType(NetworkCapabilities.TRANSPORT_WIFI)
 .setNetworkSpecifier(specifier)
 .build();

试试

NetworkRequest request = NetworkRequest.Builder()
.addTransportType(NetworkCapabilities.TRANSPORT_WIFI)
.removeCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
.setNetworkSpecifier(specifier)
.build()

显然,默认情况下需要互联网功能。

文档(见https://developer.android.com/reference/android/net/wifi/WifiNetworkSpecifier.Builder#build())说

创建一个用于请求本地 Wi-Fi 网络的说明符对象。在构建 NetworkRequest 时,应在 NetworkRequest.Builder#setNetworkSpecifier(NetworkSpecifier) 中使用生成的 NetworkSpecifier。这些说明符只能用于请求本地 wifi 网络(即没有互联网功能)。因此,如果有其他传输(例如蜂窝)可用,设备将不会将其默认路由切换到 wifi。

我不太明白这一段,但它谈到了设备切换回默认路由,什么会导致与您的目标网络断开连接。

那里提供的示例包括该行

.removeCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)

我复制了这个例子,它对我有用。从未尝试在没有上述线路的情况下建立连接。

但是,我只尝试连接到具有 Internet 连接的网络。令我惊讶的是,当我尝试在没有它的情况下连接到一个时,尽管有文档,但连接失败了。

【讨论】:

  • 您在什么设备上试用过?我试过这条线,但它在我的三星 S9+ 上不起作用。尝试连接到我的网络连接到互联网以及没有互联网的 softAP。两者都不适合我。
  • 银河 A10s。它在有互联网的情况下工作,但直到现在我断开电缆并尝试没有互联网。与文档所说的相反,它失败了。
【解决方案4】:

我一直在跟踪和研究这一点。我的所有发现以及我当前的最佳解决方案都可以在 here

找到

但更具体的问题是从链接中获取的以下信息

here by Google 所述,一些 OEM Rom 没有“保持请求”,因此连接会立即断开。 OnePlus 在他们后来的一些型号中解决了这个问题,但不是全部。对于某些 Android 版本上的某些手机型号,此错误将持续存在,因此需要成功的回退(即没有网络中断的手动连接)。没有可用的解决方法

  • removeCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET) 不会帮助在 OnePlus 上保持连接,如 here 所述

  • here 所述,设置 Bssid 无助于保持 OnePlus 上的连接

  • google 帮不上忙,他们说这不在他们的掌控之中here

  • OnePlus 论坛帖子确认它在更新后适用于某些型号(但不是全部),请参阅 hereherehere

【讨论】:

    猜你喜欢
    • 2020-05-15
    • 1970-01-01
    • 2020-01-15
    • 1970-01-01
    • 2020-01-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-11-10
    相关资源
    最近更新 更多