Membaca status jaringan

Android memungkinkan aplikasi mempelajari perubahan dinamis konektivitas. Gunakan kelas berikut untuk melacak dan menanggapi perubahan konektivitas:

  • ConnectivityManager memberi tahu aplikasi Anda tentang status konektivitas di dalam sistem.
  • Class Network mewakili salah satu jaringan yang saat ini terhubung dengan perangkat. Anda dapat menggunakan objek Network sebagai kunci untuk mengumpulkan informasi tentang jaringan dengan ConnectivityManager atau untuk mengikat soket di jaringan. Saat jaringan terputus, objek Network akan tidak dapat digunakan; meskipun kemudian perangkat dihubungkan kembali ke peralatan yang sama, objek Network baru akan mewakili jaringan baru tersebut.
  • Objek LinkProperties berisi informasi tentang link untuk jaringan, seperti daftar server DNS, alamat IP lokal, dan rute jaringan yang diinstal untuk jaringan.
  • Objek NetworkCapabilities berisi informasi tentang properti jaringan, seperti transport (Wi-Fi, seluler, Bluetooth), dan kemampuan jaringan. Misalnya, Anda dapat membuat kueri objek untuk menentukan apakah jaringan mampu mengirim MMS, berada di belakang captive portal, dan apakah objek berbayar.

Aplikasi tertarik dengan status langsung dari konektivitas kapan pun dapat memanggil metode ConnectivityManager untuk menemukan jenis jaringan apa yang tersedia. Metode ini sangat membantu dalam proses debug, dan secara berkala meninjau ringkasan konektivitas yang tersedia kapan saja. Namun, metode ConnectivityManager sinkron tidak memberi tahu aplikasi Anda tentang apa pun yang terjadi setelah panggilan, sehingga Anda tidak dapat mengupdate UI atau menyesuaikan perilaku aplikasi berdasarkan jaringan putus atau saat kemampuan jaringan berubah.

Karena konektivitas dapat berubah kapan saja dan sebagian besar aplikasi harus memiliki tampilan status jaringan yang selalu segar dan terbaru di perangkat, aplikasi dapat mendaftarkan callback dengan ConnectivityManager agar diberitahukan tentang perubahan yang penting bagi aplikasi. Dengan callback, aplikasi Anda dapat langsung bereaksi ke perubahan relevan apa pun di konektivitas tanpa harus melakukan polling mahal yang dapat melewatkan update cepat.

Mendapatkan status instan

Perangkat Android mungkin mempertahankan banyak koneksi secara bersamaan. Pertama, dapatkan instance ConnectivityManager:

Kotlin

val connectivityManager = getSystemService(ConnectivityManager::class.java)

Java

ConnectivityManager connectivityManager = getSystemService(ConnectivityManager.class);

Gunakan instance ini untuk mendapatkan referensi ke jaringan default saat ini untuk aplikasi Anda:

Kotlin

val currentNetwork = connectivityManager.getActiveNetwork()

Java

Network currentNetwork = connectivityManager.getActiveNetwork();

Dengan referensi ke jaringan, aplikasi Anda dapat mengkueri informasi tentang hal tersebut.

Kotlin

val caps = connectivityManager.getNetworkCapabilities(currentNetwork)
val linkProperties = connectivityManager.getLinkProperties(currentNetwork)

Java

NetworkCapabilities caps = connectivityManager.getNetworkCapabilities(currentNetwork);
LinkProperties linkProperties = connectivityManager.getLinkProperties(currentNetwork);

Mengkueri status instan tidak berguna untuk sebagian besar aplikasi, kecuali untuk proses debug. Untuk fungsionalitas yang lebih berguna, seperti diberi tahu ketika jaringan baru muncul dan jaringan terputus, daftarkan NetworkCallback. Untuk informasi selengkapnya tentang mendaftarkan callback jaringan, lihat Memantau kejadian jaringan.

NetworkCapabilities dan LinkProperties

