2017-09-26 87 views
0

試圖轉換我從Intent.ACTION_GET_CONTENT得到的URI,輸入流打開罰款的本地文件,但URI從驅動器(/document/acc=1;doc=4089)我得到FileNotFoundException,說該文件是「虛擬」。我怎樣才能打開這樣的文件的輸入流?如何在雲上打開「虛擬」文件的inputstream?

獲取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!"); 
    } 

importedFileUri = data.getData(); 
       System.out.println("URI path: "+importedFileUri.getPath()+" "+importedFileUri.getEncodedPath()); 
       System.out.println("URI Scheme "+importedFileUri.getScheme()); 
       System.out.println("URI Authority :"+importedFileUri.getAuthority()); 
       System.out.println("URI Fragment :"+importedFileUri.getFragment()); 
       System.out.println("URI path segments : "); 
       for(String str : importedFileUri.getPathSegments()){ 
        System.out.println("\t" +str); 
       } 
       String ext; 
       if (importedFileUri.getScheme().equals(ContentResolver.SCHEME_CONTENT)) { 
        final MimeTypeMap mime = MimeTypeMap.getSingleton(); 
        ext = mime.getExtensionFromMimeType(mActivity.getContentResolver().getType(importedFileUri)); 
        System.out.println("resolved type (content) : "+ mActivity.getContentResolver().getType(importedFileUri)); 
       } else { 
        ext = MimeTypeMap.getFileExtensionFromUrl(Uri.fromFile(new File(importedFileUri.getPath())).toString()); 
        System.out.println("resolved type (other) : "+ Uri.fromFile(new File(importedFileUri.getPath())).toString()); 
       } 

獲取的InputStream:

InputStream is = null; 
       try { 
        is = contentResolver.openInputStream(importedFileUri); 
       } catch (FileNotFoundException e) { 
        e.printStackTrace(); 
       } 

結果:

URI路徑:/ document/acc = 1; doc = 4089/document/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片段:空

URI路徑段:

文件

ACC = 1; DOC = 4089

解決類型(內容):應用/ vnd.google-apps.spreadsheet

EXT:空

除外:

java.io.FileNotFoundException:文件是虛擬的:acc = 1; doc = 4089

+0

當然可以。請顯示你的代碼。 – greenapps

+0

'但是對於來自驅動器的URI(/ document/acc = 1; doc = 4089)I'這不是uri。沒有內容計劃。請告訴完整的方案。 – greenapps

+0

@greenapps這是我的代碼和我的結果 – ColonD

回答

0

檢查文件是否在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(); 
    } 

總體

if (isVirtualFile(sourceuri)) { 
    input = getInputStreamForVirtualFile(sourceuri, getMimeType(name)); 
} else { 
    input = activity.getContentResolver().openInputStream(sourceuri); 
} 

更多信息here