【问题标题】:Android - Programmatically check internet connection and display dialog if notConnectedAndroid - 以编程方式检查互联网连接并在未连接时显示对话框
【发布时间】:2013-07-26 15:51:12
【问题描述】:

我正在做一个实时项目。当用户点击应用程序时。欢迎屏幕出现(该屏幕上有一个网络视图)。如果未连接互联网,则应用程序崩溃。基本上,我的问题是以编程方式检查移动设备是否连接到互联网。如果没有,则不要从 web 服务获取数据到 webview 并显示一个对话框,显示“检查您的互联网连接”

在进行研究时,我发现了很多东西,并且我已经尝试实施。但是,它不能满足我的要求

我的代码是,

public boolean isOnline() {
    ConnectivityManager cm =
        (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
    NetworkInfo netInfo = cm.getActiveNetworkInfo();
    if (netInfo != null && netInfo.isConnectedOrConnecting()) {
        return true;
    }
    else
    {
        Description.setVisibility(View.INVISIBLE);
        new AlertDialog.Builder(WelcomePage.this)
        .setTitle(getResources().getString(R.string.app_name))
        .setMessage(
                getResources().getString(
                        R.string.internet_error))
        .setPositiveButton("OK", null).show();
    }
    return false;
}

我在doInBackground()AsyncTask 中调用这个函数

请帮忙!

【问题讨论】:

  • 这是否检查互联网连接或 wifi 连接。我怀疑是后者,而互联网连接只能通过 ping 来验证?

标签: android android-webview android-internet android-websettings


【解决方案1】:

你可以查看这个库:

https://github.com/novoda/merlin

您只需implement Connectable,当网络出现故障或恢复时,您都会收到回调。

因此,您可以在这种情况下显示您的对话框。

你也可以查询库的当前状态,选择不做你的网络任务

创建 Merlin(使用 Merlin.Builder())

merlin = new Merlin.Builder().withConnectableCallbacks().build(context);

在您的活动中绑定和取消绑定服务

@Override
protected void onResume() {
    super.onResume();
    merlin.bind();
}

@Override
protected void onPause() {
    super.onPause();
    merlin.unbind();
}

注册回调

merlin.registerConnectable(new Connectable() {
        @Override
        public void onConnect() {
            // Do something!
        }
});

演示中的MerlinActivity 展示了一种将 Merlin 从主应用程序代码中整理出来的简单方法。

【讨论】:

  • 如果您转到github.com/novoda/merlin 并向下滚动,请阅读自述文件,它的解释非常简单
  • 每次我使用 merlin 完成第二个活动时,merlin 都会不断泄漏(第一次也是在使用它)(我在 onPause 和 onDestroy 中有 merlin.unbind 和 merlin == null)
  • @KrzysztofDziuba 如果您在 GH 回购github.com/novoda/merlin/issues 上打开问题,我们将很乐意帮助您处理 Merlin 问题。
【解决方案2】:

终于,我得到了答案。

ConnectivityManager conMgr =  (ConnectivityManager)getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo netInfo = conMgr.getActiveNetworkInfo();
if (netInfo == null){
    Description.setVisibility(View.INVISIBLE);
    new AlertDialog.Builder(WelcomePage.this)
        .setTitle(getResources().getString(R.string.app_name))
        .setMessage(getResources().getString(R.string.internet_error))
        .setPositiveButton("OK", null).show();
}else{
    dialog = ProgressDialog.show(WelcomePage.this, "", "Loading...", true,false);
    new Welcome_Page().execute();
}

【讨论】:

  • 这不应该是预期的答案,因为您自己问如何检查 Internet 连接而不是网络连接,而上面的答案显示了后一部分
  • 如果设备已连接到网络但没有数据(互联网)余额可供使用,这将执行 Welcome_Page()
  • 您必须小心,因为 Internet 连接与网络连接不同。我强烈建议你使用像stackoverflow.com/a/17880697/245638 这样可靠的东西,或者查看源代码
【解决方案3】:

NetworkInfo 类在 API 29 (Android 10.0) 中被弃用,更多详情请参见此处:

This class was deprecated in API level 29. Use ConnectivityManager#getNetworkCapabilities or ConnectivityManager#getLinkProperties to get information synchronously

更新代码(使用 Kotlin)

var isConnected = false
val connectivityManager = getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
    val networkCapabilities = connectivityManager.activeNetwork ?: return false
    val activeNetwork = connectivityManager.getNetworkCapabilities(networkCapabilities) ?: return false
    isConnected = when {
        activeNetwork.hasTransport(NetworkCapabilities.TRANSPORT_WIFI) -> true
        activeNetwork.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR) -> true
        activeNetwork.hasTransport(NetworkCapabilities.TRANSPORT_ETHERNET) -> true
        else -> false
    }
} else {
    connectivityManager.run {
        activeNetworkInfo?.run {
            isConnected = when (type) {
                ConnectivityManager.TYPE_WIFI -> true
                ConnectivityManager.TYPE_MOBILE -> true
                ConnectivityManager.TYPE_ETHERNET -> true
                else -> false
            }
        }
    }
}

