2023-06-01

【Kotlin】socket ping 判斷是否連上網際網路

2023.06.01
ping 的回應速度極快,還可指定等待 timeout 的時間限制,目前為止找到的最佳解


app 層級 build.gradle
  1.  
  2. android {
  3. ...
  4. ...
  5. buildFeatures {
  6. viewBinding true
  7. }
  8. }
  9.  
  10. dependencies {
  11. ...
  12. ...
  13. implementation("org.jetbrains.kotlinx:kotlinx-coroutines-android:1.6.4")
  14. }
  15.  



AndroidManifest.xml
  1.  
  2. <uses-permission android:name="android.permission.INTERNET" />
  3.  
  4. <application
  5. ...
  6. ...
  7.  



activity_main.xml
  1.  
  2. <?xml version="1.0" encoding="utf-8"?>
  3. <androidx.constraintlayout.widget.ConstraintLayout
  4. xmlns:android="http://schemas.android.com/apk/res/android"
  5. xmlns:app="http://schemas.android.com/apk/res-auto"
  6. xmlns:tools="http://schemas.android.com/tools"
  7. android:layout_width="match_parent"
  8. android:layout_height="match_parent"
  9. tools:context=".MainActivity">
  10.  
  11. <TextView
  12. android:id="@+id/lblHello"
  13. android:layout_width="wrap_content"
  14. android:layout_height="wrap_content"
  15. android:text="Hello World!"
  16. app:layout_constraintBottom_toBottomOf="parent"
  17. app:layout_constraintEnd_toEndOf="parent"
  18. app:layout_constraintStart_toStartOf="parent"
  19. app:layout_constraintTop_toTopOf="parent"
  20. android:onClick="pingDuration"
  21. />
  22.  
  23. </androidx.constraintlayout.widget.ConstraintLayout>
  24.  



MainActivity.kt
  1.  
  2. ...
  3. ...
  4.  
  5. import androidx.appcompat.app.AppCompatActivity
  6. import android.os.Bundle
  7. import android.view.View
  8. import kotlinx.coroutines.CoroutineScope
  9. import kotlinx.coroutines.Dispatchers
  10. import kotlinx.coroutines.Job
  11. import kotlinx.coroutines.launch
  12. import java.net.InetSocketAddress
  13. import java.net.Socket
  14. import java.text.SimpleDateFormat
  15. import java.util.Date
  16. import java.util.Locale
  17.  
  18.  
  19. class MainActivity : AppCompatActivity() {
  20. private lateinit var binding: ActivityMainBinding
  21.  
  22. override fun onCreate(savedInstanceState: Bundle?) {
  23. super.onCreate(savedInstanceState)
  24. binding = ActivityMainBinding.inflate(layoutInflater)
  25. val view = binding.root
  26. setContentView(view)
  27. pingDuration()
  28. }
  29.  
  30.  
  31. // 偵測 internet 連線狀況
  32. fun pingDuration() {
  33. val mScope = CoroutineScope(Job() + Dispatchers.IO)
  34. mScope.launch(Dispatchers.IO) {
  35. var sDuration = ""
  36. try {
  37. val a1 = Date()
  38. val timeoutMs = 1000 // 設定 timeout 為 1 秒
  39. val socket = Socket()
  40. val socketAddress = InetSocketAddress("8.8.8.8", 53)
  41. socket.connect(socketAddress, timeoutMs)
  42. socket.close()
  43. val a2 = Date()
  44.  
  45. val durationMillis = a2.time - a1.time // 平均小於 0.07 秒
  46. val hours = durationMillis / (1000 * 60 * 60)
  47. val minutes = durationMillis % (1000 * 60 * 60) / (1000 * 60)
  48. val seconds = durationMillis % (1000 * 60) / 1000
  49. val millis = durationMillis % 1000
  50. sDuration = String.format("%02d:%02d:%02d.%03d", hours, minutes, seconds, millis)
  51. } catch (e: Exception) {
  52. sDuration = "斷網 -- "+e.message
  53. }
  54. runOnUiThread {
  55. binding.lblHello.text = sDuration
  56. }
  57. }
  58. }
  59. }
  60.  



沒有留言:

張貼留言