在我的应用程序中,用户可以选择文件并在相应的应用程序中打开它们(使用ACTION_VIEW意图)。
在将数据提供给其他应用程序之前,我需要对数据进行一些处理。所以我使用了流媒体解决方案:我实现了一个实现openTypedAssetFile
和writeDataToPipe
的ContentProvider(此方法填充由openPipeHelper
创建的输出ParcelFileDescriptor)。
这有效:我可以打开.pdf文件,.txt文件等。流媒体似乎是正确的。
我可以使用三方应用程序打开图像。
但是,当我使用Gallery
打开图片时,它不起作用(图库显示黑屏),我得到以下异常:
fail to open myfile.jpg
UriImage(21890): java.io.FileNotFoundException: Not a whole file
我查看了Gallery源代码(here),我可以看到异常抛出此处:
try {
if (MIME_TYPE_JPEG.equalsIgnoreCase(mContentType)) {
InputStream is = mApplication.getContentResolver()
.openInputStream(mUri);
mRotation = Exif.getOrientation(is);
Utils.closeSilently(is);
}
**mFileDescriptor = mApplication.getContentResolver()
.openFileDescriptor(mUri, "r");**
if (jc.isCancelled()) return STATE_INIT;
return STATE_DOWNLOADED;
} catch (FileNotFoundException e) {
Log.w(TAG, "fail to open: " + mUri, e);
return STATE_ERROR;
}
然而,一旦在Gallery应用程序中,如果我选择"设置为壁纸",那么我可以看到我的图像,然后很好地流式传输。因此,当Gallery打开时会出现问题。
经过深入研究(在ContentResolver代码中等),我无法理解为什么它会以这种方式运行。似乎Gallery
不支持流式文件。是对的吗 ?
你有什么想法吗?
非常感谢。
答案 0 :(得分:-1)
String scheme = mUri.getScheme();
ContentResolver contentResolver = getContentResolver();
// If we are sent file://something or
// content://org.openintents.filemanager/mimetype/something...
if (scheme.equals("file")
|| (scheme.equals("content") && fileUri
.getEncodedAuthority().equals(
"org.openintents.filemanager"))) {
// Get the path
filePath = fileUri.getPath();
// Trim the path if necessary
// openintents filemanager returns
// content://org.openintents.filemanager/mimetype//mnt/sdcard/xxxx.jpg
if (filePath.startsWith("/mimetype/")) {
String trimmedFilePath = filePath
.substring("/mimetype/".length());
filePath = trimmedFilePath.substring(trimmedFilePath
.indexOf("/"));
}
} else if (scheme.equals("content")) {
// If we are given another content:// URI, look it up in the
// media provider
filePath = getFilePathFromContentUri(fileUri,
contentResolver);
} else {
Log.e("filePath--------->>>>>", filePath + "");
}
和
private String getFilePathFromContentUri(Uri selectedVideoUri,
ContentResolver contentResolver) {
String filePathString;
String[] filePathColumn = { MediaColumns.DATA };
Cursor cursor = contentResolver.query(selectedVideoUri, filePathColumn,
null, null, null);
cursor.moveToFirst();
int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
filePathString = cursor.getString(columnIndex);
cursor.close();
return filePathString;
}
现在使用此文件路径..
try {
if (MIME_TYPE_JPEG.equalsIgnoreCase(mContentType)) {
InputStream is = mApplication.getContentResolver()
.openInputStream(filePath); // ** change is here
mRotation = Exif.getOrientation(is);
Utils.closeSilently(is);
}
** mFileDescriptor = mApplication.getContentResolver()
.openFileDescriptor(filePath, "r"); **
if (jc.isCancelled()) return STATE_INIT;
return STATE_DOWNLOADED;
} catch (FileNotFoundException e) {
Log.w(TAG, "fail to open: " + mUri, e);
return STATE_ERROR;
}
这对我有用