当设备连接到内部wifi网络时,ConnectivityManager.NetworkCallback() -> onAvailable(Network network)方法未被触发。

9
我正在尝试将遥测数据发送到内部wifi网络上的App Center,但它在此网络上无法发送,但是在任何外部网络上都可以发送。调试时发现,当设备连接到内部wifi时,方法onAvailable()未被调用,但连接到任何外部wifi时会被调用。
以下代码来自于App Center SDK: appcenter\utils\NetworkStateHelper.javaNetworkStateHelper.java。 类NetworkStateHelper -> 方法reopen() --> 公共void onAvailable(Network network)方法
示例代码:
private ConnectivityManager.NetworkCallback mNetworkCallback = new ConnectivityManager.NetworkCallback() 
{

    @Override
    public void onAvailable(Network network) {
        onNetworkAvailable(network);
    }

    @Override
    public void onLost(Network network) {
        onNetworkLost(network);
    }
};

当连接到内部Wi-Fi网络时,应调用onAvailable方法。


你好,gradle文件中的目标API是什么? - Maksim Novikov
它是26,compileSdkVersion为26 buildToolsVersion为"26.0.2" - sonu769
我在一些Android 6设备上遇到了类似的问题。 - algrid
3个回答

13
你需要将网络类型限制为Wifi1. 构建NetworkRequest
val networkRequest = getNetworkRequest()

private fun getNetworkRequest(): NetworkRequest {
    return NetworkRequest.Builder()
        .addTransportType(NetworkCapabilities.TRANSPORT_WIFI)    //here!!
        .build()
}

2. 构建NetworkCallback

val networkCallback = getNetworkCallBack()

private fun getNetworkCallBack(): ConnectivityManager.NetworkCallback {
    return object : ConnectivityManager.NetworkCallback() {
        override fun onAvailable(network: Network) {    //when Wifi is on
            super.onAvailable(network)

            Toast.makeText(requireContext(), "Wifi is on!", Toast.LENGTH_SHORT).show()
        }

        override fun onLost(network: Network) {    //when Wifi 【turns off】
            super.onLost(network)

            Toast.makeText(requireContext(), "Wifi turns off!", Toast.LENGTH_SHORT).show()
        }
    }
}

3. 注册和注销:

fun getConnectivityManager() = requireContext().getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager

override fun onResume() {    //start monitoring when in the foreground
    super.onResume()

    getConnectivityManager().registerNetworkCallback(networkRequest, networkCallback)
}

override fun onPause() {    //stop monitoring when not fully visible
    super.onPause()

    getConnectivityManager().unregisterNetworkCallback(networkCallback)
}

4. 别忘了权限:

<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />

演示:https://youtu.be/RPRcGbuB6eI


2
根据Android 文档所述:

如果应用程序在其清单中声明广播接收器,且目标API为Android 7.0(API级别24)或更高版本,则不会收到CONNECTIVITY_ACTION广播。如果使用Context.registerReceiver()注册广播接收器并且上下文仍然有效,则应用程序仍将收到CONNECTIVITY_ACTION广播。

这意味着,如果您的目标API高于24,则需要在活动启动时注册广播接收器。
在您的活动中,onCreate()方法中进行注册。
IntentFilter intentFilter = new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION);
registerReceiver(connectivityReceiver, intentFilter);

声明广播:

private BroadcastReceiver connectivityReceiver = new BroadcastReceiver() {
    @Override
    public void onReceive(Context context, Intent intent) {
      //check state here....
    }
  };

10
自 API 级别28开始,Connectivity-action已被弃用。现在应该使用网络回调(network callback)API,即问题中提到的那个API。请参考:https://developer.android.com/reference/android/net/ConnectivityManager.html#CONNECTIVITY_ACTION。 - Guillaume Perrot
感谢您的帮助。我正在使用 Android 6.0.1,目标 SDK 版本是 26。 - sonu769
我展示的示例代码来自只读的App Center SDK。https://learn.microsoft.com/en-us/appcenter/sdk/analytics/android - sonu769
@sonu769 你使用 Xamarin 吗? - Maksim Novikov
No just android - sonu769

0

我有一个问题,我想要刷新(强制刷新),因为public void onCapabilitiesChanged(Network network, NetworkCapabilities networkCapabilities)不会立即改变速度。

