java - 将 fileChooserParams 中的 mime 类型转换为 Intent.setType 的正确格式
问题描述
我正在尝试使用 Android 中的 WebView 上传文件。
这是正在使用的代码:
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
@Override
public boolean onShowFileChooser(WebView webView, final ValueCallback<Uri[]> filePathsCallback, final WebChromeClient.FileChooserParams fileChooserParams) {
Intent intent = fileChooserParams.createIntent();
LOG.d(LOG_TAG, "mime types: " + Arrays.toString(fileChooserParams.getAcceptTypes()));
// PRINTS [.jpg,.png,.tiff,.jpeg,.tif,.pdf] !!
try {
parentEngine.cordova.startActivityForResult(new CordovaPlugin() {
@Override
public void onActivityResult(int requestCode, int resultCode, Intent intent) {
// ...
}
}, intent, FILECHOOSER_RESULTCODE);
} catch (ActivityNotFoundException e) {
// ...
}
return true;
}
问题是当我必须使用的外部库 ( )ng-file-upload
触发此方法的执行时,在 fileChooserParams 中作为参数传递的 mime 类型是:[.jpg,.png,.tiff,.jpeg,.tif,.pdf]
. 我在允许的 mime 类型列表中看不到其中的大多数。
因此,我在 LogCat 中发现了这个错误:
No activity found to handle file chooser intent.: android.content.ActivityNotFoundException: No Activity found to handle Intent { act=android.intent.action.GET_CONTENT cat=[android.intent.category.OPENABLE] typ=.jpg,.png,.tiff,.jpeg,.tif,.pdf }
如果我只是添加intent.setType("image/* application/pdf");
一切按预期工作!
现在的问题是:在我想提交给cordova-android的贡献者的合并请求中,我如何安全地将fileChooserParams转换为正确的格式?
解决方案
我使用以下代码改进了解决方案:
// Validation utility for mime types
private List<String> extractValidMimeTypes(String[] mimeTypes) {
List<String> results = new ArrayList<String>();
List<String> mimes;
if (mimeTypes.length() == 1 && mimeTypes[0].contains(",")) {
mimes = Arrays.asList(mimeTypes[0].split(","));
} else {
mimes = Arrays.asList(mimeTypes);
}
MimeTypeMap mtm = MimeTypeMap.getSingleton();
for (String mime : mimes) {
if (mime != null && mime.trim().startsWith(".")) {
String extensionWithoutDot = mime.trim().substring(1, mime.trim().length());
String derivedMime = mtm.getMimeTypeFromExtension(extensionWithoutDot);
if (derivedMime != null && !results.contains(derivedMime)) {
// adds valid mime type derived from the file extension
results.add(derivedMime);
}
} else if (mtm.getExtensionFromMimeType(mime) != null && !results.contains(mime)) {
// adds valid mime type checked agains file extensions mappings
results.add(mime);
}
}
return results;
}
public boolean onShowFileChooser(WebView webView, final ValueCallback<Uri[]> filePathsCallback, final WebChromeClient.FileChooserParams fileChooserParams) {
Intent intent = fileChooserParams.createIntent();
List<String> validMimeTypes = extractValidMimeTypes(fileChooserParams.getAcceptTypes());
if (validMimeTypes.isEmpty()) {
intent.setType(DEFAULT_MIME_TYPE);
} else {
intent.setType(String.join(" ", validMimeTypes));
}
...
有关更多详细信息,请参阅我的拉取请求。
推荐阅读
- javascript - JQuery从ajax中删除列表元素
- java - GOF 中提到的可插拔适配器
- c++ - 检查 parallel_for 循环语法
- git - 在 git-merge 中使用 vimdiff,如何显示提交 ID?
- python - 如何计算Python中列中有多少名称的计数
- typescript - 如何让 Typescript 从通用类型列表的 Array.map 调用中推断出特定类型?
- java - 比较 JMeter 中的 2 个 CSV 文件
- php - 如何在 Wordpress 中隐藏空的自定义字段?
- command - 如何在 PC 上的 Ubuntu 中启动浏览器?
- c# - 将 csv 标头合并为新标头