鬂已星星也 發表於 2020-6-22 17:50:00

Android开发 ConnectivityManager

<h1><span style="color: rgba(0, 128, 128, 1)">版权声明</span></h1>
<p>本文来自博客园,作者:观心静&nbsp;,转载请注明原文链接:https://www.cnblogs.com/guanxinjing/p/13178067.html</p>
<div>本文版权归作者和博客园共有,欢迎转载,但必须给出原文链接,并保留此段声明,否则保留追究法律责任的权利。</div>
<h1><span style="color: rgba(0, 128, 128, 1)">前言</span></h1>
<p>  ConnectivityManager类用于查询网络状态,并且也能被动监听网络状态的变化。</p>
<h1><span style="color: rgba(0, 128, 128, 1)">判断是否有网络</span></h1>
<p><span style="color: rgba(0, 0, 0, 1)">下面这个getActiveNetworkInfo 方法是过时的旧方法。这里记录一下,请注意如果获取到的是null,那么等于当前设备没有连接网络。<span style="color: rgba(0, 0, 0, 1)">注意这里是使用kotlin代码调用的(个人最近在切换到kotlin)</span></span></p>
<div class="cnblogs_code">
<pre>    <span style="color: rgba(0, 0, 255, 1)">private</span><span style="color: rgba(0, 0, 0, 1)"> fun hasNetwork(): Boolean {
      val connectivity </span>=<span style="color: rgba(0, 0, 0, 1)"> getSystemService(CONNECTIVITY_SERVICE) as ConnectivityManager
      val networkInfo </span>=<span style="color: rgba(0, 0, 0, 1)"> connectivity.activeNetworkInfo
      </span><span style="color: rgba(0, 0, 255, 1)">return</span> networkInfo != <span style="color: rgba(0, 0, 255, 1)">null</span> &amp;&amp; networkInfo.isAvailable <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">networkInfo如果是null也是没有网络</span>
    }</pre>
</div>
<p><span style="color: rgba(0, 0, 0, 1)">新方法请使用getActiveNetwork,,同上<span style="color: rgba(0, 0, 0, 1)">如果获取到的是null,那么等于当前设备没有连接网络</span></span></p>
<div class="cnblogs_code">
<pre>    <span style="color: rgba(0, 0, 255, 1)">private</span><span style="color: rgba(0, 0, 0, 1)"> fun hasNetwork2(): Boolean {
      var connectivityManager: ConnectivityManager </span>=<span style="color: rgba(0, 0, 0, 1)"> getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
      </span><span style="color: rgba(0, 0, 255, 1)">if</span> (android.os.Build.VERSION.SDK_INT &gt;=<span style="color: rgba(0, 0, 0, 1)"> android.os.Build.VERSION_CODES.M) {
            val network </span>=<span style="color: rgba(0, 0, 0, 1)"> connectivityManager.activeNetwork
            </span><span style="color: rgba(0, 0, 255, 1)">return</span> network != <span style="color: rgba(0, 0, 255, 1)">null</span> <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">如果是null代表没有网络</span>
<span style="color: rgba(0, 0, 0, 1)">      }
      </span><span style="color: rgba(0, 0, 255, 1)">return</span> <span style="color: rgba(0, 0, 255, 1)">false</span><span style="color: rgba(0, 0, 0, 1)">
    }</span></pre>