Objek NetworkCapabilities dan LinkProperties memberikan informasi tentang semua atribut bahwa sistem tahu tentang suatu jaringan. Objek LinkProperties tahu tentang rute, alamat link, nama antarmuka, informasi proxy (jika ada), dan server DNS. Panggil metode yang relevan pada objek LinkProperties untuk mengambil informasi yang Anda butuhkan. Objek NetworkCapabilities mengenkapsulasi informasi tentang transport jaringan dan kemampuannya.

Transport adalah abstraksi dari media fisik melalui tempat jaringan beroperasi. Contoh umum transport adalah Ethernet, Wi-Fi, dan seluler, tetapi juga dapat berupa VPN atau Wi-Fi Peer-to-Peer.

Di Android, suatu jaringan dapat memiliki beberapa transport secara bersamaan. Contohnya adalah VPN yang beroperasi melalui jaringan Wi-Fi dan seluler; jaringan semacam itu akan memiliki transport Wi-Fi, seluler, dan VPN. Untuk mengetahui apakah jaringan memiliki transport tertentu, gunakan NetworkCapabilities.hasTransport(int) dengan salah satu konstanta NetworkCapabilities.TRANSPORT_*.

Kemampuan adalah properti jaringan. Contoh kemampuan meliputi MMS, NOT_METERED, dan INTERNET. Jaringan dengan kemampuan MMS dapat mengirim dan menerima pesan Multimedia Messaging Service, sedangkan jaringan tanpa kemampuan ini tidak dapat melakukannya. Jaringan dengan kemampuan NOT_METERED tidak menagih pengguna untuk data. Aplikasi Anda dapat memeriksa kemampuan yang sesuai dengan menggunakan metode NetworkCapabilities.hasCapability(int) dengan salah satu konstanta NetworkCapabilities.NET_CAPABILITY_*.

Konstanta NET_CAPABILITY_* yang paling berguna mencakup:

  • NET_CAPABILITY_INTERNET: Kemampuan ini menunjukkan bahwa jaringan disiapkan untuk mengakses internet. Perhatikan bahwa ini adalah tentang penyiapan dan bukan kemampuan sebenarnya untuk menjangkau server publik. Misalnya, jaringan dapat disiapkan untuk mengakses internet, tetapi bergantung pada captive portal.

    Jaringan seluler operator biasanya memiliki kemampuan INTERNET, sedangkan jaringan Wi-Fi P2P lokal biasanya tidak. Untuk konektivitas yang sebenarnya, lihat NET_CAPABILITY_VALIDATED.

  • NET_CAPABILITY_NOT_METERED: Kemampuan ini menunjukkan bahwa jaringan tidak berbayar. Jaringan dianggap sebagai berbayar saat pengguna sensitif terhadap penggunaan data yang berat pada koneksi tersebut karena biaya keuangan, batasan data, atau masalah baterai/ performa.

  • NET_CAPABILITY_NOT_VPN: Kemampuan ini menunjukkan bahwa jaringan tersebut bukan virtual private network.

  • NET_CAPABILITY_VALIDATED: Kemampuan ini menunjukkan bahwa jaringan ditemukan telah memberikan akses aktual ke internet publik saat terakhir kali jaringan diperiksa. Jaringan di balik captive portal atau jaringan yang tidak memberikan resolusi nama domain tidak memiliki kemampuan ini. Ini adalah hal terdekat yang sistem dapat beri tahu tentang jaringan yang sebenarnya menyediakan akses, meskipun pada prinsipnya jaringan yang divalidasi tetap dapat bergantung pada pemfilteran berdasarkan IP atau mengalami kehilangan konektivitas tiba-tiba karena masalah seperti sinyal yang buruk.

  • NET_CAPABILITY_CAPTIVE_PORTAL: Kemampuan ini menunjukkan bahwa jaringan telah ditemukan memiliki captive portal saat terakhir kali diperiksa.

Ada kemampuan lain yang mungkin menarik untuk aplikasi yang lebih khusus. Baca definisi parameter di NetworkCapabilities.hasCapability(int) untuk mengetahui informasi selengkapnya.

