Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/file/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 如何为“打开输入流”;虚拟的;云上的文件?_Android_File_Cloud_Uri_Android Contentprovider - Fatal编程技术网

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 &lt; 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 &lt; 1) {
        throw new FileNotFoundException();
    }

    return resolver
        .openTypedAssetFileDescriptor(uri, openableMimeTypes[0], null)
        .createInputStream();
}