Android 如何为“打开输入流”;虚拟的;云上的文件?
试图转换我从Android 如何为“打开输入流”;虚拟的;云上的文件?,android,file,cloud,uri,android-contentprovider,Android,File,Cloud,Uri,Android Contentprovider,试图转换我从Intent.ACTION\u GET\u CONTENT获得的URI,输入流对于本地文件可以正常打开,但是对于来自驱动器(/document/acc=1;doc=4089)的URI),我得到一个FileNotFoundException,表示文件是“虚拟的”。如何打开此类文件的输入流 获取URI: Intent i = new Intent(Intent.ACTION_GET_CONTENT); i.setType("*/*"); //No I18N tr
Intent.ACTION\u GET\u CONTENT
获得的URI
,输入流对于本地文件可以正常打开,但是对于来自驱动器(/document/acc=1;doc=4089
)的URI
),我得到一个FileNotFoundException
,表示文件是“虚拟的”。如何打开此类文件的输入流
获取URI:
Intent i = new Intent(Intent.ACTION_GET_CONTENT);
i.setType("*/*"); //No I18N
try{
startActivityForResult(Intent.createChooser(i, "Pick a file"), REQUEST_CODE_UPLOAD_FILE_FOR_IMPORT);
}catch (android.content.ActivityNotFoundException ex){
Log.e("Error","FileManager not found!");
}
及
获取输入流:
InputStream is = null;
try {
is = contentResolver.openInputStream(importedFileUri);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
结果:
URI路径:/document/acc=1;单据=4089/单据/acc%3D1%3Bdoc%3D4089
GetString-
content://com.google.android.apps.docs.storage/document/acc%3D1%3Bdoc%3D4089
URI方案内容
URI授权:com.google.android.apps.docs.storage
URI片段:null
URI路径段:
文件
acc=1;doc=4089
解析类型(内容):application/vnd.google-apps.spreadsheet
分机:空
例外情况:
java.io.FileNotFoundException:文件是虚拟的:acc=1;doc=4089
检查URI处的文件是否为虚拟文件:
private static boolean isVirtualFile(Uri uri) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
if (!DocumentsContract.isDocumentUri(activity, uri)) {
return false;
}
Cursor cursor = activity.getContentResolver().query(
uri,
new String[]{DocumentsContract.Document.COLUMN_FLAGS},
null, null, null);
int flags = 0;
if (cursor.moveToFirst()) {
flags = cursor.getInt(0);
}
cursor.close();
return (flags & DocumentsContract.Document.FLAG_VIRTUAL_DOCUMENT) != 0;
} else {
return false;
}
}
使用以下命令从虚拟文件获取输入流:
private static InputStream getInputStreamForVirtualFile(Uri uri, String mimeTypeFilter)
throws IOException {
ContentResolver resolver = activity.getContentResolver();
String[] openableMimeTypes = resolver.getStreamTypes(uri, mimeTypeFilter);
if (openableMimeTypes == null ||
openableMimeTypes.length < 1) {
throw new FileNotFoundException();
}
return resolver
.openTypedAssetFileDescriptor(uri, openableMimeTypes[0], null)
.createInputStream();
}
更多信息。由于应用程序无法使用openInputStream()方法直接打开虚拟文件,因此如果您在操作\u打开\u文档意图中包含类别\u可打开类别,则应用程序不会收到任何虚拟文件 要打开虚拟文件,您的客户端应用程序需要包含特殊的逻辑来处理它们。例如,如果要获取文件的字节表示以预览文件,则需要从文档提供程序请求备用MIME类型 要在应用程序中获取虚拟文档的URI,首先需要创建打开文件选择器UI的意图,就像前面在Seach for documents中显示的代码一样
private boolean isVirtualFile(Uri uri) {
if (!DocumentsContract.isDocumentUri(this, uri)) {
return false;
}
Cursor cursor = getContentResolver().query(
uri,
new String[] { DocumentsContract.Document.COLUMN_FLAGS },
null, null, null);
int flags = 0;
if (cursor.moveToFirst()) {
flags = cursor.getInt(0);
}
cursor.close();
return (flags & DocumentsContract.Document.FLAG_VIRTUAL_DOCUMENT) != 0;
}
验证文件是否为虚拟文件后,可以将该文件强制转换为其他MIME类型,例如图像文件。下面的代码片段显示如何检查虚拟文件是否可以表示为图像,如果可以,则从虚拟文件获取输入流
private InputStream getInputStreamForVirtualFile(Uri uri, String mimeTypeFilter)
throws IOException {
ContentResolver resolver = getContentResolver();
String[] openableMimeTypes = resolver.getStreamTypes(uri, mimeTypeFilter);
if (openableMimeTypes == null ||
openableMimeTypes.length < 1) {
throw new FileNotFoundException();
}
return resolver
.openTypedAssetFileDescriptor(uri, openableMimeTypes[0], null)
.createInputStream();
}
描述和代码片段取自android文档。查看链接和参考以了解有关Storage Access Framework的更多信息
当然可以。请显示您的代码。
但是对于来自驱动器的URI(/document/acc=1;doc=4089)我
没有URI。没有内容方案。请告诉完整的方案。@greenapps这是我的代码和结果。您应该打印importedFileUri.toString()
。因为这是真正的内容方案。正在尝试转换URI
。我看不到您正在尝试更改uri。当然,这是不必要的。
private boolean isVirtualFile(Uri uri) {
if (!DocumentsContract.isDocumentUri(this, uri)) {
return false;
}
Cursor cursor = getContentResolver().query(
uri,
new String[] { DocumentsContract.Document.COLUMN_FLAGS },
null, null, null);
int flags = 0;
if (cursor.moveToFirst()) {
flags = cursor.getInt(0);
}
cursor.close();
return (flags & DocumentsContract.Document.FLAG_VIRTUAL_DOCUMENT) != 0;
}
private InputStream getInputStreamForVirtualFile(Uri uri, String mimeTypeFilter)
throws IOException {
ContentResolver resolver = getContentResolver();
String[] openableMimeTypes = resolver.getStreamTypes(uri, mimeTypeFilter);
if (openableMimeTypes == null ||
openableMimeTypes.length < 1) {
throw new FileNotFoundException();
}
return resolver
.openTypedAssetFileDescriptor(uri, openableMimeTypes[0], null)
.createInputStream();
}