Kemampuan jaringan dapat berubah kapan saja. Jika mendeteksi captive portal, sistem akan menampilkan notifikasi yang mengajak pengguna untuk login. Sementara ini sedang berlangsung, jaringan memiliki kemampuan NET_CAPABILITY_INTERNET dan NET_CAPABILITY_CAPTIVE_PORTAL, tetapi tidak memiliki kemampuan NET_CAPABILITY_VALIDATED. Saat pengguna mengambil tindakan dan login ke halaman captive portal, perangkat menjadi dapat mengakses internet publik dan jaringan memperoleh kemampuan NET_CAPABILITY_VALIDATED serta kehilangan kemampuan NET_CAPABILITY_CAPTIVE_PORTAL. Demikian juga, transport jaringan dapat berubah secara dinamis. Misalnya, VPN dapat mengonfigurasi ulang dirinya sendiri untuk menggunakan jaringan yang lebih cepat yang baru muncul, seperti beralih dari seluler ke Wi-Fi untuk jaringan dasarnya. Dalam hal ini, jaringan kehilangan transport TRANSPORT_CELLULAR dan mendapatkan transport TRANSPORT_WIFI, sekaligus mempertahankan transport TRANSPORT_VPN.

Memantau kejadian jaringan

Untuk mengetahui tentang kejadian jaringan, gunakan class NetworkCallback bersamaan dengan ConnectivityManager.registerDefaultNetworkCallback(NetworkCallback) dan ConnectivityManager.registerNetworkCallback(NetworkCallback). Kedua metode ini memiliki tujuan yang berbeda.

Semua aplikasi Android memiliki jaringan default. Sistem memutuskan jaringan mana yang seharusnya menjadi jaringan default. Sistem ini biasanya memilih jaringan tidak berbayar dibandingkan yang berbayar dan jaringan yang lebih cepat dibandingkan yang lebih lambat. Saat aplikasi memberikan permintaan jaringan, seperti dengan HttpsURLConnection, sistem memenuhi permintaan ini dengan menggunakan jaringan default. Aplikasi juga dapat mengirimkan traffic di jaringan lain. Untuk informasi selengkapnya, lihat Jaringan tambahan

Jaringan yang disetel sebagai jaringan default dapat berubah kapan saja selama masa aktif aplikasi. Contoh umumnya adalah perangkat yang berada dalam jangkauan titik akses Wi-Fi yang aktif, tidak berbayar, dan lebih cepat daripada seluler. Perangkat akan terhubung ke titik akses ini dan mengalihkan jaringan default untuk semua aplikasi ke jaringan Wi-Fi baru.

Jika jaringan baru menjadi default, semua koneksi baru yang dibuka aplikasi akan menggunakan jaringan ini. Pada waktu tertentu, semua koneksi yang ada di jaringan default sebelumnya akan dihentikan secara paksa. Jika penting bagi aplikasi untuk mengetahui kapan jaringan default berubah, aplikasi harus mendaftarkan callback jaringan default seperti berikut:

Kotlin

connectivityManager.registerDefaultNetworkCallback(object : ConnectivityManager.NetworkCallback() {
    override fun onAvailable(network : Network) {
        Log.e(TAG, "The default network is now: " + network)
    }

    override fun onLost(network : Network) {
        Log.e(TAG, "The application no longer has a default network. The last default network was " + network)
    }

    override fun onCapabilitiesChanged(network : Network, networkCapabilities : NetworkCapabilities) {
        Log.e(TAG, "The default network changed capabilities: " + networkCapabilities)
    }

    override fun onLinkPropertiesChanged(network : Network, linkProperties : LinkProperties) {
        Log.e(TAG, "The default network changed link properties: " + linkProperties)
    }
})

Java

