Turėjau pranešimų iš naudotojų su "Android 8", kad mano programa (kuri naudoja galinį kanalą) nerodo turinio. Atlikęs tyrimą radau, kad "Android 8" sistemoje vyksta ši išimtis:
08-29 12:03:11.246 11285-11285/ E/: [12:03:11.245, main]: Exception: IOException java.io.IOException: Cleartext HTTP traffic to * not permitted
at com.android.okhttp.HttpHandler$CleartextURLFilter.checkURLPermitted(HttpHandler.java:115)
at com.android.okhttp.internal.huc.HttpURLConnectionImpl.execute(HttpURLConnectionImpl.java:458)
at com.android.okhttp.internal.huc.HttpURLConnectionImpl.connect(HttpURLConnectionImpl.java:127)
at com.deiw.android.generic.tasks.AbstractHttpAsyncTask.doConnection(AbstractHttpAsyncTask.java:207)
at com.deiw.android.generic.tasks.AbstractHttpAsyncTask.extendedDoInBackground(AbstractHttpAsyncTask.java:102)
at com.deiw.android.generic.tasks.AbstractAsyncTask.doInBackground(AbstractAsyncTask.java:88)
at android.os.AsyncTask$2.call(AsyncTask.java:333)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:245)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1162)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:636)
at java.lang.Thread.run(Thread.java:764)
(pašalinau paketo pavadinimą, URL ir kitus galimus identifikatorius)
Android 7 ir žemesnėse sistemose viskas veikia, Manifest'e nenustatau android:usesCleartextTraffic
(ir true
nustatymas nepadeda, vis tiek tai yra numatytoji reikšmė), taip pat nenaudoju Network Security Information. Jei iškviečiu NetworkSecurityPolicy.getInstance().isCleartextTrafficPermitted()
, ji grąžina false
Android 8 versijai, true
senesnei versijai, naudojant tą patį apk failą.
Bandžiau rasti kokį nors paminėjimą apie tai "Google" informacijoje apie "Android O", bet nesėkmingai.
Pagal Tinklo saugumo konfigūracija -
Pradedant "Android 9" (API 28 lygis), aiškaus teksto palaikymas yra išjungtas pagal numatytuosius nustatymus.
Taip pat pažvelkite į - https://koz.io/android-m-and-the-war-on-cleartext-traffic/
1 variantas -
Sukurkite failą res/xml/network_security_config.xml -
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
<domain-config cleartextTrafficPermitted="true">
<domain includeSubdomains="true">domain.com (to be adjusted)</domain>
</domain-config>
</network-security-config>
AndroidManifest.xml -
<?xml version="1.0" encoding="utf-8"?>
<manifest ...>
<uses-permission android:name="android.permission.INTERNET" />
<application
...
android:networkSecurityConfig="@xml/network_security_config"
...>
...
</application>
</manifest>
2 variantas -
android:usesCleartextTraffic Doc
AndroidManifest.xml -
<?xml version="1.0" encoding="utf-8"?>
<manifest ...>
<uses-permission android:name="android.permission.INTERNET" />
<application
...
android:usesCleartextTraffic="true"
...>
...
</application>
</manifest>
Taip pat, kaip @david.s' atsakymas nurodė android:targetSandboxVersion
taip pat gali būti problema -
Pagal Manifest Docs -
android:targetSandboxVersion
Tikslinė smėlio dėžė, kurią turi naudoti ši programa. Kuo aukštesnė smėlio dėžės versija skaičius, tuo aukštesnis saugumo lygis. Numatytoji reikšmė yra 1; jūs taip pat galite nustatyti reikšmę 2. Nustačius šį atributą į 2, programa perjungiama į kitą SELinux smėlio dėžę. Šie apribojimai taikomi 2 lygio smėlio dėžė:
- Numatytoji
usesCleartextTraffic
reikšmė tinklo saugumo konfigūracijoje yra false.- Uid dalijimasis neleidžiamas.
Taigi 3 variantas -
Jei android:targetSandboxVersion
yra <manifest>
, sumažinkite jį iki 1
.
AndroidManifest.xml -
<?xml version="1.0" encoding="utf-8"?>
<manifest android:targetSandboxVersion="1">
<uses-permission android:name="android.permission.INTERNET" />
...
</manifest>
"AndroidManifest" radau šį parametrą:
android:networkSecurityConfig="@xml/network_security_config"
o @xml/network_security_config apibrėžtas network_security_config.xml kaip:
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
<!--Set application-wide security config using base-config tag.-->
<base-config cleartextTrafficPermitted="false"/>
</network-security-config>
tiesiog pakeičiau cleartextTrafficPermitted į true
Gerai, aš tai supratau. Taip yra dėl Manifest parametro android:targetSandboxVersion="2"
, kurį pridėjau, nes mes taip pat turime "Instant App" versiją - jis turėtų užtikrinti, kad vartotojui atnaujinus "Instant App" į įprastą programą, jis nepraras savo duomenų. Tačiau, kaip matyti iš neaiškaus aprašymo:
Nurodo tikslinę smėlio dėžę, kurią ši programa nori naudoti. Aukštesnės sanbox versijos turės vis aukštesnį saugumo lygį.
Numatytoji šio atributo reikšmė yra 1.
Akivaizdu, kad jis taip pat prideda naują saugumo politikos lygį, bent jau "Android 8" sistemoje.