NetworkCallback เป็นคลาสนามธรรมใน Android SDK สำหรับตรวจสอบการเปลี่ยนแปลงสถานะเครือข่ายผ่าน ConnectivityManager ตาม Android Developers Documentation (2025) การใช้ NetworkCallback ช่วยให้แอปของคุณตอบสนองต่อการเชื่อมต่อ การตัดการเชื่อมต่อ หรือการเปลี่ยนแปลงคุณสมบัติการเชื่อมต่อได้อย่างทันท่วงที ConnectivityManager.NetworkCallback ให้ข้อมูลโดยละเอียดเกี่ยวกับประเภทเครือข่าย พอร์ทัลที่มีข้อจำกัด และการสูญเสียอินเทอร์เน็ตโดยไม่ต้องสอบถามบริการระบบอย่างต่อเนื่อง
ประเด็นสำคัญ
NetworkCallback เป็นคลาสนามธรรมจากแพ็คเกจ android.net ซึ่งเป็นส่วนหนึ่งของ Android SDK มันถูกออกแบบมาเพื่อรับการแจ้งเตือนเกี่ยวกับการเปลี่ยนแปลงสถานะการเชื่อมต่อเครือข่ายผ่านบริการระบบ ConnectivityManager
ก่อน NetworkCallback นักพัฒนาใช้ BroadcastReceiver เพื่อติดตามการเปลี่ยนแปลงเครือข่าย วิธีการนี้ต้องการการลงทะเบียนใน manifest อย่างต่อเนื่อง ทำงานด้วยความล่าช้า และไม่ให้ข้อมูลโดยละเอียดเกี่ยวกับคุณสมบัติการเชื่อมต่อ Android 5.0 (API 21) ได้นำเสนอ NetworkCallback เป็นทางเลือกที่ยืดหยุ่นและมีประสิทธิภาพมากขึ้น
callback ทำงานแบบอะซิงโครนัส: แอปสมัครรับอีเวนต์ผ่าน ConnectivityManager และระบบจะเรียกเมธอดของ callback เมื่อสถานะเครือข่ายเปลี่ยนแปลง ซึ่งช่วยลดความจำเป็นในการ สอบถามสถานะเครือข่ายเป็นระยะ ช่วยประหยัดทรัพยากรแบตเตอรี่และ CPU
ConnectivityManager จัดการอินเทอร์เฟซเครือข่ายทั้งหมดบนอุปกรณ์ — Wi-Fi, ข้อมูลมือถือ, Ethernet, VPN เมื่ออินเทอร์เฟซใด ๆ เหล่านี้เปลี่ยนแปลง ระบบจะสร้างออบเจ็กต์ Network และส่งไปยังเมธอดที่เกี่ยวข้องของ callback ที่ลงทะเบียนไว้ แต่ละ Network มีตัวระบุที่ไม่ซ้ำกันซึ่งเปลี่ยนแปลงเมื่อเชื่อมต่อใหม่
callback ไม่ได้ผูกติดกับประเภทเครือข่ายเฉพาะ — มันสามารถติดตามอินเทอร์เฟซที่มีอยู่ทั้งหมดพร้อมกันได้ ในการกรองประเภทการเชื่อมต่อ ให้ใช้คลาส NetworkRequest ซึ่งระบุ โปรโตคอลการขนส่ง ที่ต้องการ (Wi-Fi, ข้อมูลเซลลูลาร์, Ethernet) และความสามารถของเครือข่าย
การลงทะเบียน NetworkCallback ทำผ่านเมธอด ConnectivityManager.registerNetworkCallback พารามิเตอร์แรกคือ NetworkRequest.Builder ที่อธิบายความต้องการเครือข่าย พารามิเตอร์ที่สองคืออินสแตนซ์ของ callback จำเป็นต้องมีสิทธิ์ ACCESS_NETWORK_STATE ใน manifest
class NetworkMonitor(private val context: Context) {
private val connectivityManager =
context.getSystemService(Context.CONNECTIVITY_SERVICE)
as ConnectivityManager
private val callback =
object : ConnectivityManager.NetworkCallback() {
override fun onAvailable(network: Network) {
Log.d("Network", "Available: ${network}")
}
override fun onLost(network: Network) {
Log.d("Network", "Lost: ${network}")
}
}
fun register() {
connectivityManager.registerNetworkCallback(
NetworkRequest.Builder().build(), callback
)
}
fun unregister() {
connectivityManager.unregisterNetworkCallback(callback)
}
}
แนะนำให้ลงทะเบียน NetworkCallback เมื่อแอปอยู่ในเบื้องหน้าและยกเลิกเมื่อเข้าสู่เบื้องหลัง ใน Activity ให้ใช้ onStart และ onStop เพื่อจัดการวงจรชีวิตของ callback ใน Fragment ให้ใช้ onResume และ onPause
เพื่อลดความซับซ้อนในการจัดการการลงทะเบียน คุณสามารถใช้คอมโพเนนต์ที่รับรู้วงจรชีวิต ไลบรารี AndroidX Lifecycle ช่วยให้คุณสร้าง LifecycleObserver ที่กำหนดเองซึ่งลงทะเบียนและยกเลิก callback โดยอัตโนมัติเมื่อสถานะวงจรชีวิตเปลี่ยนแปลง
สำหรับงานเบื้องหลัง การลงทะเบียนทำใน Service หรือ WorkManager โปรดทราบว่าใน Android 8+ บริการเบื้องหลังมีข้อจำกัดในการเริ่มทำงาน WorkManager พร้อม NetworkType เป็นวิธีที่เชื่อถือได้มากกว่าในการทำงานภายใต้สถานะเครือข่ายที่กำหนด เนื่องจากรวมเข้ากับ API ความเข้ากันได้และเคารพโหมด Doze
NetworkCallback จัดเตรียมชุดเมธอดที่ถูกเรียกเมื่อสถานะเครือข่ายเปลี่ยนแปลง ไม่จำเป็นต้องโอเวอร์ไรด์ทุกเมธอด — ให้ใช้งานเฉพาะที่จำเป็นสำหรับงานเฉพาะของแอปของคุณ onAvailable และ onLost เป็นขั้นต่ำที่จำเป็นสำหรับการตรวจสอบการเชื่อมต่อพื้นฐาน
| เมธอด | เมื่อใดถูกเรียก | พารามิเตอร์ |
|---|---|---|
| onAvailable | เครือข่ายพร้อมใช้งาน | Network — ออบเจ็กต์เครือข่าย |
| onLost | เครือข่ายสูญหายหรือถูกตัดการเชื่อมต่อ | Network — ออบเจ็กต์เครือข่าย |
| onCapabilitiesChanged | ความสามารถของเครือข่ายเปลี่ยนแปลง | Network, NetworkCapabilities |
| onBlockedStatusChanged | สถานะการบล็อกเปลี่ยนแปลง | Network, Boolean |
| onNetworkSuspended | เครือข่ายถูกระงับโดยระบบ | Network |
| onNetworkResumed | เครือข่ายกลับมาทำงานหลังจากการระงับ | Network |
เมธอดนี้เป็นกุญแจสำคัญในการรับข้อมูลโดยละเอียดเกี่ยวกับเครือข่าย พารามิเตอร์ NetworkCapabilities มีแฟลก: NET_CAPABILITY_INTERNET — มีการเข้าถึงอินเทอร์เน็ต, NET_CAPABILITY_NOT_METERED — การเชื่อมต่อไม่จำกัด, NET_CAPABILITY_NOT_ROAMING — ไม่มีการโรมมิ่ง นอกจากนี้ยังสามารถทราบความหน่วงของสัญญาณและแบนด์วิดท์
พอร์ทัลที่มีข้อจำกัดเป็นกรณีพิเศษ: เมื่อเชื่อมต่อกับเครือข่าย Wi-Fi สาธารณะผ่านพอร์ทัล เมธอด onCapabilitiesChanged จะไม่แสดง INTERNET ทันที เครือข่ายพร้อมใช้งานในตอนแรกแต่ไม่มีอินเทอร์เน็ต — ต้องมีการอนุญาตผ่านเบราว์เซอร์ นักพัฒนาต้องพิจารณาความล่าช้านี้ในตรรกะของแอป
ถูกเรียกเมื่อระบบบล็อกการรับส่งข้อมูลเครือข่ายสำหรับแอป — ตัวอย่างเช่น เมื่อเปิดโหมดประหยัดข้อมูลหรือจำกัดข้อมูลเบื้องหลัง onBlockedStatusChanged ช่วยให้แอปทราบว่าคำขอเครือข่ายของมันถูกห้ามชั่วคราวและเปลี่ยนไปประมวลผลในเครื่อง
มาดูการใช้งาน NetworkCallback ในทางปฏิบัติสำหรับตรวจสอบการเข้าถึงอินเทอร์เน็ตและจัดการพอร์ทัลที่มีข้อจำกัด ตัวอย่างด้านล่างแสดงการตรวจสอบ NET_CAPABILITY_INTERNET และการตรวจสอบความถูกต้องของการเชื่อมต่อผ่านคำขอ HTTP ไปยังเซิร์ฟเวอร์ของ Google
val networkCallback = object : ConnectivityManager.NetworkCallback() {
override fun onCapabilitiesChanged(
network: Network,
caps: NetworkCapabilities
) {
val hasInternet = caps.hasCapability(
NetworkCapabilities.NET_CAPABILITY_INTERNET
)
val isMetered = caps.hasCapability(
NetworkCapabilities.NET_CAPABILITY_NOT_METERED
).not()
when {
hasInternet && isMetered ->
Log.d("Network", "Mobile data connected")
hasInternet ->
Log.d("Network", "Wi-Fi connected")
else ->
Log.d("Network", "No internet access")
}
}
override fun onLost(network: Network) {
Log.d("Network", "Connection lost: ${network}")
// หยุดคำขอเครือข่าย
}
}
เมื่อเชื่อมต่อกับเครือข่ายสาธารณะที่ต้องอนุญาต (ร้านกาแฟ สนามบิน) ระบบจะแจ้ง onAvailable ก่อน แต่ onCapabilitiesChanged อาจไม่แสดง INTERNET ในกรณีเช่นนี้ จำเป็นต้องตรวจสอบเพิ่มเติมผ่านคำขอ HTTP ไปยังปลายทางที่เสถียร เช่น https://www.google.com/generate_204
หากคำขอส่งคืนรหัส 204 — อินเทอร์เน็ตพร้อมใช้งาน หากมีการเปลี่ยนเส้นทาง (301, 302, 307) — จำเป็นต้อง อนุญาตผ่านเบราว์เซอร์ ในกรณีนี้ คุณสามารถเปิด WebView หรือ Intent ด้วย URL การเปลี่ยนเส้นทางเพื่อทำการรับรองความถูกต้องบนพอร์ทัล
fun Context.validateInternet(network: Network) {
CoroutineScope(Dispatchers.IO).launch {
try {
val url = URL("https://www.google.com/generate_204")
val connection =
network.openConnection(url) as HttpURLConnection
connection.instanceFollowRedirects = false
connection.connect()
when (connection.responseCode) {
HttpURLConnection.HTTP_NO_CONTENT ->
Log.d("Network", "Internet is available")
in HttpURLConnection.HTTP_MOVED_PERM
..HttpURLConnection.HTTP_TEMP_REDIRECT ->
Log.d("Network", "Captive portal detected")
}
connection.disconnect()
} catch (e: Exception) {
Log.e("Network", "Validation failed: ${e.message}")
}
}
}
ก่อน NetworkCallback วิธีการหลักในการตรวจสอบเครือข่ายคือ BroadcastReceiver พร้อมตัวกรอง android.net.conn.CONNECTIVITY_CHANGE วิธีการนี้มีข้อเสียที่สำคัญ: ความล่าช้าหลายวินาที ไม่มีข้อมูลเกี่ยวกับประเภทอินเทอร์เฟซ และการใช้พลังงานที่เพิ่มขึ้นเนื่องจากการปลุกอุปกรณ์อย่างต่อเนื่อง
ทางเลือกสมัยใหม่คือ LiveData หรือ StateFlow ร่วมกับ NetworkCallback รูปแบบนี้เกี่ยวข้องกับการห่อ callback ในสตรีมเชิงรับที่แจ้ง UI โดยอัตโนมัติเกี่ยวกับการเปลี่ยนแปลงสถานะ ตัวอย่างเช่น MutableStateFlow ที่มีประเภท NetworkStatus อัปเดตภายในเมธอดของ callback และ ViewCollector สมัครรับการเปลี่ยนแปลง
| วิธีการ | API Level | ความหน่วง | ระดับรายละเอียด | การใช้พลังงาน |
|---|---|---|---|---|
| BroadcastReceiver | 1+ | สูง | ต่ำ | สูง |
| NetworkCallback | 21+ | ต่ำ | สูง | ต่ำ |
| ConnectivityManager.getActiveNetwork | 23+ | ทันที | ปานกลาง | ไม่มี |
| NWPathMonitor (iOS) | iOS 12+ | ต่ำ | สูง | ต่ำ |
ตั้งแต่ Android 10 เป็นต้นไป ข้อจำกัดเบื้องหลังเข้มงวดมากขึ้น และ NetworkCallback อาจไม่ถูกเรียกเมื่อแอปอยู่ในเบื้องหลัง สำหรับงานที่สำคัญ — เช่น การโหลดข้อมูลเมื่อเครือข่ายพร้อมใช้งาน — ให้ใช้ WorkManager พร้อมข้อจำกัด NetworkType.CONNECTED WorkManager รับประกันการทำงานเมื่อเงื่อนไขเครือข่ายเป็นไปตามที่กำหนด
ใน Android 12+ มีข้อจำกัดเกี่ยวกับ การลงทะเบียน manifest ของ BroadcastReceiver สำหรับ CONNECTIVITY_ACTION นักพัฒนาต้องย้ายไปใช้ NetworkCallback หรือใช้ WorkManager นโยบาย Google Play ตั้งแต่สิงหาคม 2022 กำหนดให้ลบการลงทะเบียน manifest สำหรับการดำเนินการนี้
คำถามที่พบบ่อย
BroadcastReceiver พร้อม CONNECTIVITY_CHANGE ให้เพียงข้อเท็จจริงของการเปลี่ยนแปลงเครือข่ายโดยไม่มีรายละเอียดและมีความล่าช้าถึงหลายวินาที NetworkCallback ทำงานแบบอะซิงโครนัส ให้ออบเจ็กต์ Network, ประเภทอินเทอร์เฟซ, ความสามารถในการเชื่อมต่อ และไม่ต้องการการลงทะเบียน manifest ซึ่งถูกห้ามใน Android 12+
ใน Android 10+ ข้อจำกัดเบื้องหลังอาจทำให้ NetworkCallback ล่าช้าหรือไม่ถูกเรียก สำหรับงานเบื้องหลัง ให้ใช้ WorkManager พร้อมข้อจำกัด NetworkType — มันรับประกันการทำงานเมื่อเงื่อนไขเป็นไปตามที่กำหนด โดยไม่ขึ้นกับโหมดประหยัดพลังงาน
เรียกเมธอด unregisterNetworkCallback บน ConnectivityManager โดยส่งอินสแตนซ์ callback เดียวกับที่ใช้ในการลงทะเบียน callback ที่ไม่ได้ยกเลิกอาจทำให้หน่วยความจำรั่วไหลเนื่องจากระบบเก็บการอ้างอิงไว้ อย่าลืมยกเลิกใน onStop หรือ onDestroy
NetworkCallback พร้อมใช้งานตั้งแต่ API Level 21 (Android 5.0 Lollipop) สำหรับอุปกรณ์ที่มีเวอร์ชันเก่ากว่า ให้ใช้ BroadcastReceiver หรือไลบรารีความเข้ากันได้ เช่น AndroidX Activity NetworkCallback ซึ่งครอบ API สำหรับการรองรับที่กว้างขึ้น
ใช้ ConnectivityManager.getActiveNetwork (API 23+) ร่วมกับ getNetworkCapabilities เมธอดนี้ส่งคืนเครือข่ายที่ใช้งานอยู่ในปัจจุบันแบบซิงโครนัส โดยไม่ต้องสมัครรับการเปลี่ยนแปลง สำหรับ API 21-22 ให้ใช้ getActiveNetworkInfo ซึ่งถูกทำเครื่องหมายว่าเลิกใช้แล้วในเวอร์ชันใหม่กว่า
สรุป
เราจะพัฒนาแอปพลิเคชันบนมือถือแบบครบวงจร
IT Sectr สร้างแอปพลิเคชัน iOS และ Android สำหรับสตาร์ทอัพและธุรกิจตั้งแต่ปี 2017 เราจะให้คำแนะนำและเสนอวิธีแก้ปัญหาที่ดีที่สุดแก่คุณ
อ่านเพิ่มเติม