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 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 berhenti digunakan. Meskipun perangkat nanti terhubung kembali ke perangkat yang sama, objek Network baru akan mewakili jaringan baru.
  • 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 dapat mengirim MMS, berada di belakang captive portal, atau diukur.

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 metode ini tidak memungkinkan Anda mengupdate UI. Aplikasi juga tidak dapat menyesuaikan perilaku aplikasi berdasarkan koneksi jaringan atau saat kemampuan jaringan berubah.

Konektivitas dapat berubah kapan saja, dan sebagian besar aplikasi perlu 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.

Penggunaan NetworkCallback dan cara lain untuk mengetahui status konektivitas perangkat tidak memerlukan izin tertentu. Namun, beberapa jaringan tunduk pada izin tertentu. Misalnya, mungkin ada jaringan yang dibatasi yang tidak tersedia untuk aplikasi. Melakukan binding ke jaringan latar belakang memerlukan izin CHANGE_NETWORK_STATE. Beberapa panggilan mungkin memerlukan izin khusus agar dapat berjalan. Baca dokumentasi khusus untuk setiap panggilan untuk detailnya.

Mendapatkan status instan

Perangkat yang didukung Android dapat mempertahankan banyak koneksi secara bersamaan. Untuk mendapatkan informasi tentang status jaringan saat ini, pertama-tama dapatkan instance ConnectivityManager:

Kotlin

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

Java

ConnectivityManager connectivityManager = getSystemService(ConnectivityManager.class);

Selanjutnya, 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 meminta 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);

Untuk fungsionalitas yang lebih berguna, daftarkan NetworkCallback. Untuk mengetahui informasi selengkapnya tentang mendaftarkan callback jaringan, lihat Memproses peristiwa 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. VPN dan Wi-Fi Peer-to-Peer juga dapat ditransfer. Di Android, suatu jaringan dapat memiliki beberapa transport secara bersamaan. Contohnya adalah VPN yang beroperasi melalui jaringan Wi-Fi dan seluler. VPN memiliki transport Wi-Fi, seluler, dan VPN. Untuk mengetahui apakah jaringan memiliki transport tertentu, gunakan metode NetworkCapabilities.hasTransport(int) dengan salah satu konstanta NetworkCapabilities.TRANSPORT_*.

Kemampuan menerangkan properti jaringan. Contoh kemampuan meliputi MMS, NOT_METERED, dan INTERNET. Jaringan dengan kemampuan MMS dapat mengirim dan menerima pesan Multimedia Messaging Service, dan 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: menunjukkan bahwa jaringan disiapkan untuk mengakses internet. 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: 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 performa/ baterai.

  • NET_CAPABILITY_NOT_VPN: menunjukkan bahwa jaringan bukan virtual private network.

  • NET_CAPABILITY_VALIDATED: menunjukkan bahwa jaringan memberikan akses aktual ke internet publik saat 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: menunjukkan bahwa jaringan memiliki captive portal saat diperiksa.

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

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.

Memproses peristiwa jaringan

Untuk mengetahui tentang peristiwa 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, yang ditentukan oleh sistem. 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 mengetahui informasi selengkapnya, lihat bagian tentang 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 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.

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. Untuk mengetahui informasi selengkapnya, lihat bagian tentang NetworkCapabilities dan LinkProperties.

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. Namun, walaupun 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. Contoh berikut menunjukkan cara mem-build NetworkRequest untuk aplikasi yang hanya tertarik dengan 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);

Ini berarti aplikasi Anda mendeteksi semua perubahan terkait jaringan yang tidak berbayar pada sistem.

Untuk callback jaringan default, ada versi registerNetworkCallback(NetworkRequest, NetworkCallback, Handler) yang menerima Handler sehingga tidak memuat thread Connectivity aplikasi.

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, periksa default untuk melihat apakah cocok dengan kasus penggunaan Anda, dan hapus jika Anda ingin aplikasi diberi tahu tentang jaringan yang tidak memiliki kemampuan ini. Di sisi lain, tambahkan kemampuan agar tidak dipanggil atas perubahan konektivitas apa pun di jaringan yang tidak berinteraksi dengan aplikasi Anda.

Misalnya, jika aplikasi Anda perlu mengirim pesan MMS, tambahkan NET_CAPABILITY_MMS ke NetworkRequest agar tidak mendapatkan pemberitahuan tentang semua jaringan yang tidak dapat mengirim pesan MMS. Tambahkan TRANSPORT_WIFI_AWARE jika aplikasi Anda hanya tertarik dengan 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 urutan callback

Bagian ini menjelaskan urutan callback yang mungkin diperoleh aplikasi jika mendaftarkan callback default dan callback reguler di perangkat yang memiliki konektivitas seluler. Dalam contoh ini, perangkat menghubungkan ke titik akses Wi-Fi yang bagus, lalu memutuskan koneksinya. Contoh 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 tersedia, aplikasi juga 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 aktif, aplikasi tidak dapat 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 menyertakan kemampuan NET_CAPABILITY_VALIDATED. Setelah beberapa saat, aplikasi akan menerima panggilan ke onNetworkCapabilitiesChanged() yang kemampuan barunya menyertakan 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 selalu aktif dinonaktifkan, saat Wi-Fi terputus, perangkat akan mencoba terhubung kembali ke jaringan 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 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, dan beberapa jaringan mungkin dibatasi untuk aplikasi dengan hak istimewa. Untuk memeriksa konektivitas internet, lihat NET_CAPABILITY_INTERNET dan NET_CAPABILITY_VALIDATED.

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 memungkinkan sistem mencoba menampilkan jaringan yang tidak muncul, seperti jaringan seluler saat perangkat terhubung ke jaringan Wi-Fi. Aplikasi tersebut memanggil ConnectivityManager.requestNetwork(NetworkRequest, NetworkCallback) dengan NetworkCallback yang akan dipanggil saat jaringan ditampilkan.