connectivityManager.registerDefaultNetworkCallback(new ConnectivityManager.NetworkCallback() {
    @Override
    public void onAvailable(Network network) {
        Log.e(TAG, "The default network is now: " + network);
    }

    @Override
    public void onLost(Network network) {
        Log.e(TAG, "The application no longer has a default network. The last default network was " + network);
    }

    @Override
    public void onCapabilitiesChanged(Network network, NetworkCapabilities networkCapabilities) {
        Log.e(TAG, "The default network changed capabilities: " + networkCapabilities);
    }

    @Override
    public void onLinkPropertiesChanged(Network network, LinkProperties linkProperties) {
        Log.e(TAG, "The default network changed link properties: " + linkProperties);
    }
});

Saat jaringan baru menjadi default, aplikasi akan menerima panggilan ke onAvailable(Network) untuk jaringan baru. Implementasikan onCapabilitiesChanged(Network,NetworkCapabilities), onLinkPropertiesChanged(Network,LinkProperties), atau keduanya agar bereaksi dengan sesuai terhadap perubahan konektivitas.

Untuk callback yang didaftarkan dengan registerDefaultNetworkCallback(), onLost() berarti jaringan telah kehilangan status default. Koneksi mungkin terputus atau tidak terputus.

Meskipun Anda dapat mengetahui tentang transport yang digunakan jaringan default dengan membuat kueri NetworkCapabilities.hasTransport(int), ini adalah proxy yang buruk untuk bandwidth atau nilai berbayar jaringan. Aplikasi Anda tidak boleh berasumsi bahwa Wi-Fi selalu tidak berbayar dan selalu menyediakan bandwidth yang lebih baik daripada seluler. Sebagai gantinya, gunakan NetworkCapabilities.getLinkDownstreamBandwidthKbps() untuk mengukur bandwidth, dan NetworkCapabilites.hasCapability(int) dengan argumen NET_CAPABILITY_NOT_METERED untuk menentukan nilai berbayar. Lihat NetworkCapabilities dan LinkProperties untuk informasi selengkapnya.

Secara default, metode callback dipanggil di thread konektivitas aplikasi Anda, yang merupakan thread terpisah yang digunakan oleh ConnectivityManager. Jika implementasi callback Anda perlu melakukan pekerjaan yang lebih lama, panggil callback pada thread pekerja terpisah dengan menggunakan varian ConnectivityManager.registerDefaultNetworkCallback(NetworkCallback, Handler).

Batalkan pendaftaran callback jika Anda tidak menggunakannya lagi dengan memanggil ConnectivityManager.unregisterNetworkCallback(NetworkCallback). Aktivitas utama Anda di onPause() adalah tempat yang tepat untuk melakukannya, terutama jika Anda mendaftarkan callback di onResume().

Jaringan tambahan

Meskipun jaringan default adalah satu-satunya jaringan yang relevan untuk sebagian besar aplikasi, beberapa aplikasi mungkin tertarik dengan jaringan lain yang tersedia. Untuk mencari tahu tentang hal ini, aplikasi membuat NetworkRequest yang cocok dengan kebutuhan aplikasi dan memanggil ConnectivityManager.registerNetworkCallback(NetworkRequest, NetworkCallback). Proses ini mirip dengan memantau jaringan default. Perbedaan utamanya adalah, saat hanya ada satu jaringan default yang berlaku kapan pun untuk aplikasi, versi ini memungkinkan aplikasi Anda melihat semua jaringan yang tersedia secara bersamaan, sehingga panggilan ke onLost(Network) berarti jaringan tersebut telah terputus seterusnya, bukan tidak lagi default.

Aplikasi ini membuat NetworkRequest untuk memberi tahu ConnectivityManager jenis jaringan apa yang ingin dipantau. Misalnya, jika aplikasi Anda hanya tertarik pada koneksi internet yang tidak berbayar:

Kotlin

val request = NetworkRequest.Builder()
  .addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED)
  .addCapability(NET_CAPABILITY_INTERNET)
  .build()

connectivityManager.registerNetworkCallback(request, myNetworkCallback)

Java

NetworkRequest request = new NetworkRequest.Builder()
  .addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED)
  .addCapability(NET_CAPABILITY_INTERNET)
  .build();

