【问题标题】:Check internet connectivity android in kotlin在 kotlin 中检查互联网连接 android
【发布时间】:2018-07-02 18:34:39
【问题描述】:

我尝试了this 的答案(已接受的答案)。我可以使用“PING”方法,但是 UI 变黑了,因为它说它会阻塞 UI 线程。它看起来不太好并且令人不安,所以我尝试使用第二种方法“连接到 Internet 上的 Socket”,但我不知道如何在 Kotlin 中使用该类。

这是android studio把Java转成kotlin的结果

package com.mockie.daikokuten.helpers

import android.os.AsyncTask.execute
import android.os.AsyncTask
import java.io.IOException
import java.net.InetSocketAddress
import java.net.Socket


internal class InternetCheck(private val mConsumer: Consumer) : AsyncTask<Void, Void, Boolean>() {
interface Consumer {
    fun accept(internet: Boolean?)
}

init {
    execute()
}

override fun doInBackground(vararg voids: Void): Boolean? {
    try {
        val sock = Socket()
        sock.connect(InetSocketAddress("8.8.8.8", 53), 1500)
        sock.close()
        return true
    } catch (e: IOException) {
        return false
    }

}

override fun onPostExecute(internet: Boolean?) {
    mConsumer.accept(internet)
}
}

但是我不知道如何使用它。我试过这样:

InternetCheck{ internet-> Log.d("test", "asdasdas") }

它不起作用并导致错误。它说我必须通过“消费者”。

我的问题是如何使用该类

