我在本教程中研究了如何使用ContentProviders和加载器
我是怎么看的:我们有一个Activity和ListView,SimpleCursorAdapter和CursorLoader.我们也实施ContentProvider.
在Activity我们可以调用getContentResolver().insert(URI, contentValues);通过点击一个按钮.
在我们的实现中ContentProvider,在insert()方法结束时,我们调用getContentResolver().notifyChange(URI, null);并且我们CursorLoader将收到消息,它应该重新加载数据并更新UI.此外,如果我们FLAG_REGISTER_CONTENT_OBSERVER在SimpleCursorAdapter其中使用它也将接收消息并且onContentChanged()将调用其方法.
因此,如果我们插入,更新或删除数据,我们的ListView将会更新.
Activity.startManagingCursor(cursor);已弃用,cursor.requery()已弃用,因此我没有看到任何练习意义 cursor.setNotificationUri().
我查看了setNotificationUri()方法的源代码,发现它调用mContentResolver.registerContentObserver(mNotifyUri, true, mSelfObserver)了方法.也是CursorLoader一样的.最后,游标将接收消息,并在Cursor内部调用以下方法:
protected void onChange(boolean selfChange) {
synchronized (mSelfObserverLock) {
mContentObservable.dispatchChange(selfChange, null);
// ...
}
}
Run Code Online (Sandbox Code Playgroud)
但我无法理解这一点.
所以我的问题是:我们为什么要叫cursor.setNotificationUri()在query()我们的方法ContentProvider实现?
database android cursor android-contentresolver android-contentprovider
我有一个包含2个部分的应用程序.
每个都作为不同的进程运行.问题是他们都共享一个数据库.当服务尝试写入某些内容并且UI正在读取数据时,我经常会遇到数据库锁定错误.反之亦然.怎么办呢?
synchronise我猜想,即使是因为2个不同的过程也无济于事.Content Providers 也许是一个选项,但由于我使用复杂的查询来挖掘信息,所以也很难使用它. 如何让两个进程共享数据库.任何提示将不胜感激.
我正在浏览一些代码,我意识到我实际上并不知道如何使用连接CursorLoader和LoaderManager组合CursorAdapter.这是我困惑的部分.
agendaAdapter = new MyAgendaAdapter(this, null);
makeProviderBundle(new String[] {"_id", "event_name", "start_date", "start_time",
"end_date", "end_time", "location"}, "date(?) >= start_date and date(?) <= end_date",
new String[]{getChosenDate(), getChosenDate()}, null);
getLoaderManager().initLoader(0, myBundle, MainDisplayActivity.this);
list.setAdapter(agendaAdapter);
Run Code Online (Sandbox Code Playgroud)
那么query()我的自定义方法如何ContentProvider将其发送到特定的方法CursorAdapter呢?我只是没有看到连接.我理解其他一切,但这个问题是什么.哦,我应该提一下,代码工作正常.
android android-contentprovider android-loadermanager android-cursorloader
我正在使用我的自定义ContentProvider与sqlite数据库进行通信.我想在列表(使用ListFragment)上显示来自两个表(具有多对多关系)的数据.我能想到的唯一解决方案就是使用rawQuery.问题是,如果这是一个好习惯,还是应该以其他方式解决这个问题?
表格示例:
表A:ID,COLUMN_FROM_A
表B:ID,COLUMN_FROM_B
连接表AB:ID,FK_ID_A,FK_ID_B
ContentProvider中重写的查询方法示例:
@Override
public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
SQLiteQueryBuilder queryBuilder = new SQLiteQueryBuilder();
Cursor cursor = null;
int uriType = URIMatcher.match(uri);
switch (uriType) {
case TABLE_A_URI:
queryBuilder.setTables("TABLE_A");
cursor = queryBuilder.query(databaseHelper.getReadableDatabase(), projection, selection, selectionArgs, null, null, sortOrder);
break;
case TABLE_B_URI:
queryBuilder.setTables("TABLE_B");
cursor = queryBuilder.query(databaseHelper.getReadableDatabase(), projection, selection, selectionArgs, null, null, sortOrder);
break;
case TABLE_JOIN_A_B_URI:
cursor = databaseHelper.getReadableDatabase().rawQuery("select a.COLUMN_FORM_A, b.COLUMN_FROM_B from TABLE_A a, TABLE_B b, TABLE_AB ab where ab.FK_ID_A=a.ID and ab.FK_ID_B=b.ID", …Run Code Online (Sandbox Code Playgroud) 我需要获取所有电话联系人及其电子邮件地址和照片uri:
这就是我在做什么:
private void getContacts() {
ContentResolver cr = getContentResolver();
Cursor cur = cr.query(Contacts.CONTENT_URI, null, null, null, Contacts.DISPLAY_NAME);
if (cur.getCount() > 0) {
while (cur.moveToNext()) {
// if
// (Integer.parseInt(cur.getString(cur.getColumnIndex(ContactsContract.Contacts.HAS_PHONE_NUMBER)))
// > 0) {
Contact contact = new Contact();
String id = cur.getString(cur.getColumnIndex(ContactsContract.Contacts._ID));
Uri uri = getContactPhotoUri(Long.parseLong(id));
// set photoUri
contact.setContactPhotoUri(uri);
// set name
contact.setContactName(cur.getString(cur.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME)));
// get the phone number
Cursor pCur = cr.query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null,
ContactsContract.CommonDataKinds.Phone.CONTACT_ID + " = ?", new String[] { id }, null);
while (pCur.moveToNext()) {
// …Run Code Online (Sandbox Code Playgroud) performance android android-contentresolver android-contentprovider android-contacts
我想知道是否可以在同一操作中使用android.content.ContentResolver.applyBatch()方法将master和detail记录保存到内容提供者,其中providers参数中的后续ContentProviderOperation项取决于先前项的结果.
我遇到的问题是,当调用ContentProviderOperation.newInsert(Uri)方法并且Uri是不可变的时,实际的Uri是未知的.
我想出的内容如下所示:
Master Uri:content://com.foobar.masterdetail/master
Detail Uri:content://com.foobar.masterdetail/master/#/detail
ArrayList<ContentProviderOperation> operations = new ArrayList<ContentProviderOperation>();
operations.add(ContentProviderOperation.newInsert(intent.getData())
.withValue(Master.NAME, "")
.withValue(Master.VALUE, "")
.build());
operations.add(ContentProviderOperation.newInsert(intent.getData()
.buildUpon()
.appendPath("#") /* ACTUAL VALUE NOT KNOWN UNTIL MASTER ROW IS SAVED */
.appendPath("detail")
.build())
.withValue(Detail.MASTER_ID, /* WHAT GOES HERE? */)
.withValue(Detail.NAME, "")
.withValue(Detail.VALUE, "")
.build());
ContentProviderResult[] results = this.getContentResolver().applyBatch(MasterDetail.AUTHORITY, operations);
for (ContentProviderResult result : results) {
Uri test = result.uri;
}
Run Code Online (Sandbox Code Playgroud)
在我的内容提供程序中,我重写了applyBatch()方法,以便将操作包装在事务中.
这是可能的还是有更好的方法来做到这一点?
谢谢.
我们知道应用程序运行时内容提供程序加载.但我希望在内容提供商推出之前进行一些操作.我怎么抓住这个手术?在调用内容提供者的onCreate方法之前
我开发了一个Android应用程序并发布了1.0版本.该应用程序包含带有5个表的SQLite本地数据库.
现在我们计划发布2.0版本,同时更新1.0版用户.在2.0版本中,我们已经包含了前面5个表的额外两个表,现在有7个表.
现在我的问题是,版本1.0的用户都在本地数据库中有一些数据,如果他更新到版本2.0,以前的数据会丢失吗?如果是这样的话.那么替代方法是什么?
有一个命令可以根据意图启动一个活动:am start.还发送广播:am broadcast.
我想可能应该有一个shell命令来查询内容提供者,可能是这样的:
query content://com.myapp.authority/path --where 'column=?' --arg 1 --order 'column desc'
Run Code Online (Sandbox Code Playgroud)
或类似的.
有吗?
我的应用允许用户从其他应用导入他们的照片和视频.现在谷歌用Google照片取代了Google+照片,但有些事情让我感到震惊.其中一件事是在应用重启后重新使用导入的文件.我感觉他们已经收紧了Google照片使用图片URI返回意图时发出的权限,因此在我的应用程序被杀后,它不再拥有访问上传文件的权限.我正在接受安检:
java.lang.SecurityException: Permission Denial: opening provider com.google.android.apps.photos.contentprovider.MediaContentProvider from ProcessRecord{2c17ab9e 2124:com.myapp.myapp/u0a436} (pid=2124, uid=10436) that is not exported from uid 10427
Run Code Online (Sandbox Code Playgroud)
编辑:
我也在重复使用提供的文件时遇到同样的问题 com.google.android.apps.docs.sync.filemanager.FileProvider
有什么建议/解决方法吗?我知道我可以在失去许可之前阅读该文件,所以理论上我可以复制它,但我不能说我非常喜欢这个...