</div>
<h1><span style="color: rgba(0, 128, 128, 1)">判断外部网络是否连接</span></h1>
<p>有时候WiFi连接了不等于外部网络也连接了,我们有时候需要判断外部网络。以前的都是教使用shell来ping外部网络来判断的。这多多少少有点过时了。这里我们可以直接通过连接网络来判断</p>
<p>代码</p>
<pre class="highlighter-hljs" data-dark-theme="true"><code>private fun hasExternalNetwork(application: Application): Boolean {
    var connectivityManager: ConnectivityManager = application.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
    if (android.os.Build.VERSION.SDK_INT &gt;= android.os.Build.VERSION_CODES.M) {
      val network = connectivityManager.activeNetwork
      if (network == null){
            return false
      }
      //这里创建2个验证网络连接的公共网络地址,你也可以按需多增加几个
      val urlList = listOf&lt;String&gt;("https://223.5.5.5/", //阿里
            "https://www.baidu.com/" //百度
      )
      var notConnectCount = 0
      urlList.forEach {
            try {
                val openConnection = network.openConnection(URL(it))
                openConnection.connect()
            } catch (e:IOException){
                notConnectCount++
                Log.e("zh", "无法连接")
            }
      }
      return notConnectCount &lt; 2
    }
    return false
}</code></pre>
<h1><span style="color: rgba(0, 128, 128, 1)">判断当前正在使用的网络类型</span></h1>
<div>
<pre class="highlighter-hljs" data-dark-theme="true"><code>/**
* 当前网络类型 1:WIFI 2:移动网络 0:未知
*/
private fun currentNetworkType():Int {
    val cm = App.app.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
    val activeNetwork = cm.activeNetwork
    activeNetwork?.let { network -&gt;
      cm.getNetworkCapabilities(network)?.let { capabilities -&gt;
            if (capabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)) {
                return 1
            } else if (capabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)) {
                return 2
            }
      }
    }
    return 0
}</code></pre>
</div>
<h1><span style="color: rgba(0, 128, 128, 1)">监听网络状态</span></h1>
<p><span style="color: rgba(0, 0, 0, 1)">如果你的需求只是关注是否有网络,你只需要关心 <strong>onAvailable回调</strong><span style="color: rgba(0, 0, 0, 1)">(有网络时回调)</span> 与 <strong>onLost回调</strong>(无网络时回调)</span></p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">private</span> <span style="color: rgba(0, 0, 255, 1)">void</span><span style="color: rgba(0, 0, 0, 1)"> networkListener() {
      ConnectivityManager connectivity </span>=<span style="color: rgba(0, 0, 0, 1)"> (ConnectivityManager) getContext().getApplicationContext().getSystemService(Context.CONNECTIVITY_SERVICE);
      NetworkRequest.Builder builder </span>= <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> NetworkRequest.Builder();
      NetworkRequest request </span>=<span style="color: rgba(0, 0, 0, 1)"> builder.addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
                .addTransportType(NetworkCapabilities.TRANSPORT_WIFI)    </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">表示此网络使用Wi-Fi传输</span>
                .addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR)<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">表示此网络使用蜂窝传输</span>
<span style="color: rgba(0, 0, 0, 1)">                .build();
      connectivity.registerNetworkCallback(request, </span><span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> ConnectivityManager.NetworkCallback() {
            @Override
            </span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">void</span><span style="color: rgba(0, 0, 0, 1)"> onAvailable(Network network) {
                </span><span style="color: rgba(0, 0, 255, 1)">super</span><span style="color: rgba(0, 0, 0, 1)">.onAvailable(network);
                </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">网络可用</span>
                ToastUtils.showShortToast("网络可用"<span style="color: rgba(0, 0, 0, 1)">);
                Log.e(</span>"调试_临时_log", "this_onAvailable"<span style="color: rgba(0, 0, 0, 1)">);

            }

            @Override
            </span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">void</span><span style="color: rgba(0, 0, 0, 1)"> onUnavailable() {
                </span><span style="color: rgba(0, 0, 255, 1)">super</span><span style="color: rgba(0, 0, 0, 1)">.onUnavailable();
                </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">如果在指定的超时时间内未找到网络,则调用</span>
                Log.e("调试_临时_log", "this_onUnavailable"<span style="color: rgba(0, 0, 0, 1)">);
            }

            @Override
            </span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">void</span><span style="color: rgba(0, 0, 0, 1)"> onLost(@NonNull Network network) {
                </span><span style="color: rgba(0, 0, 255, 1)">super</span><span style="color: rgba(0, 0, 0, 1)">.onLost(network);
                </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">当框架的网络严重中断或正常故障结束时调用</span>
                Log.e("调试_临时_log", "this_onLost"<span style="color: rgba(0, 0, 0, 1)">);
            }

            @Override
            </span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">void</span> onBlockedStatusChanged(@NonNull Network network, <span style="color: rgba(0, 0, 255, 1)">boolean</span><span style="color: rgba(0, 0, 0, 1)"> blocked) {
                </span><span style="color: rgba(0, 0, 255, 1)">super</span><span style="color: rgba(0, 0, 0, 1)">.onBlockedStatusChanged(network, blocked);
                </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">当对指定网络的访问被阻止或取消阻止时调用</span>
                Log.e("调试_临时_log", "this_onBlockedStatusChanged"<span style="color: rgba(0, 0, 0, 1)">);
            }

            @Override
            </span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">void</span><span style="color: rgba(0, 0, 0, 1)"> onCapabilitiesChanged(@NonNull Network network, @NonNull NetworkCapabilities networkCapabilities) {
                </span><span style="color: rgba(0, 0, 255, 1)">super</span><span style="color: rgba(0, 0, 0, 1)">.onCapabilitiesChanged(network, networkCapabilities);
                </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">当网络连接到此请求的框架*更改功能但仍满足规定的需求时调用。</span>
                <span style="color: rgba(0, 0, 255, 1)">boolean</span> isInternet = networkCapabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET);<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">获取是否能连接Internet网</span>
                Log.e("调试_临时_log", "this_onCapabilitiesChanged : isInternet = " +<span style="color: rgba(0, 0, 0, 1)"> isInternet);
            }

            @Override
            </span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">void</span> onLosing(@NonNull Network network, <span style="color: rgba(0, 0, 255, 1)">int</span><span style="color: rgba(0, 0, 0, 1)"> maxMsToLive) {
                </span><span style="color: rgba(0, 0, 255, 1)">super</span><span style="color: rgba(0, 0, 0, 1)">.onLosing(network, maxMsToLive);
                </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">当网络即将断开时调用。通常与新替换网络的呼叫配对,
                </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">以实现优雅的切换。如果我们有严重损失*(损失而没有警告),则可能无法调用此方法。</span>
                Log.e("调试_临时_log", "this_onLosing"<span style="color: rgba(0, 0, 0, 1)">);
            }

            @Override
            </span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">void</span><span style="color: rgba(0, 0, 0, 1)"> onLinkPropertiesChanged(@NonNull Network network, @NonNull LinkProperties linkProperties) {
                </span><span style="color: rgba(0, 0, 255, 1)">super</span><span style="color: rgba(0, 0, 0, 1)">.onLinkPropertiesChanged(network, linkProperties);
                </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">当与该请求连接的框架网络更改时调用。</span>
                Log.e("调试_临时_log", "this_onLinkPropertiesChanged"<span style="color: rgba(0, 0, 0, 1)">);
            }
      });
    }</span></pre>
