Appið þitt kallar VpnService.prepare, fær null, byggir göng og lýsingin virðist gild, en ekkert nær til þjónsins. Eða prepare skilar Intent, notandinn samþykkir það, og establish mistekst samt. Bæði útkoman þýða venjulega það sama: annað app á nú þegar VPN-viðmótið fyrir þennan notanda, og protect-köllin þín merkja sambönd sem göngin þín geta ekki notað. Farðu í gegnum prófanirnar hér að neðan í réttri röð og stoppaðu við þá fyrstu sem mistekst, því síðara skref getur ekki lagað fyrra.

Athugaðu VPN-rýmið áður en þú snertir protect

Android gefur hverjum notanda nákvæmlega eitt virkt VPN-viðmót. Það er regla kerfisins, ekki heimild sem appið þitt getur beðið um, svo tveir biðlar sem báðir vilja vera göngin geta ekki verið til saman.

VPN sem er alltaf virkt og stillt fyrir annað app er erfiðasta tilfellið, því kerfið heldur því appi tengdu og hafnar yfirtöku. Ferðaflutningssía eins og AdGuard, fyrirtækjabiðlari eða neytenda-VPN getur haldið rýminu á meðan notandinn hefur gleymt að það er uppsett. Biddu notandann að opna Stillingar og lesa færsluna sem er skráð undir VPN; nafnið þar er eigandinn sem þú keppir við. Þar til sú færsla er aftengd eða stillingin alltaf virkt er hreinsuð getur VpnService þitt ekki orðið viðmótið.

Skref 1: lestu hvað prepare skilar

VpnService.prepare svarar einni spurningu: má þetta app verða VPN-ið? Það skilar null þegar samþykki er þegar til staðar, og Intent þegar notandinn þarf enn að samþykkja það, sem þú verður að ræsa með startActivityForResult. Líttu á null-skil sem leyfi til að halda áfram, ekki sem sönnun þess að establish takist.

Intent intent = VpnService.prepare(context);
if (intent != null) {
    startActivityForResult(intent, REQUEST_VPN);
}

Ef Intent-leiðin kemur til baka og notandinn hafnaði mun prepare halda áfram að skila Intent í næstu tilraun. Skráðu niðurstöðukóðann í stað þess að reyna aftur í lykkju, því hafnað samþykki er ákvörðun notandans, ekki skammvinn villa.

Skref 2: staðfestu að viðmótið tilheyri appinu þínu

Eftir establish er ParcelFileDescriptor sem þú færð sönnun þín um eignarhald, og það er þess virði að athuga hana fyrir sérhverja sambands-vinnu. Lýsing sem er null eða þegar lokuð þýðir að viðmótið var aldrei búið til, jafnvel þótt engin undantekning hafi komið fram. Berðu saman viðmótsnafnið frá byggjandanum við það sem kerfið tilgreinir fyrir virka VPN-ið, með dumpsys á prófunartæki. Ef þau eru ólík er göngin sem þú byggðir ekki göngin sem flytja ferðaflutninginn.

adb shell dumpsys connectivity

Sama misræmið útskýrir tengt tákn með dauðum ferðaflutningi. Kerfið sýnir göng hins appsins, á meðan kóðinn þinn heldur lýsingu fyrir viðmót sem hann á ekki.

Skref 3: kallaðu protect fyrir connect

Þegar viðmótið er til eru sambönd sem appið þitt opnar látin fara í göngin að sjálfgefnu. Ytri flutningurinn getur ekki fylgt þeirri reglu eða umbúið pakkinn myndi hringsóla aftur í viðmótið, svo VpnService protect merkir samband til að fara fram hjá VPN-inu og nota undirliggjandi netið. Kallið skilar boolean, og að hunsa það er leiðin að sambandi sem lítur heilbrigt út og flytur ekkert.

Kallaðu protect fyrir connect eða bind, aldrei eftir. Vörnin verður að vera komin á sinn stað áður en sambandið er tengt eða búið, því tengt samband hefur þegar valið leið sína og seinna protect færir það ekki á áreiðanlegan hátt. Ef protect skilar false skaltu stoppa og athuga eignarhaldið aftur: það mistekst þegar viðmótið tilheyrir ekki appinu þínu, sem er einmitt ástandið sem annað VPN skilur eftir. False-skil eru merki um að fara aftur í Skref 1, ekki að reyna sama sambandið aftur.

DatagramSocket socket = new DatagramSocket();
if (!vpnService.protect(socket)) {
    return;
}
socket.connect(serverAddress, serverPort);

Skref 4: bindu ferli þegar samband er óþægilegt

Sumir flutningar eru ekki eitt samband: bókasafn getur opnað nokkur, eða þú vilt að hver tenging í hjálparferli noti sama útgjafann. ConnectivityManager.bindProcessToNetwork bindur ferlið við valið net, og eldra setProcessDefaultNetwork gerði sama hlutinn áður en það var úrelt. Biddu um undirliggjandi tenginguna með NET_CAPABILITY_NOT_VPN svo bindingin velji netið undir göngunum þínum frekar en göngin sjálf.

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

Að binda ferli er ekki annað VPN. Það velur útgang fyrir það ferli, sem er gagnlegt fyrir flutninginn þinn og gagnslaust til að keyra tvö göng í einu.

Lagaðu tækið hjá notandanum, ekki kóðaleiðina

Ekkert API leyfir tveimur appum að deila VPN-rýminu, svo lagfæringin tilheyrir ástandi tækisins. Bjóddu notandanum tvo áþreifanlega kosti: aftengdu eða hreinsaðu alltaf virkt fyrir hitt appið svo prepare þitt geti tekið yfir, eða opnaðu stillingar á hverja app hjá því appi og útilokaðu appið þitt frá göngunum þess. Útilokunin heldur síunni gangandi fyrir allt annað og leyfir appinu þínu að nota venjulegu tenginguna, sem er oft útkoman sem notandinn vill í raun.

Skrifaðu báðar leiðir í stuðningsskjölin þín, því notendur vita sjaldan hvaða app á VPN-ið. Biddu þá að senda nafn virka VPN-sins úr Stillingum og niðurstöður prepare, establish og protect úr skrám þínum, og þú getur sagt innan mínútu hvaða skref mistókst. Staðfestu síðan með raunverulegum ferðaflutningi: nafnleit, TCP-tengingu og eina beiðni í gegnum göngin, ekki bara tengt tákn. Gild lýsing og grænn vísir sanna eignarhald í besta falli, aldrei að flutningurinn hafi staðist leiðarreglurnar.

Ef allar fjórar prófanir ganga og ferðaflutningurinn deyr samt er eignarhaldið ekki lengur vandamál þitt. Farðu yfir í leiðsögn og aðgengi að þjóninum, og prófaðu sömu skilríki frá tæki án VPN-appa.

Tengdir greinar