تاسو نه شئ کولی له Android څخه وپوښتئ چې VPN نښلول شوی که نه. VpnService د نښلېدو حالت لپاره getter نه ښیې، او په حالت پټه کې د کیلي انځور سیسټم کاږي، نه هغه څه چې ستاسو اپلیکیشن یې لوستلی شي. هغه څه چې کولی شئ ترسره یې کړئ دا دي چې د اړیکې سټیک ته یوه تنګه پوښتنه وکړئ: دا اپلیکیشن کومه شبکه کاروي، او ایا هغه شبکه د VPN ټرانسپورټ وړي. دا لارښود هغه کتنې په هغه ترتیب کې ترسره کوي چې د غلطو مثبتو پایلو مخه نیسي، د وسیلې په shell کې د امر څخه تر هغه callback چې په اپلیکیشن کې پرېږدئ.

د اپلیکیشن کوډ د لمس کولو دمخه وسیله له shell څخه وګورئ

لومړی بنسټیز حالت واخلئ. adb shell dumpsys connectivity هره شبکه چې سیسټم پېژني چاپوي، او هر بلاک خپل ټرانسپورټونه لیستوي، نو VPN شبکه په هغه لیست کې د VPN سره ښکاري. تر هر څه دمخه د اصلي شبکې بلاک ولولئ، بیا هغه نورې شبکې ولټوئ چې هماغه ټرانسپورټ وړي.

دوه پایلې دوه بېلابېلو پوښتنو ته ځواب وایي. د VPN شبکې شتون او ستاسو اپلیکیشن د هغې کارول یو شی نه دي، او په هغه وسیله چې کاري پروفایل یا دویم کاروونکی لري، دواړه کېدای شي یوځای سم وي پداسې حال کې چې ستاسو پروسه مستقیم له انټرنیټ سره خبرې کوي. د فعالې شبکې کرښه هغه ده چې ستاسو ساکټونه څه کوي هغه ټاکي.

هغه شبکه وپوښتئ چې اپلیکیشن یې کاروي

په کوډ کې د وړتیا ازموینه څلور کرښې ده. په مانیفست کې ACCESS_NETWORK_STATE وغواړئ، بیا د فعالې شبکې وړتیاوې د VPN ټرانسپورټ سره پرتله کړئ:

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);

ځواب په قصد تنګ دی: ایا د اپلیکیشن اصلي شبکه اوس VPN ده. دا هېڅ نه وایي چې کوم VPN، ایا ستاسو دی، یا تونل بل سر ته رسېږي. true د «ترافیک د یو ډول تونل له لارې وځي» په توګه واخلئ او خپل حساب جلا وساتئ. یو بولین چې په خاموشۍ سره درې شیان یوځای مانا کوي، هغه لامل دی چې د سیټینګز سکرین VPN بند ښیې پداسې حال کې چې کاروونکی د هغې له لارې ګرځي.

برعکس، که غواړئ پوه شئ چې ایا کومه VPN شبکه موجوده ده، cm.getAllNetworks() تکرار کړئ او هره وړتیا ټولګه وازموئ. دواړه ځوابونه په هغه وسیله توپیر لري چې هلته د اپلیکیشن ځانګړی VPN چلېږي چې نور اپلیکیشنونه پوښي خو ستاسو نه، او هماغه توپیر د هغو تېروتنو راپورونو سرچینه ده چې وایي اپلیکیشن هغه VPN نه ویني چې ښکاره روښانه دی.

د پولینګ پر ځای بدلونونو څارنه وکړئ

د ټایمر سره پولینګ د دې پوښتنې لپاره غلط شکل دی، ځکه چې د حالت بدلونونه د پېښو په توګه راځي. هغه غوښتنه ثبت کړئ چې د VPN ټرانسپورټ سره سمون لري او پرېږدئ چوکاټ تاسو ته ووایي کله چې سمون لرونکې شبکه ښکاري، ورکېږي یا بدلېږي:

NetworkRequest request = new NetworkRequest.Builder()
    .addTransportType(NetworkCapabilities.TRANSPORT_VPN)
    .removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VPN)
    .build();