connectivityManager.registerNetworkCallback(request, myNetworkCallback);

Hal ini akan memastikan bahwa aplikasi Anda memantau semua perubahan mengenai semua jaringan tidak berbayar di sistem.

Untuk callback jaringan default, ada versi registerNetworkCallback(NetworkRequest, NetworkCallback, Handler) yang menerima Handler sehingga tidak memuat thread Connectivity aplikasi Anda. Panggil ConnectivityManager.unregisterNetworkCallback(NetworkCallback) saat callback tidak relevan lagi. Suatu aplikasi dapat mendaftarkan beberapa callback jaringan secara serentak.

Untuk mempermudah, objek NetworkRequest berisi kemampuan umum yang dibutuhkan sebagian besar aplikasi, termasuk hal berikut:

Saat menulis aplikasi, Anda harus memeriksa jaringan default untuk mencari tahu apakah cocok dengan kasus penggunaan dan memperjelas apakah aplikasi Anda harus diberi tahu tentang jaringan yang tidak memiliki kemampuan ini. Sebaliknya, aplikasi Anda harus menambahkan kemampuan agar tidak dipanggil atas perubahan konektivitas apa pun di jaringan yang tidak berinteraksi dengan aplikasi Anda.

Misalnya, jika harus mengirimkan pesan MMS, aplikasi harus menambahkan NET_CAPABILITY_MMS ke NetworkRequest-nya agar tidak mengetahui semua jaringan yang tidak dapat mengirimkan MMS, atau TRANSPORT_WIFI_AWARE jika aplikasi hanya tertarik pada konektivitas Wi-Fi P2P. NET_CAPABILITY_INTERNET dan NET_CAPABILITY_VALIDATED akan berguna jika Anda tertarik dengan kemampuan untuk mentransfer data dengan server di internet.

Contoh

Bagian ini menjelaskan urutan callback yang mungkin diperoleh aplikasi jika mendaftarkan callback default dan callback reguler di perangkat yang saat ini memiliki konektivitas seluler. Dalam contoh ini, perangkat menghubungkan ke titik akses Wi-Fi yang bagus, lalu memutuskan koneksinya. Bagian ini juga mengasumsikan perangkat mengaktifkan setelan Data seluler selalu aktif.

Linimasa ini adalah sebagai berikut:

  1. Saat aplikasi memanggil registerNetworkCallback(), callback segera menerima panggilan dari onAvailable(), onNetworkCapabilitiesChanged(), dan onLinkPropertiesChanged() untuk jaringan seluler, karena hanya jaringan tersebut yang aktif. Jika jaringan lain telah tersedia, aplikasi juga akan menerima callback untuk jaringan lainnya.

    Diagram status menunjukkan kejadian callback jaringan terdaftar dan callback yang dipicu oleh kejadian.
    Gambar 1. Status aplikasi setelah memanggil registerNetworkCallback()

  2. Kemudian, aplikasi akan memanggil registerDefaultNetworkCallback(). Callback jaringan default mulai menerima panggilan ke onAvailable(), onNetworkCapabilitiesChanged(), dan onLinkPropertiesChanged() untuk jaringan seluler karena jaringan seluler adalah jaringan default. Jika jaringan non-default lain telah aktif, aplikasi tidak akan menerima panggilan untuk jaringan non-default.

    Diagram status menunjukkan kejadian mendaftarkan callback jaringan dan
callback yang dipicu oleh kejadian.
    Gambar 2. Status aplikasi setelah mendaftarkan jaringan default

  3. Kemudian, perangkat akan terhubung ke jaringan Wi-Fi (tidak berbayar). Callback jaringan reguler menerima panggilan ke onAvailable(), onNetworkCapabilitiesChanged(), dan onLinkPropertiesChanged() untuk jaringan Wi-Fi.

    Diagram status menunjukkan callback yang dipicu saat aplikasi terhubung ke