【讨论】:

    【解决方案4】:

    检查互联网连接

     ConnectivityManager mgr = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
     NetworkInfo netInfo = mgr.getActiveNetworkInfo();
    
            if (netInfo != null) {
                if (netInfo.isConnected()) {
                    // Internet Available
                }else {
                   //No internet
                }
            } else {
                //No internet
            }
    

    【讨论】:

      【解决方案5】:

      这是检查您的互联网连接的简单功能。如果已连接,则返回 true,否则返回 false。

       public boolean isInternetOn() {
      
              // get Connectivity Manager object to check connection
              ConnectivityManager connec =
                      (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
      
              // Check for network connections
              if (connec.getNetworkInfo(0).getState() == android.net.NetworkInfo.State.CONNECTED ||
                      connec.getNetworkInfo(0).getState() == android.net.NetworkInfo.State.CONNECTING ||
                      connec.getNetworkInfo(1).getState() == android.net.NetworkInfo.State.CONNECTING ||
                      connec.getNetworkInfo(1).getState() == android.net.NetworkInfo.State.CONNECTED) {
      
      
                  return true;
      
              } else if (
                      connec.getNetworkInfo(0).getState() == android.net.NetworkInfo.State.DISCONNECTED ||
                              connec.getNetworkInfo(1).getState() == android.net.NetworkInfo.State.DISCONNECTED) {
      
      
                  return false;
              }
              return false;
          }
      }
      

      这是一个检查互联网连接并检查有效或包含在服务器 this 中的 URL 的项目。

      【讨论】:

        【解决方案6】:
        if (InternetConnection.checkConnection(context)) {
            // Internet Available...
        } else {
            // Internet Not Available...
        }
        

        只复制下面的类

        public class InternetConnection {
        
            /** CHECK WHETHER INTERNET CONNECTION IS AVAILABLE OR NOT */
            public static boolean checkConnection(Context context) {
                final ConnectivityManager connMgr = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
        
                NetworkInfo activeNetworkInfo = connMgr.getActiveNetworkInfo();
        
                if (activeNetworkInfo != null) { // connected to the internet
                    Toast.makeText(context, activeNetworkInfo.getTypeName(), Toast.LENGTH_SHORT).show();
        
                    if (activeNetworkInfo.getType() == ConnectivityManager.TYPE_WIFI) {
                        // connected to wifi
                        return true;
                    } else if (activeNetworkInfo.getType() == ConnectivityManager.TYPE_MOBILE) {
                        // connected to the mobile provider's data plan
                        return true;
                    }
                }
                return false;
            }
        }
        

        授予以下权限以显示

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

        【讨论】:

          【解决方案7】:

          我尝试了上述不同的方法,除此之外,我在某些情况下被抓到了。所以最后,我使用下面的代码 sn-p 进行网络调用...

          try {
              InetAddress address = InetAddress.getByName("www.stackoverflow.com");
              //Connected to working internet connection
          } catch (UnknownHostException e) {
              e.printStackTrace();
              //Internet not available
          }
          

          这在许多方面都很有用。如果这种方法有问题,请告诉我。

          【讨论】:

          • 这可行,但必须在工作线程中执行。上面的代码给出了 Network on main thread 异常。
          • 同意@SkyTreasure,这取决于我们如何使用这个sn-p ;)
          • @SkyTreasure 能否给出在主线程中使用它的代码?
          【解决方案8】:
           public boolean isOnline() {
                  NetworkInfo activeNetworkInfo = ((ConnectivityManager) 
                  getSystemService(CONNECTIVITY_SERVICE)).getActiveNetworkInfo();
                  return activeNetworkInfo != null && 
                  activeNetworkInfo.isConnectedOrConnecting();
              }
          

          【讨论】:

            【解决方案9】:

            您的设备具有网络连接并不意味着您可以访问互联网。它可以是没有互联网的 wifi,也可以是没有数据包的数据 SIM。 从 API 23 开始,您可以使用下面的方法来检查它。您可以在 UI 上执行此操作。或者在广播接收器中。

            ConnectivityManager cm = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
            Network currentnetwork = cm.getActiveNetwork();
            if (currentnetwork != null) {
                    if (cm.getNetworkCapabilities(currentnetwork).hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET) && cm.getNetworkCapabilities(currentnetwork).hasCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED)) {
                        
                        // do your stuff. We have internet.
                } else {
                        // We have no internet connection.
                    }
            
               } else {
                   // We have no internet connection.
               }
            

            【讨论】:

              【解决方案10】:
              private boolean isOnline() {
                      ConnectivityManager connMgr = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
                      NetworkInfo networkInfo = connMgr.getActiveNetworkInfo();
                      return (networkInfo != null && networkInfo.isConnected());
                  }
              

              这是官方的方式,谷歌也使用同样的方式来检查安卓设备的互联网连接。你可以在这里查看 - link。 这是一个非常完美的方法,它实际上检查互联网是否正常工作。

              现在你的具体问题,使用一个计时器类,然后在 if(isOnline) 然后 toast 中放一个 toast。

              【讨论】:

                【解决方案11】:

                doInBackground 在与主 UI 不同的线程上运行,因此您无法在此处创建显示对话框。相反,在您的 AsyncTask 中覆盖 onPreExecute,并在那里进行测试。

                【讨论】:

                • @Java_Android 它对我来说看起来不错 - 它只需要移动到不同的方法(在 UI 线程中运行的方法)。
                • @Java_Android 请阅读我的回答。您需要在 onPreExecute 中执行此操作,您可以在 AsyncTask 中覆盖它。按照提供的链接获得更多帮助。
                • @Phil..Buddy,我也试过了......它既不能在主线程的“onCreate”中工作,也不能在“AsyncTask”的“onPreExecute”中工作
                【解决方案12】:

                关于如何检查互联网连接的更新 Kotlin 和 Android 29 版本(getNetworkInfo 在 SDK 29 中已弃用)适用于 minSDK >= 23:

                fun hasInternet(): Boolean {
                    val connectivityManager = appContainer.contextProvider.currentAppContext()
                        .getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
                    val network = connectivityManager.activeNetwork
                
                    val capabilities = connectivityManager.getNetworkCapabilities(network)
                    var hasInternet = false
                    capabilities?.let {
                        hasInternet = it.hasCapability(NET_CAPABILITY_INTERNET)
                    }
                    return hasInternet
                }
                

                【讨论】:

                  【解决方案13】:

                  这组代码可帮助您检查从 API 级别 16 到 30 的互联网连接是否可用

                  @SuppressWarnings("deprecation")
                  public static boolean isInternetAvailable(Activity activity) {
                      ConnectivityManager conMgr = (ConnectivityManager) activity.getSystemService(Context.CONNECTIVITY_SERVICE);
                  
                      if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                          Network network = conMgr.getActiveNetwork();
                          NetworkCapabilities networkCapabilities = conMgr.getNetworkCapabilities(network);
                          if (networkCapabilities != null) {
                              return networkCapabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET);
                          } else return false;
                      } else {
                          // below API Level 23
                          return conMgr.getActiveNetworkInfo() != null
                                  && conMgr.getActiveNetworkInfo().isAvailable()
                                  && conMgr.getActiveNetworkInfo().isConnected();
                      }
                  }
                  

                  【讨论】:

                    【解决方案14】:

                    Internet 连接也可以在onCreate()onResume() 方法中检查。无需在 AsyncTask 内部调用。

                    或者你可以在调用AsyncTask execute()方法之前调用

                    if(isOnline)
                    {
                       MyAsyncTask task=new MyAMyAsyncTask();
                       task.execute();
                    
                    }
                    
                    else
                    {
                    // no internet connection
                    }
                    

                    【讨论】:

                      猜你喜欢
                      • 1970-01-01
                      • 2015-03-31
                      • 2012-04-16
                      • 1970-01-01
                      • 1970-01-01
                      • 2012-06-12
                      • 1970-01-01
                      • 1970-01-01
                      • 2011-05-30
                      相关资源
                      最近更新 更多