phr*_*eed 13 android inputstream android-contentresolver android-contentprovider
我有一些大文件(图像和视频),我需要存储在内容提供商.android文档表明......
如果您公开的字节数据太大而无法放入表本身 - 例如大型位图文件 - 将数据公开给客户端的字段实际上应该包含content:URI字符串.这是允许客户端访问数据文件的字段.该记录还应该有另一个名为"_data"的字段,该字段列出设备上该文件的确切文件路径.此字段不是由客户端读取,而是由ContentResolver读取.客户端将在面向用户的字段上调用ContentResolver.openInputStream(),该字段包含项目的URI.ContentResolver将为该记录请求"_data"字段,并且因为它具有比客户端更高的权限,所以它应该能够直接访问该文件并将该文件的读取包装器返回给客户端. - http://developer.android.com/guide/topics/providers/content-providers.html#creating
我找一个例子有点困难.特别是我希望在ImageView的上下文中使用位图.考虑以下代码准代码(它不起作用)......
ImageView iv = ....
String iconUri = cursor.getString(cursor.getColumnIndex(Table.ICON));
iv.setImageURI(Uri.parse(iconUri));
Run Code Online (Sandbox Code Playgroud)
意见/问题...
setImageURI实现使用内容解析openInputStream,所以这应该工作.
String scheme = mUri.getScheme();
...
} else if (ContentResolver.SCHEME_CONTENT.equals(scheme)
|| ContentResolver.SCHEME_FILE.equals(scheme)) {
try {
d = Drawable.createFromStream(
mContext.getContentResolver().openInputStream(mUri),
null);
Run Code Online (Sandbox Code Playgroud)
--frameworks /碱/核心/ JAVA /机器人/插件/ ImageView.java
我搞定了.我从MediaStore和MediaProvider中提取了一些提示.包含数据的文件根据内容提供者(目录),列名,行ID和媒体类型命名.然后内容解析器获取文件描述符,如此...
Uri iconUri = Uri.withAppendedPath(Table.getUri(cursor), Table.ICON);
ib.setImageURI(iconUri);
Run Code Online (Sandbox Code Playgroud)
......内容提供商以实物回应......
@Override
public ParcelFileDescriptor openFile (Uri uri, String mode) {
int imode = 0;
if (mode.contains("w")) imode |= ParcelFileDescriptor.MODE_WRITE_ONLY;
if (mode.contains("r")) imode |= ParcelFileDescriptor.MODE_READ_ONLY;
if (mode.contains("+")) imode |= ParcelFileDescriptor.MODE_APPEND;
List<String> pseg = uri.getPathSegments();
if (pseg.size() < 3) return null;
try {
File filePath = filePathFromRecord(pseg.get(2), pseg.get(1));
return ParcelFileDescriptor.open(filePath, imode);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
return null;
}
Run Code Online (Sandbox Code Playgroud)
Pēt*_*une 12
在问题的下半部分给出的解决方案是基本正确的.我将尝试在此处添加更多详细信息.
执行此操作后getContentResolver().openInputStream(...),内容解析程序将转到您的内容提供商并调用其openFile方法.这是ContentProvider.java中的openFile外观:
public ParcelFileDescriptor openFile(Uri uri, String mode)
throws FileNotFoundException {
throw new FileNotFoundException("No files supported by provider at "
+ uri);
}
Run Code Online (Sandbox Code Playgroud)
所以这解释了"无文件支持..."错误的确切来源!您可以通过覆盖openFile子类中的方法并提供自己的实现来解决这个问题.它很整洁:当任何客户端执行openInputStream或更新时,您可以完美控制文件的放置位置openOutputStream.
在phreed的问题中的代码示例提供了一个暗示如何实现的样子.这是我的略微修改版本,它还根据需要创建目录和文件.我是这些东西的新手,所以这可能不是最好的做事方式,但它提出了一个想法.首先,它应该检查外部存储是否可用.
@Override
public ParcelFileDescriptor openFile(Uri uri, String mode) throws FileNotFoundException {
File root = new File(Environment.getExternalStorageDirectory(),
"/Android/data/com.example.myapp/cache");
root.mkdirs();
File path = new File(root, uri.getEncodedPath());
// So, if the uri was content://com.example.myapp/some/data.xml,
// we'll end up accessing /Android/data/com.example.myapp/cache/some/data.xml
int imode = 0;
if (mode.contains("w")) {
imode |= ParcelFileDescriptor.MODE_WRITE_ONLY;
if (!path.exists()) {
try {
path.createNewFile();
} catch (IOException e) {
// TODO decide what to do about it, whom to notify...
e.printStackTrace();
}
}
}
if (mode.contains("r")) imode |= ParcelFileDescriptor.MODE_READ_ONLY;
if (mode.contains("+")) imode |= ParcelFileDescriptor.MODE_APPEND;
return ParcelFileDescriptor.open(path, imode);
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
11796 次 |
| 最近记录: |