</div>
<p><span style="color: rgba(0, 0, 0, 1)">另外你可以在配置的时候<span style="color: rgba(0, 0, 0, 1)">addTransportType</span>指定监听某个网络状态比如WiFi或者移动网络,<span style="color: rgba(0, 0, 0, 1)">NetworkCapabilities类里还有更多类型:</span></span></p>
<div class="cnblogs_code">
<pre>    <span style="color: rgba(0, 128, 0, 1)">/**</span><span style="color: rgba(0, 128, 0, 1)">
   * 表示此网络使用移动蜂窝传输。
   </span><span style="color: rgba(0, 128, 0, 1)">*/</span>
    <span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">static</span> <span style="color: rgba(0, 0, 255, 1)">final</span> <span style="color: rgba(0, 0, 255, 1)">int</span> TRANSPORT_CELLULAR = 0<span style="color: rgba(0, 0, 0, 1)">;

    </span><span style="color: rgba(0, 128, 0, 1)">/**</span><span style="color: rgba(0, 128, 0, 1)">
   *表示此网络使用Wi-Fi传输。
   </span><span style="color: rgba(0, 128, 0, 1)">*/</span>
    <span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">static</span> <span style="color: rgba(0, 0, 255, 1)">final</span> <span style="color: rgba(0, 0, 255, 1)">int</span> TRANSPORT_WIFI = 1<span style="color: rgba(0, 0, 0, 1)">;

    </span><span style="color: rgba(0, 128, 0, 1)">/**</span><span style="color: rgba(0, 128, 0, 1)">
   * 表示此网络使用蓝牙传输
   </span><span style="color: rgba(0, 128, 0, 1)">*/</span>
    <span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">static</span> <span style="color: rgba(0, 0, 255, 1)">final</span> <span style="color: rgba(0, 0, 255, 1)">int</span> TRANSPORT_BLUETOOTH = 2<span style="color: rgba(0, 0, 0, 1)">;

    </span><span style="color: rgba(0, 128, 0, 1)">/**</span><span style="color: rgba(0, 128, 0, 1)">
   * 表示此网络使用以太网传输。
   </span><span style="color: rgba(0, 128, 0, 1)">*/</span>
    <span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">static</span> <span style="color: rgba(0, 0, 255, 1)">final</span> <span style="color: rgba(0, 0, 255, 1)">int</span> TRANSPORT_ETHERNET = 3<span style="color: rgba(0, 0, 0, 1)">;

    </span><span style="color: rgba(0, 128, 0, 1)">/**</span><span style="color: rgba(0, 128, 0, 1)">
   * 指示此网络使用VPN传输。
   </span><span style="color: rgba(0, 128, 0, 1)">*/</span>
    <span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">static</span> <span style="color: rgba(0, 0, 255, 1)">final</span> <span style="color: rgba(0, 0, 255, 1)">int</span> TRANSPORT_VPN = 4<span style="color: rgba(0, 0, 0, 1)">;

    </span><span style="color: rgba(0, 128, 0, 1)">/**</span><span style="color: rgba(0, 128, 0, 1)">
   * 表示此网络使用支持 Wi-Fi Aware 的传输。
   </span><span style="color: rgba(0, 128, 0, 1)">*/</span>
    <span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">static</span> <span style="color: rgba(0, 0, 255, 1)">final</span> <span style="color: rgba(0, 0, 255, 1)">int</span> TRANSPORT_WIFI_AWARE = 5<span style="color: rgba(0, 0, 0, 1)">;

    </span><span style="color: rgba(0, 128, 0, 1)">/**</span><span style="color: rgba(0, 128, 0, 1)">
   * 表示此网络使用低功耗传输。
   </span><span style="color: rgba(0, 128, 0, 1)">*/</span>
    <span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">static</span> <span style="color: rgba(0, 0, 255, 1)">final</span> <span style="color: rgba(0, 0, 255, 1)">int</span> TRANSPORT_LOWPAN = 6;</pre>
