今天測(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)行代碼,完美解決。