jaringan baru
    Gambar 3. Status aplikasi setelah terhubung ke jaringan Wi-Fi yang tidak berbayar

  4. Pada saat ini, jaringan Wi-Fi mungkin memerlukan waktu untuk memvalidasi. Dalam hal ini, panggilan onNetworkCapabilitiesChanged() untuk callback jaringan reguler tidak akan menyertakan kemampuan NET_CAPABILITY_VALIDATED. Setelah beberapa saat, aplikasi akan menerima panggilan ke onNetworkCapabilitiesChanged() yang menyertakan kemampuan baru NET_CAPABILITY_VALIDATED. Pada umumnya, validasi dilakukan dengan sangat cepat.

    Saat jaringan Wi-Fi memvalidasi, sistem akan memilihnya ke jaringan seluler, terutama karena jaringan tidak berbayar. Jaringan Wi-Fi menjadi jaringan default, sehingga callback jaringan default menerima panggilan ke onAvailable(), onNetworkCapabilitiesChanged(), dan onLinkPropertiesChanged() untuk jaringan Wi-Fi. Jaringan seluler mengarah ke latar belakang, dan callback jaringan reguler menerima panggilan ke onLosing() untuk jaringan seluler.

    Karena contoh ini mengasumsikan data seluler selalu aktif untuk perangkat ini, jaringan seluler tidak akan pernah terputus. Jika setelan dinonaktifkan, jaringan seluler akan terputus setelah beberapa saat, dan callback jaringan reguler akan menerima panggilan ke onLost().

    Diagram status menunjukkan callback yang dipicu saat koneksi jaringan
Wi-Fi memvalidasi
    Gambar 4. Status aplikasi setelah jaringan Wi-Fi memvalidasi

  5. Kemudian, perangkat tiba-tiba terputus dari Wi-Fi, karena data berada di luar jangkauan. Karena Wi-Fi terputus, callback jaringan reguler akan menerima panggilan ke onLost() untuk Wi-Fi. Karena seluler adalah jaringan default baru, callback jaringan default menerima panggilan ke onAvailable(), onNetworkCapabilitiesChanged(), dan onLinkPropertiesChanged() untuk jaringan seluler.

    Diagram status menunjukkan callback yang dipicu saat koneksi jaringan
Wi-Fi terputus
    Gambar 5. Status aplikasi setelah memutuskan koneksi dari jaringan Wi-Fi

Jika setelan data seluler yang selalu aktif telah dinonaktifkan, maka saat koneksi Wi-Fi terputus, perangkat akan mencoba menghubungkan kembali ke seluler. Gambar akan mirip, namun dengan penundaan tambahan yang singkat untuk panggilan onAvailable(), dan callback jaringan reguler juga akan menerima panggilan ke onAvailable(), onNetworkCapabilitiesChanged(), dan onLinkPropertiesChanged() karena seluler hanya akan memiliki akan tersedia.

Batasan penggunaan jaringan untuk transfer data

Dapat melihat jaringan dengan callback jaringan bukan berarti aplikasi Anda dapat menggunakan jaringan untuk transfer data. Beberapa jaringan tidak menyediakan konektivitas internet (lihat NET_CAPABILITY_INTERNET dan NET_CAPABILITY_VALIDATED untuk memeriksa konektivitas internet), dan beberapa jaringan mungkin terbatas untuk aplikasi yang memiliki hak istimewa.

Penggunaan jaringan latar belakang juga bergantung pada pemeriksaan izin. Jika aplikasi Anda ingin menggunakan jaringan latar belakang, aplikasi tersebut memerlukan izin CHANGE_NETWORK_STATE. Aplikasi dengan izin ini juga dapat meminta sistem agar mencoba menampilkan jaringan yang saat ini tidak aktif, seperti jaringan seluler saat perangkat terhubung ke jaringan Wi-Fi. Aplikasi seperti ini akan memanggil ConnectivityManager.requestNetwork(NetworkRequest, NetworkCallback) dengan NetworkCallback untuk dipanggil saat jaringan ditampilkan.