使用 KitKat 存储访问框架后打开 Google Drive File Content URI
Posted
技术标签:
【中文标题】使用 KitKat 存储访问框架后打开 Google Drive File Content URI【英文标题】:Open a Google Drive File Content URI after using KitKat Storage Access Framework 【发布时间】:2014-09-30 00:42:42 【问题描述】:我正在使用适用于 android 4.4 的存储访问框架并打开文件选择器。
除了从 Google Drive 中选择文件外,一切正常,我只能弄清楚如何将其作为输入流打开,但我想获得一个 java File 对象。
返回的内容 uri 如下所示:content://com.google.android.apps.docs.storage/document/acc%3D4%3Bdoc%3D2279
其他类似但没有可让我获取文件名、文件大小和内容的有效解决方案的问题:
Get real path from URI, Android KitKat new storage access framework Android Gallery on KitKat returns different Uri for Intent.ACTION_GET_CONTENT我还查看了 Paul Burke 的 FileChooser (https://github.com/iPaulPro/aFileChooser),这是问题列表中最常见的问题。
如何从该内容 uri 中获取文件?
我目前的解决方法是从输入流中写出一个临时文件。
谢谢!
【问题讨论】:
你找到解决办法了吗? 【参考方案1】:好的。我发现正确的方法是将来自其他帖子的输入流与来自 contentresolver 的一些数据结合使用。
这里有一些很难找到的 android 文档供参考:https://developer.android.com/training/secure-file-sharing/retrieve-info.html
获取mimetype、文件名和文件大小的相关代码:
Uri returnUri = returnIntent.getData();
String mimeType = getContentResolver().getType(returnUri);
Cursor returnCursor =
getContentResolver().query(returnUri, null, null, null, null);
int nameIndex = returnCursor.getColumnIndex(OpenableColumns.DISPLAY_NAME);
int sizeIndex = returnCursor.getColumnIndex(OpenableColumns.SIZE);
returnCursor.moveToFirst();
TextView nameView = (TextView) findViewById(R.id.filename_text);
TextView sizeView = (TextView) findViewById(R.id.filesize_text);
nameView.setText(returnCursor.getString(nameIndex));
sizeView.setText(Long.toString(returnCursor.getLong(sizeIndex)));
并获取文件内容:
getContentResolver().openInputStream(uri)
希望这对其他人有所帮助。
【讨论】:
遇到同样的问题,***.com/questions/30206483/… 请看一下,给出一些解决方案 它只获取文件名,但我想获取谷歌驱动文件的内容 uri 你找到了 mimeType,但你没有使用它。您使用参数“uri”调用“.openInputStream”,但您没有告诉我们您是如何获得该变量的。一些更多的信息将不胜感激.. @Moonbloom 知道文件名后可以创建一个空文件File.createTempFile(String prefix, String suffix)
,然后将InputStream复制到这个文件中。 ***.com/questions/11501418/…【参考方案2】:
这段代码解决了我的问题,当我尝试从谷歌驱动器中选择图像时,应用程序崩溃了,
private void setImagePath(Intent data) throws Exception
String wholeID="";
Uri selectedImage = data.getData();
if(Build.VERSION.SDK_INT<=Build.VERSION_CODES.JELLY_BEAN_MR2)
wholeID=getUriPreKitkat(selectedImage);
else
wholeID = DocumentsContract.getDocumentId(selectedImage);
// Split at colon, use second item in the array
Log.i("debug","uri google drive "+wholeID);
String id = wholeID.split(":")[1];
String[] column = MediaStore.Images.Media.DATA;
// where id is equal to
String sel = MediaStore.Images.Media._ID + "=?";
Cursor cursor = getActivity().getContentResolver().
query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
column, sel, new String[]id, null);
int columnIndex = cursor.getColumnIndex(column[0]);
if (cursor.moveToFirst())
filePath = cursor.getString(columnIndex);
cursor.close();
【讨论】:
【参考方案3】:添加到@Keith Entzeroth 答案,在得到 fileName、fileSize 和 Input Stream 之后,这是获取文件的方式
public static File getFile(final Context context, final Uri uri)
Log.e(TAG,"inside getFile==");
ContentResolver contentResolver = context.getContentResolver();
try
String mimeType = contentResolver.getType(uri);
Cursor returnCursor =
contentResolver.query(uri, null, null, null, null);
int nameIndex = returnCursor.getColumnIndex(OpenableColumns.DISPLAY_NAME);
int sizeIndex = returnCursor.getColumnIndex(OpenableColumns.SIZE);
returnCursor.moveToFirst();
String fileName = returnCursor.getString(nameIndex);
String fileSize = Long.toString(returnCursor.getLong(sizeIndex));
InputStream inputStream = contentResolver.openInputStream(uri);
File tempFile = File.createTempFile(fileName, "");
tempFile.deleteOnExit();
FileOutputStream out = new FileOutputStream(tempFile);
IOUtils.copyStream(inputStream,out);
return tempFile;
catch (Exception e)
e.printStackTrace();
return null;
【讨论】:
解决方案确实有效,但是文件扩展名旁边有一些数字以上是关于使用 KitKat 存储访问框架后打开 Google Drive File Content URI的主要内容,如果未能解决你的问题,请参考以下文章
从URI获取真实路径,Android KitKat新的存储访问框架[重复]
KitKat ACTION_OPEN_DOCUMENT 在三星设备上不显示文档