问题描述
为我们开发的应用 (https://play.google.com/store/apps/details?id=io.rff.saide.knowhow) 在选择国家/地区后首次启动时会下载其特定国家/地区的内容。有两种来源选项:来自 SD 卡或互联网。第二个选项仍然有效(在通常糟糕的连接环境中速度太慢),但在包括从 Android 9 升级到 10 的软件更新后,第一个选项在三星的 T290(许多设备经过测试)上停止工作——但是,它仍在工作在其他平板电脑型号上没问题,例如联想 M8。
第一步:更新到 2020 年 5 月的安全补丁:SD 卡选项仍然有效 第二步:更新到 2020 年 7 月补丁和 Android 10:SD 卡选项不再起作用 第三步:更新到 2020 年 12 月的补丁:仍然没有改进
该应用在 G-Suite(受管设备,应用被列入白名单)下运行,但 Google 保证这无法解释这种行为(“如果它适用于一台设备,它将适用于所有设备”)。
开发者重新编译了一个新版本,以确保它包含最新的 Android 更新。他也确定各自的代码行不可能是原因。
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
这个问题的根源是什么?必须是平板电脑的系统软件吗?
解决方法
var ExternalStorageSdcardAccess = function (_fileHandler,_errorHandler) {
var errorHandler = _errorHandler || _defultErrorHandler;
var fileHandler = _fileHandler || _defultFileHandler;
var root = "file:///";
return {
scanRoot: scanRoot,scanPathList: scanPathList,scanPath: scanPath
};
function scanPath(path) {
window.resolveLocalFileSystemURL(path,_gotFiles,errorHandler);
}
function scanRoot() {
scanPath(root);
}
function scanPathList(arrayOfPath) {
arrayOfPath.forEach(function (p) {
scanPath(p);
});
}
function _gotFiles(entry) {
if (entry.isFile) {
fileHandler(entry);
} else {
var dirReader = entry.createReader();
dirReader.readEntries(function (entryList) {
entryList.forEach(function (entr) {_gotFiles(entr);});
},errorHandler);
}
}
function _defultFileHandler(fileEntry) {
console.log("FileEntry: " + fileEntry.name + " | " + fileEntry.fullPath);
}
function _defultErrorHandler(error) {
console.log('File System Error: ' + error.code);
}
};
function getSDCardFolder() {
ExternalStorageSdcardAccess(fileHandler,fileError).scanPath("file:///storage/");
function fileHandler(fileEntry) {
if ((fileEntry.name === app.id + "." + countryCode + '.txt') && (SDCardRoot === '')) {
var url = fileEntry.toURL();
SDCardRoot = url.substring(0,url.lastIndexOf('/') + 1);
}
function fileError(error) {}
}
function useSDCard() {
app.request.get(SDCardRoot + app.id + "." + countryCode + ".txt",{},function (data) {
if (version !== data) {
savedVersion = data;
if (navigator.connection.type === Connection.NONE) {
document.getElementById('internet-update').style.opacity = 0.5;
document.getElementById('internet-update').style.pointerEvents = 'none';
}
loadingContent = false;
openUpdate();
} else {
app.dialog.alert('The content is up-to-date.');
loadingContent = false;
}
});
}
,使用 AndroidManifest.xml
暂时选择退出范围存储,同时仍面向 Android 10:
<!-- This attribute is "false" by default on apps targeting Android 10 or higher. -->
<application android:requestLegacyExternalStorage="true" />
这只能在实现范围存储之前使用,因为 Android 11 的行为会有所不同:
在您将应用更新为面向 Android 11(API 级别 30)后,当您的应用在 Android 11 设备上运行时,系统会忽略 requestLegacyExternalStorage
属性,因此您的应用必须准备好{{ 3}} 和 support scoped storage 对于这些设备上的用户。
https://developer.android.com/about/versions/11/privacy/storage