在KitKat之前(或在新Gallery之前)Intent.ACTION_GET_CONTENT返回这样的URI
内容://媒体/外部/图像/媒体/ 3951.
使用ContentResolver和quering
MediaStore.Images.Media.DATA返回文件URL.
但是在KitKat中,Gallery会返回一个URI(通过"Last"),如下所示:
内容://com.android.providers.media.documents/document/image:3951
我该如何处理?
android android-intent android-contentresolver android-gallery
Android内容提供商的文档描述了使用ContentResolver,从中获取getContentResolver(),访问内容.
然而,还有一个ContentProviderClient,可以从中获得getContentResolver().acquireContentProviderClient(authority).它似乎提供了或多或少相同的方法,ContentResolver用于从提供者访问内容.
我什么时候应该使用ContentProviderClient而不是ContentResolver直接使用?有什么好处?
我尝试了一个解决方案(见下文)工作正常,除了在Android 4.4中调用startActivityForResult()一个名为"Open from"的活动,其中包含"Recent","Images","Downloads"以及几个可供选择的应用程序.当我选择"图像"并尝试解析返回的内容URI(使用下面的代码)时,调用cursor.getString()返回null.如果我使用Gallery应用程序选择完全相同的文件,则cursor.getString()返回文件路径.我只在API级别16和19中对此进行了测试.一切都按照16中的预期运行.至于19,我必须选择Gallery或其他应用程序,否则它不起作用.
private String getRealPathFromURI(Context context, Uri contentUri) {
Cursor cursor = null;
try {
String[] proj = { MediaStore.Images.Media.DATA };
cursor = context.getContentResolver().query(contentUri, proj, null, null, null);
int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
cursor.moveToFirst();
String path = cursor.getString(column_index);
return path;
} finally {
if (cursor != null) {
cursor.close();
}
}
}
Run Code Online (Sandbox Code Playgroud) ContentProviders和ContentResolver有什么区别?我不想要SQLite数据库.我正在开发一个媒体应用程序.
我正在开发一个应用程序,我需要插入大量的联系人条目.目前约有600个联系人,共有6000个电话号码.最大的联系人有1800个电话号码.
截至今天的状态是我创建了一个自定义帐户来保存联系人,因此用户可以选择在"联系人"视图中查看联系人.
但插入触点非常缓慢.我使用ContentResolver.applyBatch插入联系人.我尝试了不同大小的ContentProviderOperation列表(100,200,400),但总运行时间约为.相同.插入所有联系人和号码大约需要30分钟!
我发现在SQlite中缓慢插入的大多数问题都会导致交易.但是因为我使用ContentResolver.applyBatch方法,所以我不控制它,我会假设ContentResolver为我负责事务管理.
所以,我的问题是:我做错了什么,或者我能做些什么来加快这个速度?
安德斯
编辑: @jcwenger:哦,我明白了.很好的解释!
那么我将首先插入raw_contacts表,然后插入带有名称和数字的数据表.我将失去的是对我在applyBatch中使用的raw_id的后向引用.
所以我必须获取新插入的raw_contacts行的所有id作为数据表中的外键吗?
我有一个应用程序需要从服务器提取数据并将其插入SQLite数据库以响应用户输入.我认为这很简单 - 从服务器提取数据的代码是AsyncTask的一个相当简单的子类,它完全按照我的预期工作,而不会挂起UI线程.我使用一个简单的接口为它实现了回调功能,并将其包装在一个静态类中,所以我的代码如下所示:
MyServerCaller.getFolderContents(folderId, new OnFolderContentsResponseListener() {
@Override
public void onFolderContentsResponse(final List<FilesystemEntry> contents) {
// do something with contents
}
}
Run Code Online (Sandbox Code Playgroud)
一切都还不错.即使服务器需要一个小时来检索数据,UI仍然可以顺利运行,因为getFolderContents中的代码在AsyncTask的doInBackground方法中运行(该方法与UI分开).在getFolderContents方法的最后,调用onFolderContentsResponse并传递从服务器接收的FilesystemEntry列表.我只是真的说了这一切,所以我希望很清楚我的问题不在getFolderContents方法或我的任何网络代码中,因为它不会在那里发生.
当我尝试通过onFolderContentsResponse方法中的ContentProvider子类插入数据库时出现问题; 在执行该代码时,UI总是挂起,这使我相信尽管从AsyncTask的doInBackground方法调用,插入仍然在UI线程上运行.以下是有问题的代码:
MyServerCaller.getFolderContents(folderId, new OnFolderContentsResponseListener() {
@Override
public void onFolderContentsResponse(final List<FilesystemEntry> contents) {
insertContentsIntoDB(contents);
}
}
Run Code Online (Sandbox Code Playgroud)
和insertContentsIntoDB方法:
void insertContentsIntoDB(final List<FilesystemEntry> contents) {
for (FilesystemEntry entry : contents) {
ContentValues values = new ContentValues();
values.put(COLUMN_1, entry.attr1);
values.put(COLUMN_2, entry.attr2);
// etc.
mContentResolver.insert(MyContentProvider.CONTENT_URI, values);
}
}
Run Code Online (Sandbox Code Playgroud)
其中mContentResolver先前已设置为getContentResolver()方法的结果.
我已经尝试将insertContentsIntoDB放在自己的Thread中,如下所示:
MyServerCaller.getFolderContents(folderId, new OnFolderContentsResponseListener() {
@Override
public void onFolderContentsResponse(final List<FilesystemEntry> contents) { …Run Code Online (Sandbox Code Playgroud) java user-interface multithreading android android-contentresolver
这里已经讨论了很多问题,主要是不同的结果,并且由于API的变化和不同类型的URI,没有明确的答案.
我自己没有答案,但让我们谈谈它.该ExifInterface有一个接受一个构造函数filePath.这本身很烦人,因为现在不鼓励依赖路径 - 你应该使用Uris和ContentResolver.好.
我们的Uri名字uri可以从意图中检索出来onActivityResult(如果您从图库中选择图片ACTION_GET_CONTENT)或者可以是Uri我们之前拥有的(如果您从相机中选择图片并打电话intent.putExtra(MediaStore.EXTRA_OUTPUT, uri)).
我们uri可以有两种不同的模式:
file://架构.那些很容易治疗,因为他们坚持这条道路.你可以打电话new ExifInterface(uri.getPath()),你就完成了.content://界面.我个人不知道那是什么,但让我发疯.据我所知,第二种情况应该用ContentResolver你能得到的东西来对待Context.getContentResolver().以下适用于我测试的所有应用程序,无论如何:
public static ExifInterface getPictureData(Context context, Uri uri) {
String[] uriParts = uri.toString().split(":");
String path = null;
if (uriParts[0].equals("content")) {
// we can use ContentResolver.
// let’s query the DATA column which …Run Code Online (Sandbox Code Playgroud) 目标:从XML数据刷新数据库
过程:
数据库操作相当标准的东西.问题是CRUD操作不是在内部完成,ContentProvider而是使用ContentResolver插件,例如看起来像resolver.insert(CONTENT_URI, contentValues).ContentResolver API似乎没有任何与事务相关的东西,我无法使用,bulkInsert因为我间歇性地插入2个表(另外我也希望delete在事务内部).
我正在考虑ContentProvider通过使用注册我自定义的监听器,registerContentObserver但由于ContentResolver#acquireProvider隐藏了方法,我如何获得正确的引用?
我运气不好吗?
sqlite android transactions android-contentresolver android-contentprovider
什么是添加一种合适的方式DISTINCT和/或GROUPBY以ContentResolver-基于查询.现在我必须为每个特殊情况创建自定义URI.有没有更好的办法?(我仍以1.5为最低共同标准编程)
任何人都能解释一下我在处理日历活动时使用的每个术语吗?
Uri event_uri = Uri.parse("content://com.android.calendar/" + "events");
什么是uri,实际上是什么内容,因为我们可以将int值初始化为0?是否
可以使用默认值初始化uri?
Uri reminder_uri = Uri.parse("content://com.android.calendar/" + "reminders");
什么意味着这些uri?event_uri和之间有什么区别reminder_uri?
ContentValues values = new ContentValues();
values.put("calendar_id", 1);
values.put("title", str);
values.put("description", m_strDescription);
第一个做什么? values.put("calendar_id", 1);
ContentResolver cr = getContentResolver();
内容解析器有什么用?有时我们会写:
Uri u = cr.insert(event_uri, values)
这是什么uri?它与前两个uris有何不同,例如event_uri和reminder_uri
再次 values.put("event_id", Long.parseLong(event.getLastPathSegment()));
cr.insert(remindar_uri, values);
它有什么作用?