connectivityManager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);

        NetworkRequest networkRequest = new NetworkRequest.Builder()
                .addTransportType(NetworkCapabilities.TRANSPORT_WIFI)
                .addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR)
                .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
                .addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED)
                .build();

        wifiBande1Infos = new JSONObject();
        wifiBande2Infos = new JSONObject();

        NetworkCallback networkCallback = new ConnectivityManager.NetworkCallback(ConnectivityManager.NetworkCallback.FLAG_INCLUDE_LOCATION_INFO) {
                    @Override
                    public void onAvailable(Network network) {

                    }


                    @Override
                    public void onLost(Network network) {

                    }

                    @Override
                    public void onLinkPropertiesChanged(Network network, LinkProperties linkProperties) {
                    }

                    @Override
                    public void onCapabilitiesChanged(Network network, NetworkCapabilities networkCapabilities) {
                        super.onCapabilitiesChanged(network, networkCapabilities);
                        executor.execute(() -> {

                            Network activeNetwork = connectivityManager.getActiveNetwork();
                            LinkProperties linkProperties = connectivityManager.getLinkProperties(activeNetwork);

                            linkProperties = connectivityManager.getLinkProperties(network);
                            interfaceName = linkProperties.getInterfaceName();

                            WifiInfo wifiInfo = (WifiInfo) networkCapabilities.getTransportInfo();

                            if (wifiInfo != null) {
                                String ssid = wifiInfo.getSSID();

                                try {

                                    if (interfaceName.equals("wlan0")) {

                                        JSONObject ssidEntry = new JSONObject();
                                        ssidEntry.put("getRssi", String.valueOf(wifiInfo.getRssi()));
                                        ssidEntry.put("getRssi2", String.valueOf(networkCapabilities.getSignalStrength()));
                                        
                                        JSONArray ssidEntryArray = new JSONArray();
                                        ssidEntryArray.put(ssidEntry);

                                        wifiBande1Infos.put(interfaceName, ssidEntryArray);
                                    } else if (interfaceName.equals("wlan1")) {

                                        
                                        JSONObject ssidEntry = new JSONObject();
                                        
                                        ssidEntry.put("getRssi", String.valueOf(wifiInfo.getRssi()));
                                        ssidEntry.put("getRssi2", String.valueOf(networkCapabilities.getSignalStrength()));
                                        
                                        JSONArray ssidEntryArray = new JSONArray();
                                        ssidEntryArray.put(ssidEntry);

                                        wifiBande2Infos.put(interfaceName, ssidEntryArray);
                                    }

                                    refreshInfosWifi();

                                } catch (JSONException e) {
                                    Log.e(TAG, "Error Connection 152", e);
                                    e.printStackTrace();
                                }
                            }
                        });
                    }
                };


        connectivityManager.registerNetworkCallback(networkRequest, networkCallback); 
        connectivityManager.requestNetwork(networkRequest, networkCallback); 


scheduler = Executors.newScheduledThreadPool(1);
    scheduler.scheduleAtFixedRate(new Runnable() {
        @Override
        public void run() {

            try {
                updateRSSI();
            } catch (JSONException e) {
                throw new RuntimeException(e);
            }

        }
    }, 0, 1, TimeUnit.SECONDS);



 private void updateRSSI() throws JSONException {

    WifiManager wifiManager = (WifiManager) getSystemService(Context.WIFI_SERVICE);
    WifiInfo wifiInfo = wifiManager.getConnectionInfo();
    int wlan0_rssi_old = wifiInfo.getRssi();

    //Log.d(TAG, "Refresh 2s : Rssi Wlan0 OLD : "+wlan0_rssi_old);

    if(!wifiBande1Infos.isNull("wlan0")) {
        JSONArray wifiBande1InfosArray = wifiBande1Infos.getJSONArray("wlan0");
        JSONObject wifiBande1InfosObj = wifiBande1InfosArray.getJSONObject(0);
        ConnectivityManager connectivityManager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
        NetworkCapabilities networkCapabilities = connectivityManager.getNetworkCapabilities((Network) wifiBande1InfosObj.get("IdNetworkMaster"));
        WifiInfo wifiInfoRefresh = (WifiInfo) networkCapabilities.getTransportInfo();

       

    }
    if(!wifiBande2Infos.isNull("wlan1")) {
        JSONArray wifiBande2InfosArray = wifiBande2Infos.getJSONArray("wlan1");
        JSONObject wifiBande2InfosObj = wifiBande2InfosArray.getJSONObject(0);
        ConnectivityManager connectivityManager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
        NetworkCapabilities networkCapabilities = connectivityManager.getNetworkCapabilities((Network) wifiBande2InfosObj.get("IdNetworkMaster"));
        WifiInfo wifiInfoRefresh = (WifiInfo) networkCapabilities.getTransportInfo();

      

    }


    runOnUiThread(new Runnable() {
                      @Override
                      public void run() {
                          TextView T_wifiRSSI_old_txt = findViewById(R.id.wifiRSSI_old_txt);
                          T_wifiRSSI_old_txt.setText(String.valueOf(wlan0_rssi_old)+" dBm");
                          ProgressBar P_wifiRSSI_old = findViewById(R.id.wifiRSSI_old);
                          P_wifiRSSI_old.setProgress(Integer.parseInt(String.valueOf(wlan0_rssi_old)));

                      }
                  });
}

如您所见,我使用最新的API(大于等于33),但是我的应用程序只在33及以下版本中运行。

目标是比较RSSI刷新之间的差异:

  • 旧方法: WifiInfo wifiInfo = wifiManager.getConnectionInfo();
  • 新方法: WifiInfo wifiInfoRefresh = (WifiInfo) networkCapabilities.getTransportInfo();

我发现旧方法强制刷新效果很好。另一方面,对于新方法,我无法通过 onCapabilitiesChanged 更新或自己获取值。

我可能做错了什么,请您帮我纠正错误。

我还发现新方法有一个非常奇怪的效果,在-50dBm以下,两个WLANS都不再更新了。另一方面,旧方法可以一直更新到-1dbm。除非有可能通过新方法实际强制刷新。

谢谢提供帮助的任何人,我已经研究了几天了...:)


这并没有真正回答问题。如果您有不同的问题,可以通过点击提问来提出。如果您想在此问题获得新的答案时得到通知,您可以关注此问题。一旦您拥有足够的声望,您还可以添加悬赏以吸引更多关注。- 来自审核 - RusArtM

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接