cm.registerNetworkCallback(request, callback);

VPN شبکه هېڅکله NET_CAPABILITY_NOT_VPN نه وړي، نو ښکاره لرې کول نیت مستندوي. پرته له هغې غوښتنه بیا هم سمون لري، خو بل لوستونکی باید دا پخپله ومومي.

ثبت هغه ساحې پورې اړه لري چې څارنې ته اړتیا لري، معمولاً یو سکرین یا مخکینۍ خدمت. په onStop یا onDestroy کې لغوه کړئ، او callback په هغه فعالیت ونه ځړئ چې لا تللی دی. هغه اپلیکیشن چې ښکاره برخه نه لري د تلپاتې څارونکي لپاره بد کوربه دی، او هغه callback چې هېرېږي هغه دي چې د ترتیباتو له بدلون وروسته نړېږي.

درې پوښتنې جلا وساتئ

په دې برخه کې ډېره ګډوډي د درې بېلابېلو کتنو د یوې په توګه له کتلو راځي. دوی بېلابېل API کاروي، او یوه کېدای شي سمه وي پداسې حال کې چې نورې غلطې دي.

QuestionHow you answer itWhat a yes means
Did the user grant VPN consent to my app?VpnService.prepare() returns nullConsent exists; the tunnel may still be down
Is the device sending default traffic through a VPN?TRANSPORT_VPN on the active networkSomething is tunneling, not necessarily your app
Did this request arrive through the VPN?Source address seen by the serverProof for that connection, nothing wider

درېیمه کرښه هغه ده چې خلک یې په کلینټ کې ځوابول غواړي، او هلته ځواب نه شي ورکول کېدای. VPN کلینټونو ته خپل پته پول ورکړئ او په سرور کې د سرچینې پته ولولئ؛ دا یوازینی ثبوت دی چې د کاروونکي لخوا د غونډې په مینځ کې د تونل بدلولو سره هم پاتې کېږي.

د کتنې ترتیب چې غلطې مثبتې پایلې لرې کوي

زوړ نمونه کوډ چې لا هم ګرځي getNetworkInfo(ConnectivityManager.TYPE_VPN) ته زنګ وهي. هغه زنګ منسوخ دی، او په څو خپرونو کې یې null بیرته راوګرځاوه حتی کله چې VPN نښلول شوی و، نو ځکه ډېری کاپي شوي ټوټې په کار کوونکې وسیله ماتې ښکاري. د وړتیا کتنې له دې تله څخه ډډه کوي او له Android 5.0 وروسته یو شان چلند کوي. که تاسو هغه کوډبیس ساتئ چې لا یې زنګ وهي، زنګ پخپله بدل کړئ نه دا چې په fallback کې یې ونغاړئ، ځکه چې غلط ځواب یې په لومړي سر کې هماغه fallback جوړ کړی و.

یو لنډه لار د خبرداری وړ ده. د بهرني خدمت لخوا راپور شوې عامه پته د VPN د وتلو پتې سره پرتله کول د لارې په اړه څه ثابوي، خو په هره کتنه کې د درېیم ګوند غوښتنه زیاتوي، د هغه خدمت د ژوندي پاتې کېدو پورې تړلی دی، او کېدای شي کیش یا بلاک شي. دا د لاسي تشخیص په توګه وساتئ، هېڅکله د اپلیکیشن دننه د حالت کتنې په توګه نه.

کتنې په دې ترتیب کې چل کړئ او په لومړۍ هغه کې ودرېږئ چې د کاروونکي راپور سره نه سمون لري: په shell کې د ټرانسپورټ لیست، د فعالې شبکې وړتیاوې، د تونل د روښانه او بندولو پر مهال callback پېښې، بیا د سرور خوا سرچینه پته. که څلور واړه سمون ولري او اپلیکیشن بیا هم غلط چلند کوي، تېروتنه د Android په شبکه لید کې نه ده، ستاسو په خپله حالت ماشین کې ده.

اړوندې مقالې