Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/211.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/vba/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 从contentProvider.update()使用已更改的uri通知更改_Android_Sqlite_Android Contentprovider_Contentobserver - Fatal编程技术网

Android 从contentProvider.update()使用已更改的uri通知更改

Android 从contentProvider.update()使用已更改的uri通知更改,android,sqlite,android-contentprovider,contentobserver,Android,Sqlite,Android Contentprovider,Contentobserver,我已经实现了ContentProvider的update(),并使用getContext().getContentResolver().notifyChange(uri,null)向观察者发出通知 我显然需要的是,每当只有一行受到影响时,我希望使用特定于行的uri进行通知,但找不到这样做的方法。 一个额外的查询,比如“selectid where selectionArgs”可以做到这一点,但这将是一个愚蠢的方法 onchange(boolean,uri)获取完整的uri而不是特定的行,很容易理

我已经实现了
ContentProvider
update()
,并使用
getContext().getContentResolver().notifyChange(uri,null)向观察者发出通知

我显然需要的是,每当只有一行受到影响时,我希望使用特定于行的uri进行通知,但找不到这样做的方法。 一个额外的查询,比如
“selectid where selectionArgs”
可以做到这一点,但这将是一个愚蠢的方法

onchange(boolean,uri)
获取完整的uri而不是特定的行,很容易理解这是因为
ContentProvider.update()
正在发送相同的uri

some code for more clarity
MyContentProvider的update()方法

 @Override
    public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {

        Log.d("TAG", "update " + uri.getPath());

        int count = 0;
        switch (uriMatcher.match(uri)) {
        case BOOKS:
            count = booksDB.update(DATABASE_TABLE, values, selection, selectionArgs);
            break;
        case BOOK_ID:
            count = booksDB.update(DATABASE_TABLE, values,
                    _ID + " = " + uri.getPathSegments().get(1)
                            + (!TextUtils.isEmpty(selection) ? " AND (" + selection + ')' : ""),
                    selectionArgs);
            break;
        default:
            throw new IllegalArgumentException("Unknown URI " + uri);
        }

        if (count == 1) {
            Cursor c = query(uri, new String[] { _ID }, selection, selectionArgs, null);
            long rowId = Long.valueOf(c.getString(c.getColumnIndex(_ID)));
            uri = ContentUris.withAppendedId(CONTENT_URI, rowId);
        }
        getContext().getContentResolver().notifyChange(uri, null);
        return count;

    }
我将更新一些类似的表格

getContentResolver().update(MyContentProvider.CONTENT_URI, values1, MyContentProvider._ID+"<?", new String[]{"3"}));

getContentResolver().update(MyContentProvider.CONTENT\u URI,values1,MyContentProvider.\u ID+”不幸的是,我无法提出简单的解决方案(因为我不知道您需要运行的完整代码和更新),我们可以尝试一些方法(其中一些我已经在我的应用程序中实现):

  • ContentValues
    中提供ID-这种方式看起来不适用于您的情况,需要通过调用
    notifyChange()
    进行循环
  • 为带有查询的请求提供特定的
    Uri
    (只有一些特定的应用程序在选择时需要许多不同的查询,通常在
    Uri
    中包含查询参数要容易得多)。在程序的另一部分收到带有该特定
    Uri的通知后,它将能够检查其“当前项”是否已更新并采取适当行动(例如,在最简单的情况下,文章列表和一篇文章在单独的活动中打开;然后从服务器更新后台文章列表,您可能还需要更新当前打开的文章,因此,需要知道它是否已更新)。您应该能够使用刚刚收到的
    Uri
    检查观察者一侧的特定项目,因为它(Uri)将包含您用于查询的参数

在提供者方法中,只需返回附加id的uri即可

@Override
public Uri insert(Uri uri, ContentValues values) {
    Log.i(TAG, "insert " + uri);
    final SQLiteDatabase db = mOpenHelper.getWritableDatabase();
    final int match = URI_MATCHER.match(uri);

    Uri returnUri;
    switch (match) {
        case MESSAGE: {
            long _id = db.insert(MessageContract.MessageEntry.TABLE_NAME, null, values);
            if (_id > 0)
                returnUri = ContentUris.withAppendedId(MessageContract.MessageEntry.CONTENT_URI, _id);
            else
                throw new android.database.SQLException("Failed to insert row into " + uri);
            break;
        }

        default:
            throw new UnsupportedOperationException("Unknown uri: " + uri);
    }

    getContext().getContentResolver().notifyChange(returnUri, null);


    return returnUri;
}
并为后代向true注册您的观察者

getContentResolver().registerContentObserver(MessageContract.MessageEntry.CONTENT_URI, true, mContentObserver);

要从Uri获取id,您可以使用
ContentUris.parseId(Uri)

通过ContentValues传递id,并将其附加到通知url。这样您就不必进行单独的查询

@Override
public int update(@NonNull Uri uri, ContentValues values, String selection, String[] selectionArgs) {
    int rows = _database.update(getTableName(), values, selection, selectionArgs);
    if (rows > 0) {
        Uri itemUri = ContentUris.withAppendedId(uri, values.getAsLong(DatabaseModel.COLUMN_ID)); // DatabaseModel.COLUMN_ID is "_id"

        getContext().getContentResolver().notifyChange(itemUri, null);
    }
    return rows;
}

一些代码可能有用。如何更新多行?请确保在内容提供程序的
query()
方法返回的游标上调用
setNotificationUri(ContentResolver cr,Uri Uri)
。更多信息位于。>>您应该能够使用刚刚收到的Uri检查观察者一侧的特定项,因为它(Uri)将包含参数我的意思是,你可以引入特定的Uri,比如BASE/updateItemsWith/dateLater/而不是使用BASE/updateItemsWith并在更新参数中提供选择。然后在observer中,你可以使用BASE/updateItemsWith/dateLater/检查特定的项。最初的问题是更新而不是插入。更新返回nu行数已更新,而insert返回Id。更新时不能使用此方法。