</div>
<h1><span style="color: rgba(22, 145, 121, 1)">Java写法的网络工具类</span></h1>
<p><span style="color: rgba(0, 0, 0, 1)">方便一些用java的开发,直接复制黏贴使用</span></p>
<pre class="language-java highlighter-hljs" data-dark-theme="true"><code>import static android.content.Context.CONNECTIVITY_SERVICE;
import android.content.Context;
import android.net.ConnectivityManager;
import android.net.Network;
import java.io.IOException;
import java.net.URL;
import java.net.URLConnection;

/**
* 网络工具类
*/
public class NetworkUtil {

    /**
   * 检查是否有本地网络,这里的本地网络是指设备是否有连接Wifi网络,但是不保证此网络可以连接外部
   * @return
   */
    public static Boolean hasLocalityNetwork(Context context) {
      ConnectivityManager connectivity = (ConnectivityManager) context.getApplicationContext().getSystemService(CONNECTIVITY_SERVICE);
      if (android.os.Build.VERSION.SDK_INT &gt;= android.os.Build.VERSION_CODES.M) {
            Network network = connectivity.getActiveNetwork();
            return network != null; //如果是null代表没有网络
      }
      return false;
    }

    /**
   * 检查是否有外部网络
   * @param context
   * @return
   */
    public static Boolean hasExternalNetwork(Context context) {
      ConnectivityManager connectivity = (ConnectivityManager) context.getApplicationContext().getSystemService(CONNECTIVITY_SERVICE);
      if (android.os.Build.VERSION.SDK_INT &gt;= android.os.Build.VERSION_CODES.M) {
            Network network = connectivity.getActiveNetwork();
            if (network == null){
                return false;
            }
            //这里创建2个验证网络连接的公共网络地址,你也可以按需多增加几个
            String[] urlArray = {"https://223.5.5.5/", "https://www.baidu.com/"};
            int notConnectCount = 0;
            for (String item :urlArray){
                try {
                  URLConnection openConnection = network.openConnection(new URL(item));
                  openConnection.connect();
                } catch (IOException e){
                  notConnectCount++;
                }
            }
            return notConnectCount &lt; 2;
      }
      return false;
    }
}</code></pre>
<p>&nbsp;End</p>

</div>
<div id="MySignature" role="contentinfo">
    <div style="text-align: center">
    <p style="color:orange;font-size:16px;" >本文来自博客园,作者:观心静 ,转载请注明原文链接:https://www.cnblogs.com/guanxinjing/p/13178067.html </p>
    <div style="color:orange;font-size:16px;">本文版权归作者和博客园共有,欢迎转载,但必须给出原文链接,并保留此段声明,否则保留追究法律责任的权利。 </div>
</div><br><br>
来源:https://www.cnblogs.com/guanxinjing/p/13178067.html
頁: [1]
查看完整版本: Android开发 ConnectivityManager