如何获取 PhoneGap 将看到的 android 目录中的文档
How to get documents in an android directory that PhoneGap will see
我希望能够将一些文件复制到我的 PhoneGap / Cordova 的文档目录中,以便在我使用 cordova-plugin-file API 列出该目录时它们会显示出来。不幸的是,文件 API 与平板电脑存储空间中的实际内容似乎有些脱节。下面是文件插件规范所说的系统目录结构应该是这样的:
Android 文件系统布局
file:///android_asset/
| cordova.file.applicationDirectory
file:///android_asset/data/data/<app-id>/
| cordova.file.applicationStorageDirectory
file:///android_asset/data/data/<app-id>/cache
| cordova.file.cacheDirectory
file:///android_asset/data/data/<app-id>/files
| cordova.file.dataDirectory
file:///android_asset/data/data/<app-id>/Documents
| cordova.file.documents
<sdcard>/
| cordova.file.externalRootDirectory
<sdcard>/Android/data/<app-id>/
| cordova.file.externalApplicationStorageDirectory
<sdcard>/Android/data/<app-id>/cache
| cordova.file.externalCacheDirectry
<sdcard>/Android/data/<app-id>/files
| cordova.file.externalDataDirectory
不幸的是,当我将我的设备(4.4.2/Lenovo 平板电脑)插入我的 PC 或 Mac 时,我没有看到这个。相反,我看到:
- Internal Storage
|- .IdeaDesktopHD
|- .lelauncher
|- .magic
|- .powercenterhd
|- Alarms
|- Android
|- Audio
|- Bluetooth
|- Contact
|- data
|- DCIM
|- Document
|- Download
|- googleota
|- legc
|- LenovoReaper
|- LesyncDownload
|- Movies
|- MyFavorite
|- Notifications
|- Others
|- Pictures
|- Podcasts
|- powercenterhd
|- Ringtones
|- SHAREit
知道我应该将文件复制到哪里以便我的应用可以看到它们吗?
好了。我的部分问题是我被 cordova 上的文件系统/cordova-plugin-file API 的异步性质所困扰。我必须进行一些代码重构才能使文件列表正确显示,但一旦我这样做了,文件就会正确显示,而不管它们在设备上的什么位置。
这是适用的代码。请注意,您需要将 cordova-plugin-file 添加到您的 Cordova/PhoneGap 项目中,并且它不能在浏览器中运行。我实际上在另一个 if/then 块中有这个块——如果它在浏览器中是 运行,则显示 html5 <input type=file>
,如果它在移动设备中,则显示此块:
var localURLs = [
cordova.file.dataDirectory,
cordova.file.documentsDirectory,
cordova.file.externalApplicationStorageDirectory,
cordova.file.externalCacheDirectory,
cordova.file.externalRootDirectory,
cordova.file.externalDataDirectory,
cordova.file.sharedDirectory,
cordova.file.syncedDataDirectory
];
var index = 0;
var i;
var statusStr = "";
var addFileEntry = function (entry) {
var dirReader = entry.createReader();
dirReader.readEntries(
function (entries) {
var fileStr = "";
var i;
for (i = 0; i < entries.length; i++) {
if (entries[i].isDirectory === true) {
// Recursive -- call back into this subdirectory
addFileEntry(entries[i]);
} else {
fileStr += (entries[i].fullPath + "<br>"); // << replace with something useful
index++;
}
}
// add this directory's contents to the status
statusStr += fileStr;
// display the file list in #results
if (statusStr.length > 0) {
$("#results").html(statusStr);
}
},
function (error) {
console.log("readEntries error: " + error.code);
statusStr += "<p>readEntries error: " + error.code + "</p>";
}
);
};
var addError = function (error) {
console.log("getDirectory error: " + error.code);
statusStr += "<p>getDirectory error: " + error.code + ", " + error.message + "</p>";
};
for (i = 0; i < localURLs.length; i++) {
if (localURLs[i] === null || localURLs[i].length === 0) {
continue; // skip blank / non-existent paths for this platform
}
window.resolveLocalFileSystemURL(localURLs[i], addFileEntry, addError);
}
编辑(2018 年 2 月):即使您可以在 Android 文件传输 上看到文件,您也可能看不到以编程方式返回 any 结果,即使您在 Cordova 应用程序中设置了构建时权限。这是由于 runtime 添加到 Android 的权限检查(我相信 > 6.0)。有几个插件可以帮助解决这个问题;在某些时候,我猜文件插件也会为它添加自动请求。这是我对 Cordova cli-7.0.1
:
所做的
在您的 config.xml 中,设置所需的应用权限。您将需要 READ_EXTERNAL_STORAGE(如果您要这样做,也需要写)。我还添加了下面引用的两个插件:
<plugin name="cordova-plugin-device" source="npm" spec="1.1.6" />
<plugin name="cordova.plugins.diagnostic" spec="^3.7.1" />
<config-file platform="android" parent="/manifest" mode="replace">
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
</config-file>
然后,最好在应用启动代码的某处(即设备就绪事件的处理程序)检查运行时权限并在需要时添加它们:
if (device.platform === "Android") {
// request read access to the external storage if we don't have it
cordova.plugins.diagnostic.getExternalStorageAuthorizationStatus(function (status) {
if (status === cordova.plugins.diagnostic.permissionStatus.GRANTED) {
console.log("External storage use is authorized");
} else {
cordova.plugins.diagnostic.requestExternalStorageAuthorization(function (result) {
console.log("Authorization request for external storage use was " + (result === cordova.plugins.diagnostic.permissionStatus.GRANTED ? "granted" : "denied"));
}, function (error) {
console.error(error);
});
}
}, function (error) {
console.error("The following error occurred: " + error);
});
}
编辑(2021 年 8 月):Android 10.x 及以上介绍了范围存储的概念,在 Android 中进一步完善11(参见 https://developer.android.com/about/versions/11/privacy/storage)。其中大部分是为了加强设备的安全性。这对您的应用意味着 reading/writing 永久文件应该限制在以下两个沙盒目录中,如果您是一个好的 Android 公民:
- cordova.file.externalDataDirectory(如果您有 SD 卡)
- cordova.file.datadirectory
除非您有充分的理由查看整个文件系统(并且可以说服 Google Play 商店团队),如果您尝试调用所有文件访问权限,您的应用可能会被拒绝。 来自链接文章:
Note: If you publish your app to Google Play, carefully read the notice. If you target Android 11 and declare All files access, it can affect your ability to publish and update your app on Google Play.
我希望能够将一些文件复制到我的 PhoneGap / Cordova 的文档目录中,以便在我使用 cordova-plugin-file API 列出该目录时它们会显示出来。不幸的是,文件 API 与平板电脑存储空间中的实际内容似乎有些脱节。下面是文件插件规范所说的系统目录结构应该是这样的:
Android 文件系统布局
file:///android_asset/
| cordova.file.applicationDirectoryfile:///android_asset/data/data/<app-id>/
| cordova.file.applicationStorageDirectoryfile:///android_asset/data/data/<app-id>/cache
| cordova.file.cacheDirectoryfile:///android_asset/data/data/<app-id>/files
| cordova.file.dataDirectoryfile:///android_asset/data/data/<app-id>/Documents
| cordova.file.documents<sdcard>/
| cordova.file.externalRootDirectory<sdcard>/Android/data/<app-id>/
| cordova.file.externalApplicationStorageDirectory<sdcard>/Android/data/<app-id>/cache
| cordova.file.externalCacheDirectry<sdcard>/Android/data/<app-id>/files
| cordova.file.externalDataDirectory
不幸的是,当我将我的设备(4.4.2/Lenovo 平板电脑)插入我的 PC 或 Mac 时,我没有看到这个。相反,我看到:
- Internal Storage
|- .IdeaDesktopHD
|- .lelauncher
|- .magic
|- .powercenterhd
|- Alarms
|- Android
|- Audio
|- Bluetooth
|- Contact
|- data
|- DCIM
|- Document
|- Download
|- googleota
|- legc
|- LenovoReaper
|- LesyncDownload
|- Movies
|- MyFavorite
|- Notifications
|- Others
|- Pictures
|- Podcasts
|- powercenterhd
|- Ringtones
|- SHAREit
知道我应该将文件复制到哪里以便我的应用可以看到它们吗?
好了。我的部分问题是我被 cordova 上的文件系统/cordova-plugin-file API 的异步性质所困扰。我必须进行一些代码重构才能使文件列表正确显示,但一旦我这样做了,文件就会正确显示,而不管它们在设备上的什么位置。
这是适用的代码。请注意,您需要将 cordova-plugin-file 添加到您的 Cordova/PhoneGap 项目中,并且它不能在浏览器中运行。我实际上在另一个 if/then 块中有这个块——如果它在浏览器中是 运行,则显示 html5 <input type=file>
,如果它在移动设备中,则显示此块:
var localURLs = [
cordova.file.dataDirectory,
cordova.file.documentsDirectory,
cordova.file.externalApplicationStorageDirectory,
cordova.file.externalCacheDirectory,
cordova.file.externalRootDirectory,
cordova.file.externalDataDirectory,
cordova.file.sharedDirectory,
cordova.file.syncedDataDirectory
];
var index = 0;
var i;
var statusStr = "";
var addFileEntry = function (entry) {
var dirReader = entry.createReader();
dirReader.readEntries(
function (entries) {
var fileStr = "";
var i;
for (i = 0; i < entries.length; i++) {
if (entries[i].isDirectory === true) {
// Recursive -- call back into this subdirectory
addFileEntry(entries[i]);
} else {
fileStr += (entries[i].fullPath + "<br>"); // << replace with something useful
index++;
}
}
// add this directory's contents to the status
statusStr += fileStr;
// display the file list in #results
if (statusStr.length > 0) {
$("#results").html(statusStr);
}
},
function (error) {
console.log("readEntries error: " + error.code);
statusStr += "<p>readEntries error: " + error.code + "</p>";
}
);
};
var addError = function (error) {
console.log("getDirectory error: " + error.code);
statusStr += "<p>getDirectory error: " + error.code + ", " + error.message + "</p>";
};
for (i = 0; i < localURLs.length; i++) {
if (localURLs[i] === null || localURLs[i].length === 0) {
continue; // skip blank / non-existent paths for this platform
}
window.resolveLocalFileSystemURL(localURLs[i], addFileEntry, addError);
}
编辑(2018 年 2 月):即使您可以在 Android 文件传输 上看到文件,您也可能看不到以编程方式返回 any 结果,即使您在 Cordova 应用程序中设置了构建时权限。这是由于 runtime 添加到 Android 的权限检查(我相信 > 6.0)。有几个插件可以帮助解决这个问题;在某些时候,我猜文件插件也会为它添加自动请求。这是我对 Cordova cli-7.0.1
:
在您的 config.xml 中,设置所需的应用权限。您将需要 READ_EXTERNAL_STORAGE(如果您要这样做,也需要写)。我还添加了下面引用的两个插件:
<plugin name="cordova-plugin-device" source="npm" spec="1.1.6" />
<plugin name="cordova.plugins.diagnostic" spec="^3.7.1" />
<config-file platform="android" parent="/manifest" mode="replace">
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
</config-file>
然后,最好在应用启动代码的某处(即设备就绪事件的处理程序)检查运行时权限并在需要时添加它们:
if (device.platform === "Android") {
// request read access to the external storage if we don't have it
cordova.plugins.diagnostic.getExternalStorageAuthorizationStatus(function (status) {
if (status === cordova.plugins.diagnostic.permissionStatus.GRANTED) {
console.log("External storage use is authorized");
} else {
cordova.plugins.diagnostic.requestExternalStorageAuthorization(function (result) {
console.log("Authorization request for external storage use was " + (result === cordova.plugins.diagnostic.permissionStatus.GRANTED ? "granted" : "denied"));
}, function (error) {
console.error(error);
});
}
}, function (error) {
console.error("The following error occurred: " + error);
});
}
编辑(2021 年 8 月):Android 10.x 及以上介绍了范围存储的概念,在 Android 中进一步完善11(参见 https://developer.android.com/about/versions/11/privacy/storage)。其中大部分是为了加强设备的安全性。这对您的应用意味着 reading/writing 永久文件应该限制在以下两个沙盒目录中,如果您是一个好的 Android 公民:
- cordova.file.externalDataDirectory(如果您有 SD 卡)
- cordova.file.datadirectory
除非您有充分的理由查看整个文件系统(并且可以说服 Google Play 商店团队),如果您尝试调用所有文件访问权限,您的应用可能会被拒绝。 来自链接文章:
Note: If you publish your app to Google Play, carefully read the notice. If you target Android 11 and declare All files access, it can affect your ability to publish and update your app on Google Play.