如何在PhoneGap将看到的android目录中获取文档 [英] How to get documents in an android directory that PhoneGap will see

查看:18
本文介绍了如何在PhoneGap将看到的android目录中获取文档的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我希望能够将一些文件复制到我的 PhoneGap/Cordova 的 Documents 目录中,以便在我使用 cordova-plugin-file API 列出该目录时显示它们.不幸的是,文件 API 与平板电脑存储的实际布局之间似乎存在一些脱节.下面是文件插件规范所说的系统目录结构应该是这样的:

I'd like to be able to copy some files into my PhoneGap / Cordova's Documents directory, so that they show up when I use the cordova-plugin-file API to list that directory. Unfortunately, there seems to be some disconnect between the file API and what's actually laid out on the tablet's storage. Here's what the File plugin spec says the system directory structure should look like:

  • file:///android_asset/ |cordova.file.applicationDirectory
  • file:///android_asset/data/data// |cordova.file.applicationStorageDirectory
  • file:///android_asset/data/data//cache |cordova.file.cacheDirectory
  • file:///android_asset/data/data//files |cordova.file.dataDirectory
  • file:///android_asset/data/data//Documents |cordova.file.documents
  • / |cordova.file.externalRootDirectory
  • /Android/data// |cordova.file.externalApplicationStorageDirectory
  • /Android/data//cache |cordova.file.externalCacheDirectry
  • /Android/data//files |cordova.file.externalDataDirectory
  • 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 时,我没有看到这个.相反,我看到:

Unfortunately, I'm not seeing this when I plug my device (4.4.2 / Lenovo tablet) into my PC or Mac. Instead, I see:

- 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

知道我应该在哪里复制文件以便我的应用程序可以看到它们吗?

Any idea where I should be copying the files so that my app can see them?

推荐答案

现在好了.我的部分问题是我被cordova上的文件系统/cordova-plugin-file API的异步性质所困扰.我必须进行一些代码重构才能使文件列表正确显示,但是一旦我这样做了,无论文件在设备上的什么位置,它们都会正确显示.

Well now. Part of my problem was that I got bit by the asynchronous nature of the filesystem / cordova-plugin-file API on cordova. I had to do some code refactoring to get the file list to show up properly, but once I did, the files displayed properly regardless of where they were on the device.

这是适用的代码.请注意,您需要将cordova-plugin-file 添加到您的Cordova/PhoneGap 项目中,并且它在浏览器中不起作用.我实际上在另一个 if/then 块中有这个块——如果它在浏览器中运行,显示 html5 <input type=file>,如果它在移动设备中,显示这个块:

Here's the applicable code. Note that you'll need the cordova-plugin-file added to your Cordova/PhoneGap project, and that it won't work in the browser. I actually have this block inside another if/then block -- if it's running in a browser, show the html5 <input type=file>, if it's in a mobile device, show this block:

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 文件传输上看到文件,您也可能无法以编程方式返回任何结果,即使您在 Cordova 应用程序中设置了构建时间权限.这是由于 runtime 权限检查被添加到 Android(我相信 > 6.0).有几个插件可以帮助解决这个问题;在某些时候,我猜文件插件也会为它添加自动请求.这是我在 Cordova cli-7.0.1 上所做的:


EDIT (Feb 2018): even if you can see the files on Android File Transfer, you might not get any results back programmatically, even if you have build time permissions set in your Cordova app. This is due to runtime permission checks added to Android (I believe > 6.0). There are a couple plugins that can help get around this; at some point, I'm guessing the file plugin will add automatic requests for it as well. Here's what I've done as of Cordova cli-7.0.1:

在您的 config.xml 中,设置所需的应用权限.您将需要 READ_EXTERNAL_STORAGE(如果您打算这样做,也需要写入).我还添加了下面引用的两个插件:

In your config.xml, set the needed app permissions. You'll need READ_EXTERNAL_STORAGE (and write as well, if you are going to do that). I'm also adding two plugins that are referenced below:

<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>

然后,最好在您应用的启动代码(即设备就绪事件的处理程序)中的某处,检查运行时权限并在需要时添加它们:

Then, preferably somewhere in your app's startup code (i.e., the handler for the device ready event), check for the runtime permissions and add them if needed:

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).其中大部分是为了加强设备的安全性.这对您的应用意味着,如果您是一名优秀的 Android 公民,则读取/写入永久文件应仅限于以下两个沙盒目录:

EDIT (August 2021): Android 10.x and above introduces the concept of scoped storage, which is further refined in Android 11 (see https://developer.android.com/about/versions/11/privacy/storage). Most of this is to tighten up security on your device. What it means for your app is that reading/writing to permanent files should be limited to the two following sandboxed directories if you're a good Android citizen:

  • cordova.file.externalDataDirectory(如果您有 SD 卡)
  • cordova.file.datadirectory

除非您有充分的理由环顾整个文件系统(并且可以说服 Google Play 商店团队这样做),如果您尝试这样做,您的应用很可能会被拒绝调用所有文件访问权限.来自链接的文章:

Unless you have a good reason to be looking around the entire filesystem (and can convince the Google Play store team of this), your app is likely to get rejected if you try to invoke All files access. From the linked article:

注意:如果您将应用发布到 Google Play,请仔细阅读通知.如果您面向 Android 11 并声明所有文件访问权限,则可能会影响您在 Google Play 上发布和更新应用的能力.

这篇关于如何在PhoneGap将看到的android目录中获取文档的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