Android'da VPN ulangan-u yo'qligini kod orqali qanday tekshirish mumkin
Android'da VPN ulanish holatini qaytaruvchi getter yo'q. Tarmoq imkoniyatlarini so'rang, transport o'zgarishlarini kuzating va ilova roziligini, qurilma holatini hamda server dalilini alohida saqlang.
Android'dan VPN ulanganmi yo'qmi deb so'ray olmaysiz. VpnService ulanish holatini qaytaruvchi getter taqdim etmaydi, holat qatoridagi kalit belgisini esa tizim chizadi, bu ilovangiz o'qiy oladigan narsa emas. Qila oladigan ishingiz ulanish stekiga torroq savol berish: bu ilova trafigi qaysi tarmoqdan foydalanmoqda va o'sha tarmoq VPN transportini olib yuryaptimi. Ushbu qo'llanma noto'g'ri musbat natijalardan qochadigan tartibda tekshiruvlarni o'tkazadi: qurilmadagi shell buyrug'idan ilovada qoldiradigan callback'gacha.
Ilova kodiga tegishdan oldin qurilmani shell'dan tekshiring
Avval boshlang'ich holatni oling. adb shell dumpsys connectivity tizim biladigan har bir tarmoqni chop etadi va har bir blok o'z transportlarini sanab o'tadi, shuning uchun VPN tarmog'i o'sha ro'yxatda VPN bilan ko'rinadi. Eng avval standart tarmoq blokini o'qing, keyin xuddi shu transportni olib yuruvchi boshqa tarmoqlarni qidiring.
Ikki chiqish ikki xil savolga javob beradi. VPN tarmog'ining mavjudligi ilovangiz undan foydalanayotgani bilan bir xil emas, ish profili yoki ikkinchi foydalanuvchisi bor qurilmada esa jarayoningiz internet bilan bevosita gaplashayotganda ikkalasi ham bir vaqtda to'g'ri bo'lishi mumkin. Soketlaringiz nima qilishini faol tarmoq satri hal qiladi.
Ilova foydalanayotgan tarmoqni so'rang
Kodda imkoniyat testi to'rt satr. Manifestda ACCESS_NETWORK_STATE so'rang, so'ng faol tarmoq imkoniyatlarini VPN transporti bilan solishtiring:
ConnectivityManager cm = (ConnectivityManager)
context.getSystemService(Context.CONNECTIVITY_SERVICE);
Network active = cm.getActiveNetwork();
NetworkCapabilities caps = cm.getNetworkCapabilities(active);
boolean vpnInUse = caps != null
&& caps.hasTransport(NetworkCapabilities.TRANSPORT_VPN);
Javob ataylab tor: ilovaning standart tarmog'i hozir VPN mi. U qaysi VPN, u sizniki mi yoki tunnel narigi uchga yetib boradimi, bu haqda hech narsa demaydi. true ni “trafik qandaydir tunnel orqali chiqadi” deb qabul qiling va o'z hisobingizni alohida yuriting. Bir vaqtda uch narsani jimgina anglatuvchi boolean — foydalanuvchi VPN orqali kezayotganda sozlamalar ekrani VPN'ni o'chirilgan deb ko'rsatishining sababi.
Aksincha, qandaydir VPN tarmog'i bor-yo'qligini bilish kerak bo'lsa, cm.getAllNetworks() bo'ylab takrorlang va har bir imkoniyat to'plamini sinang. Ikki javob boshqa ilovalarni qamrab oladigan, lekin sizning ilovangizni qamrab olmaydigan ilovaga xos VPN ishlayotgan qurilmada ajralib ketadi va o'sha ajralish “ilova aniq yoniq VPN'ni ko'rmayapti” degan xato hisobotlarining ko'pchiligining manbai.
Polling o'rniga o'zgarishlarni kuzating
Taymer bilan polling bu savol uchun noto'g'ri shakl, chunki holat o'zgarishlari hodisa sifatida keladi. VPN transportiga mos so'rovni ro'yxatdan o'tkazing va mos tarmoq paydo bo'lganda, yo'qolganda yoki o'zgarganda freymvork sizga aytsin:
NetworkRequest request = new NetworkRequest.Builder()
.addTransportType(NetworkCapabilities.TRANSPORT_VPN)
.removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VPN)
.build();
cm.registerNetworkCallback(request, callback);
VPN tarmog'i hech qachon NET_CAPABILITY_NOT_VPN ni olib yurmaydi, shuning uchun aniq olib tashlash niyatni hujjatlashtiradi. U bo'lmasa ham so'rov mos keladi, lekin keyingi o'quvchi buni o'zi aniqlashi kerak.
Ro'yxatga olish kuzatuv kerak bo'lgan doirada bo'ladi, odatda ekran yoki oldingi plan xizmati. onStop yoki onDestroy da ro'yxatdan chiqing va allaqachon ketgan activity'ga callback osib qo'ymang. Ko'rinadigan komponenti yo'q ilova doimiy kuzatuvchi uchun yomon uy egasi, unutilgan callback'lar esa konfiguratsiya o'zgarishidan keyin qulaydiganlardir.
Uch savolni alohida saqlang
Bu sohadagi chalkashlikning ko'pchiligi uch xil tekshiruvni bitta deb qarashdan kelib chiqadi. Ular turli API'lardan foydalanadi va biri to'g'ri bo'lganda qolganlari noto'g'ri bo'lishi mumkin.
| Question | How you answer it | What a yes means |
|---|---|---|
| Did the user grant VPN consent to my app? | VpnService.prepare() returns null | Consent exists; the tunnel may still be down |
| Is the device sending default traffic through a VPN? | TRANSPORT_VPN on the active network | Something is tunneling, not necessarily your app |
| Did this request arrive through the VPN? | Source address seen by the server | Proof for that connection, nothing wider |
Uchinchi satr odamlar klientda javob berishga urinadigan satrdir va u yerda javob berib bo'lmaydi. VPN klientlariga o'z manzillar hovuzini bering va serverda manba manzilini o'qing; sessiya o'rtasida foydalanuvchi tunnelni almashtirsa ham omon qoladigan yagona dalil shu.
Noto'g'ri musbat natijalarni istisno qiluvchi tekshiruv tartibi
Hali ham muomalada bo'lgan eski namuna kod getNetworkInfo(ConnectivityManager.TYPE_VPN) ni chaqiradi. Bu chaqiruv eskirgan va bir nechta relizda VPN ulangan bo'lsa ham null qaytargan, shuning uchun ko'chirilgan parchalarning ko'pchiligi ishlayotgan qurilmada buzilgan ko'rinadi. Imkoniyat tekshiruvlari bu tuzoqdan qochadi va Android 5.0 dan boshlab bir xil ishlaydi. Agar hali ham uni chaqiradigan kod bazasini yuritsangiz, chaqiruvni zaxira variantga o'ramasdan o'zini almashtiring, chunki noto'g'ri javobni boshida aynan o'sha zaxira variant yaratgan.
Bitta qisqa yo'l ogohlantirishga loyiq. Tashqi xizmat xabar qiladigan ommaviy manzilni VPN chiqish manzili bilan solishtirish yo'l haqida nimanidir isbotlaydi, lekin har bir tekshiruvga uchinchi tomon so'rovini qo'shadi, o'sha xizmat ishlab turishiga bog'liq va keshlanishi yoki bloklanishi mumkin. Uni qo'lda diagnostika sifatida saqlang, hech qachon ilova ichidagi holat tekshiruvi sifatida emas.
Tekshiruvlarni shu tartibda bajaring va foydalanuvchi hisobotiga zid keladigan birinchisida to'xtang: shell'dagi transport ro'yxati, faol tarmoq imkoniyatlari, tunnelni yoqib-o'chirganda callback hodisalari, so'ngra server tomonidagi manba manzili. To'rttasi ham mos kelsa-yu ilova baribir noto'g'ri ishlasa, xato Android'ning tarmoq ko'rinishida emas, sizning shaxsiy holat mashinangizda.