OpenVPN సహాయక బైనరీ Android 10లో విఫలమవుతుంది: అనుమతి నిరాకరించబడింది
Android 10 తన స్వంత నిల్వలో యాప్ రాసిన సహాయకాన్ని అమలు చేయడానికి నిరాకరిస్తుంది. logcat చదవండి, సహాయకాన్ని స్థానిక లైబ్రరీగా అందించండి మరియు bundle బిల్డులను సరిచేయండి.
యాప్ Android 9లో పనిచేసింది మరియు Android 10 నవీకరణ తర్వాత అదే ఫోన్లో చనిపోతుంది. మీ ప్రొఫైల్ తాకబడలేదు, ధృవపత్రాలు అవే, మరియు క్రాష్ ఏదైనా ప్రామాణీకరణ ట్రాఫిక్కు ముందే వస్తుంది. logcat మొదట శూన్య పాయింటర్ను చూపుతుంది, దానికి కొన్ని పంక్తుల పైన ఉంది Cannot run program ...: error=13, Permission denied. ఆ సందేశం ఫైల్ అమలు గురించి, మీ కాన్ఫిగరేషన్ చదవడం గురించి కాదు.
లోపం 13 నిజంగా ఏమి నిరాకరిస్తుంది
Android 10, API స్థాయి 29, యాప్లు తమ స్వంత డేటా డైరెక్టరీలో రాసిన ఫైల్లను అమలు చేయడాన్ని ఆపింది. ఈ నియమం మొదట రాయగలిగే, తర్వాత అమలు చేయగలిగే నిల్వను లక్ష్యంగా పెట్టుకుంది, మరియు assets నుండి కాపీ చేసే లాంచర్ సృష్టించేది సరిగ్గా అదే. ics-openvpn కోర్ పాత బిల్డులు మొదటి రన్లో APK నుండి అమలు చేయగల openvpn ఫైల్ను విప్పి ProcessBuilder ద్వారా ప్రారంభిస్తాయి. విప్పడం ఇప్పటికీ విజయవంతమవుతుంది; నిరాకరించబడేది అమలే. API 29 లక్ష్యంగా పెట్టుకున్న యాప్ పాత విడుదలతో వచ్చిన పరికరంలో నడిచినా ఈ నియమాన్ని వారసత్వంగా పొందుతుంది, అందుకే ఒక నవీకరణ ఎవరూ తాకని బిల్డును విరగ్గొట్టగలదు.
ఈ నిరాకరణలో ఒక ఫోల్డర్ పేరుకు ప్రత్యేకమైనది ఏదీ లేదు. యాప్ తన డేటా డైరెక్టరీ కింద సృష్టించిన ఫైల్ మార్గం ఏదైనా అమలు చేయలేనిదిగా పరిగణించబడుతుంది, కాబట్టి getFilesDir(), getCacheDir() మరియు అనుకూల ఉప-డైరెక్టరీ అన్నీ ఒకే విధంగా విఫలమవుతాయి.
సహాయక క్రాష్ను ప్రొఫైల్ సమస్య నుండి వేరు చేయండి
పైనుండి స్క్రోల్ చేయడం బదులు ప్రక్రియ ప్రారంభం చుట్టూ ఉన్న లాగ్ చదవండి. వెతకవలసిన సంతకం error=13 పంక్తి, దాని పైన ఉన్న స్టాక్ ట్రేస్ సాధారణంగా ProcessBuilder అని పిలిచిన లాంచర్ పద్ధతిని పేర్కొంటుంది:
adb logcat -d | grep -n -i -E "cannot run program|permission denied|startOpenVPN"సహాయకం ఎప్పుడూ ప్రారంభం కాకపోతే, మీకు OpenVPN లాగ్ అవుట్పుట్ అసలు కనిపించదు: సైఫర్ చర్చలు లేవు, నెట్టిన మార్గాలు లేవు, DNS కాన్ఫిగరేషన్ లేదు. ఆ పంక్తులు కనిపించి వైఫల్యం తర్వాత వస్తే, బైనరీ నడిచింది మరియు సమస్య ప్రొఫైల్, సర్వర్ లేదా రూటింగ్ పొరలో ఉంది. ఆ ఒక్క భేదమే .ovpn ఫైల్లను సవరించడానికి వెళ్లే చాలా సమయాన్ని ఆదా చేస్తుంది, అవి ఎప్పుడూ నిందితులు కాలేదు. కింది రెండు సరిచేతల్లో మీకు నిజంగా ఏది కావాలో కూడా అది చెబుతుంది.
మీరు పరీక్షిస్తున్న పరికరంలోని API స్థాయిని కూడా తనిఖీ చేయండి, మీ బిల్డ్ కాన్ఫిగరేషన్లోనిది కాదు. API 28లో ఎమ్యులేటర్ ఇమేజ్ ఏమీ పునరుత్పత్తి చేయదు, ఎందుకంటే ఈ పరిమితి 29 నుండి పైకి మాత్రమే కరుస్తుంది. అదే సమయంలో మీ బిల్డ్ ఫైల్లో లక్ష్య SDK తనిఖీ చేయండి: దాన్ని పెంచడమే ఈ నియమాన్ని లోపలికి లాగుతుంది.
adb shell getprop ro.build.version.sdkబైనరీని వేరే చోటికి కాపీ చేయడం ఎందుకు సహాయపడదు
స్పష్టమైన పరిష్కారం, సహాయకాన్ని మరో రాయగలిగే డైరెక్టరీలో రాయడం, అసలు విఫలమైన అదే కారణంతో విఫలమవుతుంది. Android ఇప్పటికీ యాప్ యొక్క స్థానిక లైబ్రరీ డైరెక్టరీలో ఇన్స్టాల్ చేసిన భాగస్వామ్య లైబ్రరీలను అమలు చేయడానికి అనుమతిస్తుంది, ఎందుకంటే ఇన్స్టాలర్ వాటిని ప్యాక్ చేస్తుంది, రన్టైమ్లో రాయబడవు. ఆ డైరెక్టరీయే లాంచర్ చూపించవలసిన ఏకైక స్థలం. రన్టైమ్లో మీరు స్వయంగా విప్పేది ఏదైనా, ఏ పేరు పెట్టినా, నిరాకరించిన వర్గంలోనే ఉంటుంది.
బాహ్య నిల్వ మరింత దారుణం: అది noexecతో మౌంట్ చేయబడింది, అక్కడ ఉంచిన సహాయకాన్ని ఏ యాప్ ప్రారంభించలేదు. యాప్ డేటా తొలగించడం కూడా పాత ప్రవర్తనను తిరిగి తీసుకురాదు, ఎందుకంటే తదుపరి రన్ అదే అమలు చేయలేని ప్రతిని మళ్లీ సృష్టిస్తుంది.
లాంచర్ను ప్యాకేజీ చేసిన లైబ్రరీ వైపు మళ్లించండి
సహాయకం పేరును భాగస్వామ్య లైబ్రరీ పేరుగా మార్చి, మీరు మద్దతిచ్చే ప్రతి ABI కోసం దాన్ని jniLibs కింద అందించండి, తర్వాత లాంచర్ API 28 నుండి ఇన్స్టాల్ చేసిన లైబ్రరీ మార్గాన్ని తిరిగి ఇవ్వనివ్వండి:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
return new File(context.getApplicationInfo().nativeLibraryDir,
"libovpnexec.so").getPath();
}ఆ మార్గంలో నిజమైన ఫైల్ ఉండాలంటే లైబ్రరీ ఇన్స్టాల్ సమయంలో విప్పబడాలి, కాబట్టి android:extractNativeLibs="true" ను <application> మూలకంపై సెట్ చేయండి. manifest విలీని వేరే విలువ తెస్తే దాని పక్కన tools:replace="android:extractNativeLibs" జోడించండి. application మూలక సూచన ఈ లక్షణం ఏమి నియంత్రిస్తుందో నమోదు చేస్తుంది.
లాంచర్ను చేతితో ప్యాచ్ చేస్తున్నప్పుడు నకిలీ స్థానిక వేరియబుల్ గురించి జాగ్రత్తపడండి. పాత మూలాలు అదే పద్ధతిలో తర్వాత nativeAPI అని ప్రకటిస్తాయి, రెండో ప్రకటన రన్టైమ్ కాదు కంపైల్ లోపం, కాబట్టి బిల్డ్ త్వరగా విఫలమవుతుంది మరియు పొరపాటు సులభంగా కనిపిస్తుంది. Gradle బ్లాక్లోని ABI జాబితాను మీరు జోడించే ఫోల్డర్లతో సరిపోల్చి ఉంచండి.
విడుదల ఆర్టిఫాక్ట్ను పరీక్షా బిల్డుతో సరిపోల్చండి
డీబగ్ APK సొరంగాన్ని ఎత్తగలదు, అయితే విడుదల bundle ఇప్పటికీ క్రాష్ అవుతుంది, ఎందుకంటే bundle స్థానిక లైబ్రరీలను వేరే ఆకారంలో ప్యాక్ చేస్తుంది మరియు వాటిని ఆర్కైవ్ నుండి కుదించిన రూపంలో అందించగలదు. bundle నుండి వచ్చిన బిల్డులు మాత్రమే విఫలమైతే, దీన్ని gradle.properties లో జోడించి మళ్లీ బిల్డ్ చేయండి:
android.bundle.enableUncompressedNativeLibs=falseతర్వాత ఇన్స్టాల్ చేసిన ప్యాకేజీ మీరు ఆశించిన ABIని నివేదిస్తుందని నిర్ధారించండి, రెండూ అందిస్తే 32-బిట్ మరియు 64-బిట్ పరికరంలో తనిఖీని పునరావృతం చేయండి. ప్యాకేజీ మేనేజర్ తాను ఎంచుకున్న ABIని పేర్కొంటుంది, కాబట్టి 32 బిట్కు తిరిగి వెళ్లిన పరికరం క్రాష్ నివేదికలో కాదు, ఇక్కడ కనిపిస్తుంది:
adb shell dumpsys package com.example.openvpn | grep -i primaryCpuAbiఒక ABI కోసం లైబ్రరీ లేకపోవడం అసలు అనుమతి లోపాన్ని ఆ పరికరంలో మాత్రమే పునరుత్పత్తి చేస్తుంది, కాబట్టి ఒక విజయవంతమైన పరీక్ష ఫోన్ సాక్ష్యం కాదు. manifest జెండా, లైబ్రరీ పేరు మరియు bundle సెట్టింగ్ను కలిసి అందించండి; ఒకటి మార్చి మిగతావి మరచిపోతే మీరు అదే క్రాష్కు తిరిగి వస్తారు. శాశ్వత పరిష్కారం ప్యాచ్ను ఎప్పటికీ మోయడం బదులు నిర్వహించబడే కోర్ విడుదలకు మారడం.