【问题讨论】:

    标签: android kotlin


    【解决方案1】:

    更新: 由于 Android 10 使用 NetWorkInfo 类及其方法已过时,现在您必须使用来自 NetworkCapabilities 类的 ConectivityManager 类和 getNetworkCapabilities () 方法

    如何在 Android 中检查连接性?

    科特林

    fun isOnline(context: Context): Boolean {
        val connectivityManager =
            context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
        if (connectivityManager != null) {
            val capabilities =
                connectivityManager.getNetworkCapabilities(connectivityManager.activeNetwork)
            if (capabilities != null) {
                if (capabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)) {
                    Log.i("Internet", "NetworkCapabilities.TRANSPORT_CELLULAR")
                    return true
                } else if (capabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)) {
                    Log.i("Internet", "NetworkCapabilities.TRANSPORT_WIFI")
                    return true
                } else if (capabilities.hasTransport(NetworkCapabilities.TRANSPORT_ETHERNET)) {
                    Log.i("Internet", "NetworkCapabilities.TRANSPORT_ETHERNET")
                    return true
                }
            }
        }
        return false
    }
    

    Java:

    public static boolean isOnline(Context context) {
        ConnectivityManager connectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
    
        if (connectivityManager != null) {
            NetworkCapabilities capabilities = connectivityManager.getNetworkCapabilities(connectivityManager.getActiveNetwork());
            if (capabilities != null) {
                if (capabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)) {
                    Log.i("Internet", "NetworkCapabilities.TRANSPORT_CELLULAR");
                    return true;
                } else if (capabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)) {
                    Log.i("Internet", "NetworkCapabilities.TRANSPORT_WIFI");
                    return true;
                } else if (capabilities.hasTransport(NetworkCapabilities.TRANSPORT_ETHERNET)) {
                    Log.i("Internet", "NetworkCapabilities.TRANSPORT_ETHERNET");
                    return true;
                }
            }
        }
        
        return false;
    }
    

    这两种方法都需要权限:

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

    【讨论】:

    • 答案已更新,谢谢!
    【解决方案2】:

    在 android kotlin 中检查互联网连接

    fun isNetworkAvailable(context: Context?): Boolean {
        if (context == null) return false
        val connectivityManager = context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
            val capabilities = connectivityManager.getNetworkCapabilities(connectivityManager.activeNetwork)
            if (capabilities != null) {
                when {
                    capabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR) -> {
                        return true
                    }
                    capabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI) -> {
                        return true
                    }
                    capabilities.hasTransport(NetworkCapabilities.TRANSPORT_ETHERNET) -> {
                        return true
                    }
                }
            }
        } else {
            val activeNetworkInfo = connectivityManager.activeNetworkInfo
            if (activeNetworkInfo != null && activeNetworkInfo.isConnected) {
                return true
            }
        }
        return false
    }
    

    【讨论】:

    • >= Build.VERSION_CODES.Q 不是 Build.VERSION_CODES.M?这就是linter在AndroidStudio中所说的
    • @ejdrian313 这意味着您当前的 Buildversion(M = Marshmallow,Android 5)低于 Q(Android 10),这是在 if 语句中运行代码所必需的。
    【解决方案3】:

    以这种方式调用 AsyncTask,它应该可以工作。您无需更改 InternetCheck AsyncTask 中的任何内容。基本上,您需要传入一个对象,该对象实现了 InternetCheck 类中定义的 Consumer 接口。

    InternetCheck(object : InternetCheck.Consumer {
        override fun accept(internet: Boolean?) {
            Log.d("test", "asdasdas")
        }
    })
    

    【讨论】:

      【解决方案4】:
       fun verifyAvailableNetwork(activity:AppCompatActivity):Boolean{
            val connectivityManager=activity.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
            val networkInfo=connectivityManager.activeNetworkInfo
            return  networkInfo!=null && networkInfo.isConnected
      }
      

      【讨论】:

      • connectivityManager.activeNetworkInfo 已弃用
      【解决方案5】:

      在清单顶部添加这些权限

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

      这个函数应该可以解决问题。它将根据其连接性返回布尔值

      fun isOnline(context: Context): Boolean {
          val cm = context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
      
          if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
              val n = cm.activeNetwork
              if (n != null) {
                  val nc = cm.getNetworkCapabilities(n)
          //It will check for both wifi and cellular network
                  return nc!!.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR) || nc.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)
              }
              return false
          } else {
              val netInfo = cm.activeNetworkInfo
              return netInfo != null && netInfo.isConnectedOrConnecting
          }
      }
      

      它有一个已弃用的方法以及一个基于您的 api 版本的最新方法。

      【讨论】:

        【解决方案6】:

        试试这个实用方法来检查互联网的可用性。

        fun isNetworkAvailable(context: Context): Boolean {
                val cm = context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
                var activeNetworkInfo: NetworkInfo? = null
                activeNetworkInfo = cm.activeNetworkInfo
                return activeNetworkInfo != null && activeNetworkInfo.isConnectedOrConnecting
            }
        

        希望这会有所帮助。

        【讨论】:

        • 如果连接到 wifi 但没有 Internet 连接,该代码将返回 true
        • @GenoChen 标题和附加的 SO 链接在这里都具有误导性。两人都谈到了检查互联网连接
        • @NaveenTP 我认为您正在避免 X - Y 问题。
        【解决方案7】:

        最短版本

        val Context.isConnected: Boolean
            get() {
                return (getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager)
                   .activeNetworkInfo?.isConnected == true
            }
        

        【讨论】:

        • 这只检查我们是否有网络,而不是我们是否“在线”,即连接到互联网。
        【解决方案8】:

        我把你的课改成了这个

        internal class InternetCheck(private val onInternetChecked: (Boolean) -> Unit) : 
        AsyncTask<Void, Void, Boolean>() {
         init {
             execute()
         }
        
         override fun doInBackground(vararg voids: Void): Boolean {
             return try {
                 val sock = Socket()
                 sock.connect(InetSocketAddress("8.8.8.8", 53), 1500)
                 sock.close()
                 true
             } catch (e: IOException) {
                 false
             }
        
         }
        
         override fun onPostExecute(internet: Boolean) {
             onInternetChecked(internet)
         }
        }
        

        所以你可以使用 lambda 函数,你也不必在那里处理 null 检查:

        InternetCheck{ internet-> Log.d("Connection", "Is connection enabled? "+internet) }
        

        【讨论】:

        • 我被要求在 MainActivity 中添加 StrictMode StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build(); StrictMode.setThreadPolicy(policy); Source: stackoverflow.com/a/22395546/2215337
        【解决方案9】:

        你可以这样使用它:

           InternetCheck(object : InternetCheck.Consumer {
              override fun accept(internet: Boolean?) {
                 Log.d("test", "asdasdas")
              }
           })
        

        有关更多信息,您可以查看此线程: https://youtrack.jetbrains.com/issue/KT-7770

        【讨论】:

        • 感谢您的链接和答案。 :)
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-06-12
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-01-16
        • 2016-08-28
        相关资源
        最近更新 更多