這上半年幾家手機(jī)廠商可以堪稱神仙打架,小米9,iqoo,華為,oppo,三星等等都首發(fā)Android P系統(tǒng)。咱也是幾經(jīng)考慮終于換上了新手機(jī),也體驗(yàn)一下這Android9.0(原來(lái)是Android6的一臺(tái)nubia)。然后迫不及待跑了一下自己寫(xiě)的幾個(gè)app,這一跑然后就出問(wèn)題了。
Android 9 wifi傳輸
在Android9上面連接到Pentax相機(jī)的wifi時(shí)候,但是無(wú)法傳輸文件,無(wú)法獲取單反sd卡的縮略圖等,會(huì)報(bào)如下錯(cuò):
No Network Security Config specified, using platform default
后來(lái)通過(guò)查閱官網(wǎng),發(fā)現(xiàn)Google在Android P上面禁止了明文http傳輸,也就是默認(rèn)的是使用https而不是http。而且官方也是給出了解決方案。可以參考官方詳情,我在這里簡(jiǎn)單總結(jié)一下
- 添加安全配置文件
首先在res/xml文件夾下創(chuàng)建文件network_security_config.xml文件,然后添加可以信任的域名或者ip。
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
<domain-config>
<domain includeSubdomains="true">example.com</domain>
</domain-config>
</network-security-config>
或者添加<base-config cleartextTrafficPermitted = "true" />默認(rèn)可以使用明文傳輸。之后在AndroidMainfest.xml中application下添加下面屬性
android:networkSecurityConfig="@xml/network_security_config"
- 降低api版本,在27或者以下都可以使用明文http傳輸。但是作為開(kāi)發(fā)者這樣是沒(méi)有太大意義的。
訪問(wèn)自己搭建的后臺(tái)
另一個(gè)項(xiàng)目是通過(guò)Android訪問(wèn)自己搭建的web服務(wù)器。同樣會(huì)出現(xiàn)報(bào)錯(cuò),通過(guò)上面的兩種方法是可以解決問(wèn)題的。這里還有第三種方法,那就是手動(dòng)添加ssl證書(shū)
- spring boot配置ssl證書(shū)實(shí)現(xiàn)https訪問(wèn)
可以使用java自帶的證書(shū)生成工具來(lái)實(shí)現(xiàn),首先打開(kāi)cmd終端,輸入命令來(lái)產(chǎn)生ssl證書(shū)
keytool -list -keystore server.p12
之后會(huì)提示輸入不少于六位的密碼,之后還需要重復(fù)輸入,以及填寫(xiě)其他信息等。按照步驟來(lái)就行,關(guān)鍵就是要記住密碼。spring boot中在配置文件application.properties中添加幾條配置
#需吧生成的文件放在與配置文件相同目錄下
#server.ssl.key-store=classpath:keystore.p12
#配置證書(shū)密碼
#server.ssl.key-store-password=111111
##server.ssl.keyStoreType=PKCS12
#可以手動(dòng)指定端口,否則使用默認(rèn)的8443端口
#server.ssl.keyAlias:tomcat
之后重啟項(xiàng)目可以看見(jiàn)服務(wù)端!

由于證書(shū)是自己創(chuàng)建的所以肯定為無(wú)效證書(shū)

添加證書(shū)的信任
之后我使用java跑測(cè)試時(shí)候又報(bào)了這樣的錯(cuò)誤
avax.net.ssl.SSLHandshakeException: java.security.cert.CertificateException: No subject alternative names present
這樣是因?yàn)樘砑油阧ttps之后如果使用java.net或者Android進(jìn)行訪問(wèn)的話還是需要添加信任。java應(yīng)用的話需要將證書(shū)添加到支持??梢詮木W(wǎng)站下載二進(jìn)制文件。首先點(diǎn)擊上圖的證書(shū)之后點(diǎn)擊復(fù)制到文件

之后點(diǎn)擊下一步,選擇der文件格式的證書(shū)。使用該命令可以導(dǎo)入到本地的cacerts證書(shū)庫(kù)
keytool -import -alias vbooking -keystore cacerts -file ${JAVA_HOME}/jre/lib/security/vbooking.cer
之后不管是在本地跑java測(cè)試還是,用到j(luò)ava.net.HttpURLConnection本地是不會(huì)報(bào)錯(cuò)的。Android端的話在網(wǎng)絡(luò)安全配置文件中res/raw/my_ca中添加剛才生成的DER格式證書(shū)。
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
<domain-config>
<domain includeSubdomains="true">example.com</domain>
<trust-anchors>
<certificates src="@raw/my_ca"/>
</trust-anchors>
</domain-config>
</network-security-config>
其中需要注意的一點(diǎn)就是,在Android端使用網(wǎng)路請(qǐng)求時(shí)候不能在ui主線程中使用網(wǎng)絡(luò)請(qǐng)求,應(yīng)該在AsyncTask中來(lái)調(diào)用,關(guān)于AsyncTask的使用之前也總結(jié)過(guò)。另外一點(diǎn)是需要在添加網(wǎng)絡(luò)請(qǐng)求權(quán)限。
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />