Android webview - 如何从外部存储中获取文件
Android webview - how to fetch a file from external storage
我有一个使用 webview 环绕网络应用程序的移动应用程序。
网络应用程序有一个按钮可以打开一个大的 .zip 文件(例如 100 MB)。
用户单击一个按钮,然后 select 生成一个 .zip 文件。
这会触发一个 onChange 函数,其中包含一个类型为 File (Blob) 的变量,其中包括如下属性:
- 文件名
- 文件大小
- 文件类型 (application/zip)
javascript 代码然后解析 .zip 文件,提取其中的特定数据并在网络应用程序中使用它。
当通过 Chrome 浏览器调用应用程序时,这在网络应用程序中运行良好。
例如,当在 Android phone 上的 chrome 浏览器中操作时,我可以拉取 .zip 文件并在网络应用程序中打开它。
我想做同样的事情但是使用移动应用程序。
我可以使用文件选择器选择 .zip 文件,并将其传递给 Webview,但我无法从 Javascript 代码中获取文件。
作为参考,我可以通过使用 stringBuilder 创建 data_uri 并传递内容(如数据:image/jpeg;base64)来传递图像。
但是 zip 文件要大得多。
从 Javascript 端调用 fetch(fileUri) 时出现错误。
我正在使用以下 uri
/storage/emulated/0/Android/data/com.example/files/Download/file2.zip
提取成功,但 returns 一个大小为 165(即不是文件的实际大小)的 blob 承载错误消息:
{
"error": "Not Found",
"message": "The requested URL was not found on the server. If you entered the URL manually please check your spelling and try again."
}
程序流程是这样的:
- 我 select 通过 FileChooser 生成 .zip 文件。
- 在onActivityResult中,uri值为
/document/msf:12858
(通过uri = intent.getData();
看到)
- uri需要映射到真实路径文件url,这样fileUrl才会传给webview
- 然后 Webview 将使用 fileUrl 获取文件。
我搜索了如何在使用 FileChooser selecting 文件时获取真实路径文件 url,并找到了
, and 个链接。
我无法获得真实的文件路径,所以我决定读取文件并将其写入另一个位置,这样我就可以获得文件路径。 (这样做效率不高,只是为了检查功能)。
我使用以下代码创建新文件:
InputStream stream = context.getContentResolver().openInputStream(uri);
File file2 = new File(context.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS), "file2.zip");
writeBytesToFile(stream, file2);
我在创建文件时没有看到任何错误,并且在创建文件时,读取和写入新文件的字节数符合预期。
对于 file2,我得到的值为:
/storage/emulated/0/Android/data/com.example/files/Download/file2.zip
然后,在 Javascript 代码中,我获取了这个文件路径。
但是我得到了一个 Blob,上面有“找不到文件”的内容。
所以:
- 如何验证文件确实已创建以及路径是否可以从 webview 中获取?
- 如何获取原始 selected 文件的真实文件路径,这样我就不必为了获取文件路径而将原始文件读写到新位置?
谢谢
通过执行以下步骤,我能够从外部存储中获取文件:
- 创建初始 uri (
uri1
)
uri 由以下人员创建:
- 正在通过以下方式在存储目录中创建一个临时文件 (
file1
)
context.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS)
我不确定为什么需要创建一个临时文件,但如果我不创建一个文件,我就无法获取 uri。
创建文件 3
- 获取uri通过
uri uri1 = FileProvider.getUriForFile(context, "com.example.android.fileprovider", file1);
- 创建具有以下属性的意图:
Intent.ACTION_OPEN_DOCUMENT
category: Intent.CATEGORY_OPENABLE
type: "application/zip"
extra attribute: fileIntent.putExtra(DocumentsContract.EXTRA_INITIAL_URI, uri1);
这将打开一个对话框,用于在 Downloads
目录中选择可打开的 zip 文件,
- 选择文件后,将创建一个新的 uri (
uri2
),其中包含所选文件的名称。
- 提取文件名通过
String fileName = getFileName(context, uri2);
- 通过附加文件名创建 dirPath
dirPath = "/data/user/0/com.example/" + fileName;
- 如果
dirPath
不存在(第一次),将文件写入其 dirPath
位置。
- 在连续的情况下 dirPath 存在,因此无需重新写入文件。
- 使用常规 Java 打开文件,例如通过
ZipFile zip = new ZipFile(dirPath);
我有一个使用 webview 环绕网络应用程序的移动应用程序。
网络应用程序有一个按钮可以打开一个大的 .zip 文件(例如 100 MB)。
用户单击一个按钮,然后 select 生成一个 .zip 文件。
这会触发一个 onChange 函数,其中包含一个类型为 File (Blob) 的变量,其中包括如下属性:
- 文件名
- 文件大小
- 文件类型 (application/zip)
javascript 代码然后解析 .zip 文件,提取其中的特定数据并在网络应用程序中使用它。
当通过 Chrome 浏览器调用应用程序时,这在网络应用程序中运行良好。
例如,当在 Android phone 上的 chrome 浏览器中操作时,我可以拉取 .zip 文件并在网络应用程序中打开它。
我想做同样的事情但是使用移动应用程序。
我可以使用文件选择器选择 .zip 文件,并将其传递给 Webview,但我无法从 Javascript 代码中获取文件。
作为参考,我可以通过使用 stringBuilder 创建 data_uri 并传递内容(如数据:image/jpeg;base64)来传递图像。
但是 zip 文件要大得多。
从 Javascript 端调用 fetch(fileUri) 时出现错误。
我正在使用以下 uri
/storage/emulated/0/Android/data/com.example/files/Download/file2.zip
提取成功,但 returns 一个大小为 165(即不是文件的实际大小)的 blob 承载错误消息:
{
"error": "Not Found",
"message": "The requested URL was not found on the server. If you entered the URL manually please check your spelling and try again."
}
程序流程是这样的:
- 我 select 通过 FileChooser 生成 .zip 文件。
- 在onActivityResult中,uri值为
/document/msf:12858
(通过uri = intent.getData();
看到) - uri需要映射到真实路径文件url,这样fileUrl才会传给webview
- 然后 Webview 将使用 fileUrl 获取文件。
我搜索了如何在使用 FileChooser selecting 文件时获取真实路径文件 url,并找到了
我无法获得真实的文件路径,所以我决定读取文件并将其写入另一个位置,这样我就可以获得文件路径。 (这样做效率不高,只是为了检查功能)。
我使用以下代码创建新文件:
InputStream stream = context.getContentResolver().openInputStream(uri);
File file2 = new File(context.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS), "file2.zip");
writeBytesToFile(stream, file2);
我在创建文件时没有看到任何错误,并且在创建文件时,读取和写入新文件的字节数符合预期。
对于 file2,我得到的值为:
/storage/emulated/0/Android/data/com.example/files/Download/file2.zip
然后,在 Javascript 代码中,我获取了这个文件路径。
但是我得到了一个 Blob,上面有“找不到文件”的内容。
所以:
- 如何验证文件确实已创建以及路径是否可以从 webview 中获取?
- 如何获取原始 selected 文件的真实文件路径,这样我就不必为了获取文件路径而将原始文件读写到新位置?
谢谢
通过执行以下步骤,我能够从外部存储中获取文件:
- 创建初始 uri (
uri1
) uri 由以下人员创建:- 正在通过以下方式在存储目录中创建一个临时文件 (
file1
)context.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS)
我不确定为什么需要创建一个临时文件,但如果我不创建一个文件,我就无法获取 uri。 创建文件 3 - 获取uri通过 uri uri1 = FileProvider.getUriForFile(context, "com.example.android.fileprovider", file1);
- 创建具有以下属性的意图:
Intent.ACTION_OPEN_DOCUMENT
category: Intent.CATEGORY_OPENABLE
type: "application/zip"
extra attribute: fileIntent.putExtra(DocumentsContract.EXTRA_INITIAL_URI, uri1);
这将打开一个对话框,用于在Downloads
目录中选择可打开的 zip 文件,
- 正在通过以下方式在存储目录中创建一个临时文件 (
- 选择文件后,将创建一个新的 uri (
uri2
),其中包含所选文件的名称。 - 提取文件名通过
String fileName = getFileName(context, uri2);
- 通过附加文件名创建 dirPath
dirPath = "/data/user/0/com.example/" + fileName;
- 如果
dirPath
不存在(第一次),将文件写入其dirPath
位置。 - 在连续的情况下 dirPath 存在,因此无需重新写入文件。
- 使用常规 Java 打开文件,例如通过
ZipFile zip = new ZipFile(dirPath);