Kemampuan Wi-Fi Aware memungkinkan perangkat yang menjalankan Android 8.0 (level API 26) dan lebih tinggi untuk menemukan dan terhubung langsung satu sama lain tanpa jenis konektivitas di antara mereka. Wi-Fi Aware juga dikenal sebagai Neighbor Awareness Jaringan (NAN).
Jaringan Wi-Fi Aware bekerja dengan membentuk klaster dengan perangkat di dekatnya, atau dengan membuat cluster baru jika perangkat adalah yang pertama di suatu area. Ini perilaku pengelompokan berlaku di seluruh perangkat dan dikelola oleh jaringan Wi-Fi Layanan sistem Aware; aplikasi tidak memiliki kontrol atas perilaku pengelompokan. Penggunaan aplikasi API Wi-Fi Aware untuk berkomunikasi dengan layanan sistem Wi-Fi Aware, yang mengelola perangkat keras Wi-Fi Aware di perangkat.
API Wi-Fi Aware memungkinkan aplikasi menjalankan operasi berikut:
Menemukan perangkat lain: API memiliki mekanisme untuk menemukan perangkat di sekitar. Proses dimulai saat satu perangkat memublikasikan perangkat atau layanan yang lebih dapat ditemukan. Kemudian, jika perangkat berlangganan ke satu atau beberapa dan memasuki jangkauan Wi-Fi penerbit, pelanggan akan menerima notifikasi bahwa penayang yang cocok telah ditemukan. Setelah pelanggan menemukan penerbit, pelanggan dapat mengirimkan mengirim pesan atau membuat koneksi jaringan dengan perangkat yang ditemukan. Perangkat dapat menjadi penayang dan pelanggan secara bersamaan.
Membuat koneksi jaringan: Setelah dua perangkat menemukan masing-masing lainnya, mereka dapat membuat koneksi jaringan Wi-Fi Aware dua arah tanpa titik akses.
Koneksi jaringan Wi-Fi Aware mendukung tingkat throughput yang lebih tinggi dalam jarak yang lebih panjang jarak daripada Bluetooth koneksi jarak jauh. Jenis koneksi ini berguna untuk aplikasi yang berbagi koneksi jumlah data antarpengguna, seperti aplikasi berbagi foto.
Peningkatan Android 13 (level API 33)
Di perangkat yang menjalankan Android 13 (level API 33) dan yang lebih baru yang mendukung fitur instan
mode komunikasi, aplikasi dapat menggunakan
PublishConfig.Builder.setInstantCommunicationModeEnabled()
dan
Metode SubscribeConfig.Builder.setInstantCommunicationModeEnabled()
untuk
mengaktifkan atau menonaktifkan mode komunikasi instan untuk penerbit atau pelanggan
sesi penemuan. Mode komunikasi instan
mempercepat pertukaran pesan,
penemuan layanan, dan setiap jalur data yang disiapkan sebagai bagian dari
sesi penemuan. Untuk menentukan apakah perangkat mendukung komunikasi instan
gunakan metode isInstantCommunicationModeSupported()
.
Peningkatan Android 12 (level API 31)
Android 12 (level API 31) menambahkan beberapa peningkatan pada Wi-Fi Aware:
- Di perangkat yang menjalankan Android 12 (API level 31) atau yang lebih baru, Anda dapat menggunakan
onServiceLost()
agar diberi tahu saat aplikasi Anda kehilangan layanan yang ditemukan karena layanan berhenti atau bergerak keluar dari jangkauan. - Penyiapan jalur data Wi-Fi Aware telah sederhana. Versi sebelumnya menggunakan pesan L2 untuk memberikan alamat MAC inisiator, yang latensi yang diperkenalkan. Pada perangkat yang menjalankan Android 12 dan yang lebih baru, responden (server) dapat dikonfigurasi untuk menerima peer apa pun—yaitu, tidak perlu untuk mengetahui alamat MAC initator di awal. Hal ini mempercepat jalur data memunculkan dan memungkinkan beberapa tautan titik ke titik hanya dengan satu jaringan permintaan.
- Aplikasi yang berjalan di Android 12 atau yang lebih tinggi dapat menggunakan
WifiAwareManager.getAvailableAwareResources()
untuk mendapatkan jumlah jalur data yang tersedia saat ini, sesi publikasi, dan berlangganan. Hal ini dapat membantu aplikasi menentukan apakah ada menyediakan cukup sumber daya untuk menjalankan fungsi yang diinginkan.
Penyiapan awal
Untuk menyiapkan aplikasi Anda menggunakan penemuan dan jaringan Wi-Fi Aware, lakukan langkah-langkah berikut:
Minta izin berikut dalam manifes aplikasi Anda:
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /> <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" /> <uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" /> <uses-permission android:name="android.permission.INTERNET" /> <!-- If your app targets Android 13 (API level 33) or higher, you must declare the NEARBY_WIFI_DEVICES permission. --> <uses-permission android:name="android.permission.NEARBY_WIFI_DEVICES" <!-- If your app derives location information from Wi-Fi APIs, don't include the "usesPermissionFlags" attribute. --> android:usesPermissionFlags="neverForLocation" /> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" <!-- If any feature in your app relies on precise location information, don't include the "maxSdkVersion" attribute. --> android:maxSdkVersion="32" />
Periksa apakah perangkat mendukung Wi-Fi Aware dengan
PackageManager
seperti yang ditunjukkan di bawah ini:Kotlin
context.packageManager.hasSystemFeature(PackageManager.FEATURE_WIFI_AWARE)
Java
context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_WIFI_AWARE);
Periksa apakah Wi-Fi Aware saat ini tersedia. Wi-Fi Aware mungkin ada di perangkat, tetapi saat ini mungkin tidak tersedia karena pengguna telah menonaktifkan Wi-Fi atau Lokasi. Tergantung pada kemampuan perangkat keras dan {i>firmware<i}, beberapa perangkat mungkin tidak mendukung Wi-Fi Aware jika Wi-Fi Langsung, SoftAP, atau tethering aktif gunakan. Untuk memeriksa apakah Wi-Fi Aware saat ini tersedia, telepon
isAvailable()
.Ketersediaan Wi-Fi Aware dapat berubah setiap saat. Aplikasi Anda harus daftarkan
BroadcastReceiver
untuk menerimaACTION_WIFI_AWARE_STATE_CHANGED
, yang dikirim setiap kali ketersediaan berubah. Saat aplikasi Anda menerima intent siaran, itu harus membuang semua sesi yang ada (asumsikan bahwa Layanan Wi-Fi Aware terganggu), lalu periksa kondisi ketersediaan saat ini dan menyesuaikan perilakunya. Contoh:Kotlin
val wifiAwareManager = context.getSystemService(Context.WIFI_AWARE_SERVICE) as WifiAwareManager? val filter = IntentFilter(WifiAwareManager.ACTION_WIFI_AWARE_STATE_CHANGED) val myReceiver = object : BroadcastReceiver() { override fun onReceive(context: Context, intent: Intent) { // discard current sessions if (wifiAwareManager?.isAvailable) { ... } else { ... } } } context.registerReceiver(myReceiver, filter)
Java
WifiAwareManager wifiAwareManager = (WifiAwareManager)context.getSystemService(Context.WIFI_AWARE_SERVICE) IntentFilter filter = new IntentFilter(WifiAwareManager.ACTION_WIFI_AWARE_STATE_CHANGED); BroadcastReceiver myReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { // discard current sessions if (wifiAwareManager.isAvailable()) { ... } else { ... } } }; context.registerReceiver(myReceiver, filter);
Untuk informasi selengkapnya, lihat Siaran.
Mendapatkan sesi
Untuk mulai menggunakan Wi-Fi Aware, aplikasi Anda harus mendapatkan
WifiAwareSession
dengan memanggil
attach()
. Metode ini
melakukan hal berikut:
- Mengaktifkan hardware Wi-Fi Aware.
- Bergabung atau membentuk kumpulan Wi-Fi Aware.
- Membuat sesi Wi-Fi Aware dengan namespace unik yang berfungsi sebagai untuk semua sesi penemuan yang dibuat di dalamnya.
Jika aplikasi berhasil terpasang, sistem akan menjalankan
Callback onAttached()
.
Callback ini menyediakan objek WifiAwareSession
yang harus digunakan aplikasi Anda untuk
semua operasi sesi selanjutnya. Aplikasi dapat menggunakan
sesi untuk memublikasikan layanan atau
berlangganan ke layanan.
Aplikasi Anda harus memanggil
attach()
hanya sekali. Jika
aplikasi Anda memanggil attach()
beberapa kali, aplikasi menerima sesi yang
berbeda untuk setiap panggilan, masing-masing
namespace-nya sendiri. Cara ini bisa berguna dalam skenario yang
kompleks, tetapi harus
umumnya dapat dihindari.
Memublikasikan layanan
Agar layanan dapat ditemukan, panggil metode
publish()
, yang
mengambil parameter berikut:
PublishConfig
menentukan nama dan properti konfigurasi lainnya, seperti filter pencocokan.DiscoverySessionCallback
menentukan tindakan yang akan dieksekusi saat peristiwa terjadi, seperti saat pelanggan menerima sebuah pesan.
Berikut contohnya:
Kotlin
val config: PublishConfig = PublishConfig.Builder() .setServiceName(AWARE_FILE_SHARE_SERVICE_NAME) .build() awareSession.publish(config, object : DiscoverySessionCallback() { override fun onPublishStarted(session: PublishDiscoverySession) { ... } override fun onMessageReceived(peerHandle: PeerHandle, message: ByteArray) { ... } })
Java
PublishConfig config = new PublishConfig.Builder() .setServiceName(“Aware_File_Share_Service_Name”) .build(); awareSession.publish(config, new DiscoverySessionCallback() { @Override public void onPublishStarted(PublishDiscoverySession session) { ... } @Override public void onMessageReceived(PeerHandle peerHandle, byte[] message) { ... } }, null);
Jika publikasi berhasil, maka
onPublishStarted()
metode callback akan dipanggil.
Setelah publikasi, saat perangkat yang menjalankan aplikasi pelanggan yang cocok dipindahkan ke
Jangkauan Wi-Fi perangkat publikasi, pelanggan menemukan layanan. Kapan
pelanggan menemukan penerbit, penerbit tidak menerima
notifikasi; jika pelanggan mengirim pesan ke penayang,
penerbit akan menerima notifikasi. Ketika hal itu terjadi,
onMessageReceived()
metode callback akan dipanggil. Anda dapat menggunakan
Argumen PeerHandle
dari metode ini ke
kirim pesan kembali ke pelanggan atau
membuat koneksi ke sana.
Untuk berhenti memublikasikan layanan, panggil
DiscoverySession.close()
.
Sesi Discovery dikaitkan dengan induknya
WifiAwareSession
. Jika sesi induk adalah
ditutup, sesi penemuan terkaitnya juga ditutup. Saat dihapus
tertutup juga, sistem tidak menjamin ketika berada di luar ruang lingkup
sesi ini ditutup, jadi sebaiknya Anda secara eksplisit memanggil close()
metode.
Berlangganan ke layanan
Untuk berlangganan layanan, panggil metode
Metode subscribe()
,
yang menggunakan parameter berikut:
-
SubscribeConfig
menentukan nama untuk berlangganan dan properti konfigurasi lainnya, seperti pencocokan filter. DiscoverySessionCallback
menentukan tindakan yang akan dijalankan saat peristiwa terjadi, seperti saat penayang ditemukan.
Berikut contohnya:
Kotlin
val config: SubscribeConfig = SubscribeConfig.Builder() .setServiceName(AWARE_FILE_SHARE_SERVICE_NAME) .build() awareSession.subscribe(config, object : DiscoverySessionCallback() { override fun onSubscribeStarted(session: SubscribeDiscoverySession) { ... } override fun onServiceDiscovered( peerHandle: PeerHandle, serviceSpecificInfo: ByteArray, matchFilter: List<ByteArray> ) { ... } }, null)
Java
SubscribeConfig config = new SubscribeConfig.Builder() .setServiceName("Aware_File_Share_Service_Name") .build(); awareSession.subscribe(config, new DiscoverySessionCallback() { @Override public void onSubscribeStarted(SubscribeDiscoverySession session) { ... } @Override public void onServiceDiscovered(PeerHandle peerHandle, byte[] serviceSpecificInfo, List<byte[]> matchFilter) { ... } }, null);
Jika operasi berlangganan berhasil, sistem akan memanggil
onSubscribeStarted()
di aplikasi Anda. Karena Anda dapat menggunakan
Argumen SubscribeDiscoverySession
di
untuk berkomunikasi dengan penayang setelah aplikasi menemukannya, Anda
harus menyimpan referensi ini. Anda dapat memperbarui sesi berlangganan kapan saja dengan
menelepon
updateSubscribe()
di sesi penemuan.
Pada tahap ini, langganan Anda menunggu penerbit yang cocok datang
Jangkauan Wi-Fi. Jika ini terjadi, sistem akan menjalankan
onServiceDiscovered()
. Anda dapat menggunakan PeerHandle
dari callback ini untuk mengirim pesan atau
membuat koneksi ke penayang tersebut.
Untuk berhenti berlangganan layanan, panggil
DiscoverySession.close()
.
Sesi Discovery dikaitkan dengan induknya
WifiAwareSession
. Jika sesi induk adalah
ditutup, sesi penemuan terkaitnya juga ditutup. Saat dihapus
tertutup juga, sistem tidak menjamin ketika berada di luar ruang lingkup
sesi ini ditutup, jadi sebaiknya Anda secara eksplisit memanggil close()
metode.
Mengirim pesan
Untuk mengirim pesan ke perangkat lain, Anda memerlukan beberapa objek berikut:
DiscoverySession
. Objek ini memungkinkan Anda untuk meneleponsendMessage()
. Aplikasi Anda mendapatkanDiscoverySession
dengan memublikasikan layanan atau berlangganan ke layanan.PeerHandle
perangkat lain, untuk merutekan untuk membuat pesan email baru. Aplikasi Anda mendapatkanPeerHandle
melalui salah satu dari dua cara berikut:- Aplikasi Anda memublikasikan layanan dan menerima pesan dari pelanggan.
Aplikasi Anda mendapatkan
PeerHandle
darionMessageReceived()
. - Aplikasi Anda berlangganan ke layanan. Kemudian, ketika menemukan kecocokan
aplikasi Anda akan mendapatkan
PeerHandle
darionServiceDiscovered()
.
- Aplikasi Anda memublikasikan layanan dan menerima pesan dari pelanggan.
Aplikasi Anda mendapatkan
Untuk mengirim pesan, panggil
sendMessage()
. Tujuan
callback berikut mungkin akan terjadi:
- Setelah pesan berhasil diterima oleh peer, sistem akan memanggil metode
onMessageSendSucceeded()
di aplikasi pengirim. - Ketika peer menerima pesan, sistem akan memanggil
onMessageReceived()
di aplikasi penerima.
Meskipun PeerHandle
diperlukan untuk berkomunikasi dengan pembanding, Anda tidak boleh
mengandalkannya sebagai ID permanen pembanding. Pengidentifikasi tingkat
yang lebih tinggi dapat
digunakan oleh aplikasi--yang disematkan dalam layanan penemuan itu sendiri atau di
pesan berikutnya. Anda dapat menyematkan ID
di layanan penemuan dengan
tindakan
setMatchFilter()
atau
setServiceSpecificInfo()
metode PublishConfig
atau
SubscribeConfig
. Tujuan
Metode setMatchFilter()
memengaruhi penemuan, sedangkan
Metode setServiceSpecificInfo()
tidak memengaruhi penemuan.
Menyematkan ID dalam pesan berarti memodifikasi array byte pesan untuk menyertakan ID (misalnya, sebagai beberapa byte pertama).
Membuat koneksi
Wi-Fi Aware mendukung jaringan klien-server antara dua perangkat Wi-Fi Aware.
Untuk menyiapkan koneksi klien-server:
Menggunakan penemuan Wi-Fi Aware untuk memublikasikan layanan (di server) dan berlangganan ke layanan (di klien).
Setelah pelanggan menemukan penayang, mengirim pesan dari pelanggan ke penayang.
Memulai
ServerSocket
di penayang perangkat dan menyetel atau memperoleh port-nya:Kotlin
val ss = ServerSocket(0) val port = ss.localPort
Java
ServerSocket ss = new ServerSocket(0); int port = ss.getLocalPort();
Gunakan
ConnectivityManager
untuk meminta jaringan Wi-Fi Aware di penayang menggunakanWifiAwareNetworkSpecifier
, menentukan sesi penemuan danPeerHandle
pelanggan, yang Anda dapatkan dari pesan yang ditransmisikan oleh pelanggan:Kotlin
val networkSpecifier = WifiAwareNetworkSpecifier.Builder(discoverySession, peerHandle) .setPskPassphrase("somePassword") .setPort(port) .build() val myNetworkRequest = NetworkRequest.Builder() .addTransportType(NetworkCapabilities.TRANSPORT_WIFI_AWARE) .setNetworkSpecifier(networkSpecifier) .build() val callback = object : ConnectivityManager.NetworkCallback() { override fun onAvailable(network: Network) { ... } override fun onCapabilitiesChanged(network: Network, networkCapabilities: NetworkCapabilities) { ... } override fun onLost(network: Network) { ... } } connMgr.requestNetwork(myNetworkRequest, callback);
Java
NetworkSpecifier networkSpecifier = new WifiAwareNetworkSpecifier.Builder(discoverySession, peerHandle) .setPskPassphrase("somePassword") .setPort(port) .build(); NetworkRequest myNetworkRequest = new NetworkRequest.Builder() .addTransportType(NetworkCapabilities.TRANSPORT_WIFI_AWARE) .setNetworkSpecifier(networkSpecifier) .build(); ConnectivityManager.NetworkCallback callback = new ConnectivityManager.NetworkCallback() { @Override public void onAvailable(Network network) { ... } @Override public void onCapabilitiesChanged(Network network, NetworkCapabilities networkCapabilities) { ... } @Override public void onLost(Network network) { ... } }; ConnectivityManager connMgr.requestNetwork(myNetworkRequest, callback);
Setelah penayang meminta jaringan, penayang harus mengirim pesan ke pelanggan.
Setelah pelanggan menerima pesan dari penayang, minta Wi-Fi Jaringan Aware pada pelanggan menggunakan metode yang sama dengan yang ada di penayang. Anjuran tidak menentukan porta saat membuat
NetworkSpecifier
Tujuan metode callback yang sesuai akan dipanggil saat koneksi jaringan tersedia, berubah, atau hilang.Setelah metode
onAvailable()
dipanggil pada pelanggan, ObjekNetwork
tersedia dengan yang dapat Anda bukaSocket
untuk berkomunikasi denganServerSocket
pada penayang, tetapi Anda perlu mengetahui Alamat dan port IPv6ServerSocket
. Anda mendapatkannya dari ObjekNetworkCapabilities
yang diberikan dalam callbackonCapabilitiesChanged()
:Kotlin
val peerAwareInfo = networkCapabilities.transportInfo as WifiAwareNetworkInfo val peerIpv6 = peerAwareInfo.peerIpv6Addr val peerPort = peerAwareInfo.port ... val socket = network.getSocketFactory().createSocket(peerIpv6, peerPort)
Java
WifiAwareNetworkInfo peerAwareInfo = (WifiAwareNetworkInfo) networkCapabilities.getTransportInfo(); Inet6Address peerIpv6 = peerAwareInfo.getPeerIpv6Addr(); int peerPort = peerAwareInfo.getPort(); ... Socket socket = network.getSocketFactory().createSocket(peerIpv6, peerPort);
Setelah selesai dengan koneksi jaringan, panggil
unregisterNetworkCallback()
Menentukan jarak peer dan penemuan kemampuan penentuan lokasi
Perangkat dengan lokasi Wi-Fi RTT kemampuan dapat langsung mengukur jarak ke peer dan menggunakan informasi ini untuk membatasi penemuan layanan Wi-Fi Aware.
Wi-Fi RTT API memungkinkan jangkauan langsung ke peer Wi-Fi Aware menggunakan Alamat MAC atau PeerHandle-nya.
Penemuan Wi-Fi Aware dapat dibatasi agar hanya menemukan layanan dalam
pembatasan wilayah tertentu. Misalnya, Anda dapat menyiapkan pembatasan wilayah yang memungkinkan penemuan
perangkat yang memublikasikan layanan "Aware_File_Share_Service_Name"
yang tidak
lebih dekat dari 3 meter (ditetapkan sebagai 3.000 mm) dan tidak lebih dari 10 meter
(ditetapkan sebagai 10.000 mm).
Untuk mengaktifkan pembatasan wilayah, baik penayang dan pelanggan harus melakukan tindakan:
Penayang harus mengaktifkan pengaturan rentang pada layanan yang dipublikasikan menggunakan setRangingEnabled(true).
Jika penayang tidak mengaktifkan rentang, maka batasan pembatasan wilayah apa pun yang ditentukan oleh pelanggan akan diabaikan dan penemuan normal dilakukan, mengabaikan jarak.
Pelanggan harus menetapkan pembatasan wilayah menggunakan beberapa kombinasi setMinDistanceMm dan setMaxDistanceMm.
Untuk kedua nilai tersebut, jarak yang tidak ditentukan menunjukkan bahwa tidak ada batas. Hanya menentukan jarak maksimum menyiratkan jarak minimum 0. Hanya menentukan atribut jarak minimum menyiratkan tidak ada maksimum.
Ketika layanan peer ditemukan dalam pembatasan wilayah, onServiceDitemukan DalamRange akan dipicu, yang akan memberikan jarak yang diukur ke peer. Tujuan Wi-Fi RTT API langsung dapat dipanggil seperlunya untuk mengukur jarak dengan di lain waktu.