获取 API 29 中的 isActiveNetworkMetered 和 isDefaultNetworkActive。

huangapple 未分类评论53阅读模式
英文:

Get isActiveNetworkMetered and isDefaultNetworkActive in API 29

问题

在API 29中,connectivityManager.getActiveNetworkInfo()被弃用后,要编写一个能够区分计量(移动网络)和WiFi连接的网络监测函数变得相当困难。

我遇到的问题有两个:

  1. connectivityManager.isActiveNetworkMetered() -- 当WiFi和移动数据都开启时,它返回true(至少在我的模拟器上是这样,我无法在设备上进行检查)。当只有WiFi开启时,它返回false,与预期相符。

  2. connectivityManager.isDefaultNetworkActive() -- 即使WiFi和移动数据关闭,它始终处于活动状态。

我唯一找到的解决办法是通过(1)onCapabilitiesChanged()和(2)getActiveNetwork()==null。以下是代码。

你知道是否有其他方法可以做到这一点?整个实现看起来很繁琐,而且互联网上充斥着已被弃用的示例。

谢谢!

private static void monitorNetworks(){
    NetworkRequest.Builder builder = new NetworkRequest.Builder();

    connectivityManager.registerNetworkCallback(
            builder.build(),
            ncb = new ConnectivityManager.NetworkCallback() {
                @Override
                public void onAvailable(Network network) {
                    scanAndSend();
                }

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

                @Override
                public void onUnavailable(){
                    scanAndSend();
                }

                @Override
                public void onCapabilitiesChanged (Network network,
                                                   NetworkCapabilities networkCapabilities){
                    boolean metered = !networkCapabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED);
                    Log.d(TAG, "NET_CAPABILITY_NOT_METERED: " +
                            String.valueOf(networkCapabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED)));
                    sendMetered(metered);
                }
            }
    );
}

private static void scanAndSend(){
    boolean is_connected = false;
    if(connectivityManager.getActiveNetwork()==null) is_connected = false;
    else is_connected = true;
    sendConnectivityIntent(IS_NETWORK_AVAILABLE, is_connected);
}

private static void sendMetered(boolean metered) {
    sendIntent(IS_NETWORK_METERED, metered);
}

private static void sendIntent(String val_name, boolean val) {
    Intent intent = new Intent();
    intent.setAction(CONNECTIVITY_ACTION);
    intent.putExtra(val_name, val);
    context.sendBroadcast(intent);
}
英文:

After connectivityManager.getActiveNetworkInfo() got deprecated in API 29, it was quite a struggle to put together a network monitoring function that would also distinguish metered (cell) vs WiFi connection.

The problems I faced were 2:

  1. connectivityManager.isActiveNetworkMetered() -- when both WiFi and Mobile data were on, it returned true (at least on my emulator, and I couldn't check on a device). When only WiFi was on, it returned false, as expected.

  2. connectivityManager.isDefaultNetworkActive() -- it would always be active even if WiFi and Mobile were off.

The only way I found to work around this is via (1) onCapabilitiesChanged() and (2) getActiveNetwork()==null. The code is pasted below.

Do you know if there are other ways to do it? The whole implementation seems cumbersome, and the internet is full of deprecated examples.

Thanks

private static void monitorNetworks(){
        NetworkRequest.Builder builder = new NetworkRequest.Builder();

        connectivityManager.registerNetworkCallback(
                builder.build(),
                ncb = new ConnectivityManager.NetworkCallback() {
                    @Override
                    public void onAvailable(Network network) {
                        scanAndSend();
                    }

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

                    @Override
                    public void onUnavailable(){
                        scanAndSend();
                    }

                    @Override
                    public void onCapabilitiesChanged (Network network,
                                                       NetworkCapabilities networkCapabilities){
                        boolean metered = !networkCapabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED);
                        Log.d(TAG, "NET_CAPABILITY_NOT_METERED: " +
                                String.valueOf(networkCapabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED)));
                        sendMetered(metered);
                    }
                }
        );
    }

    private static void scanAndSend(){
        boolean is_connected = false;
        if(connectivityManager.getActiveNetwork()==null) is_connected = false;
        else is_connected = true;
        sendConnectivityIntent(IS_NETWORK_AVAILABLE, is_connected);
    }

    private static void sendMetered(boolean metered) {
        sendIntent(IS_NETWORK_METERED, metered);
    }

    private static void sendIntent(String val_name, boolean val) {
        Intent intent = new Intent();
        intent.setAction(CONNECTIVITY_ACTION);
        intent.putExtra(val_name, val);
        context.sendBroadcast(intent);
    }

huangapple
  • 本文由 发表于 2020年4月9日 05:43:43
  • 转载请务必保留本文链接:https://java.coder-hub.com/61110523.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定