今天測(cè)試組的同事反饋眶俩,apk在應(yīng)用內(nèi)部更新時(shí)候更新不了莹汤。這個(gè)問題很嚴(yán)重,記得之前適配androidQ的時(shí)候處理過颠印,怎么又出問題了纲岭,話不多說抹竹,看看日志:
java.io.FileNotFoundException: /storage/emulated/0/myApp/download/myApp.apk: open failed: ENOENT (No such file or directory)
對(duì)應(yīng)到的代碼是這一行
File file = new File(Environment.getExternalStorageDirectory().getPath() + "/myApp/download", "myApp.apk");
if (!file.getParentFile().exists()) {
file.getParentFile().mkdirs();
}
//異常指向Z這一行
FileOutputStream fos = new FileOutputStream(file);
FileNotFoundException,顧名思義文件沒有找到止潮,網(wǎng)上有很多的帖子都是有說到在androidQ上會(huì)出現(xiàn)這個(gè)問題窃判,那么我們借鑒一下,來改改看喇闸。
先查看權(quán)限設(shè)置:
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
但肯定不是這個(gè)原因袄琳,代碼里使用RxPermission做了動(dòng)態(tài)權(quán)限申請(qǐng)的,這個(gè)問題在之前適配時(shí)處理過的仅偎。
查看了自己的compileSdkVersion,targetSdkVersion都配置的是29跨蟹,并沒有什么特別之處,為了排除問題橘沥,把原來的代碼重新寫閱讀一下窗轩,發(fā)現(xiàn)了Environment.getExternalStorageDirectory()
不推薦使用了,并給出了一大堆的說明部分提示是這樣的:
getExternalStorageDirectory
Added in API level 1
File getExternalStorageDirectory ()
Return the primary shared/external storage directory. This directory may not currently be accessible if it has been mounted by the user on their computer, has been removed from the device, or some other problem has happened. You can determine its current state with getExternalStorageState().
Note: don't be confused by the word "external" here. This directory can better be thought as media/shared storage. It is a filesystem that can hold a relatively large amount of data and that is shared across all applications (does not enforce permissions). Traditionally this is an SD card, but it may also be implemented as built-in storage in a device that is distinct from the protected internal storage and can be mounted as a filesystem on a computer.
On devices with multiple users (as described by UserManager), each user has their own isolated shared storage. Applications only have access to the shared storage for the user they're running as.
洋文一大堆座咆,看懂個(gè)大概痢艺,解決問題要緊嗎,既然不推薦使用介陶,那使用可能就會(huì)出問題堤舒,換了一種替代的寫法:
//創(chuàng)建文件路徑
File dir=new File(context.getExternalFilesDir(null).getPath()+"myApk");
if (!dir.exists()){
dir.mkdir();
}
//創(chuàng)建文件
File file = new File(dir+"/"+"jfApp.apk");
if (!file.exists()){
file.createNewFile();
}
FileOutputStream fos = new FileOutputStream(file);
同時(shí)在執(zhí)行這段之前,檢查了SD卡的狀態(tài)是否可用:
if (!Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
Toast.makeText(mContext, "SD卡不可用~", Toast.LENGTH_SHORT).show();
}
還添加了這么一句在Manifest.xml文件中哺呜,android:requestLegacyExternalStorage="false"
AndroidQ采用文件分區(qū)存儲(chǔ)舌缤,這句可以把它禁用,這里不深究新的方法某残,畢竟有這個(gè)方案不是很乘數(shù)国撵,下個(gè)版本要被拋棄了呢,那不白學(xué)了玻墅,還有介牙,畢竟改bug要緊(前面的話都是為懶進(jìn)行開脫)。
改完之后運(yùn)行代碼澳厢,完美解決环础。