7

update()を使用してオブザーバーにContentProvider通知を実装しましたgetContext().getContentResolver().notifyChange(uri, null);

私の明らかな必要性は、1つの行だけが影響を受けるときはいつでも、行固有のURIで通知したいのですが、そうする方法を見つけることができなかったということです。のような追加のクエリ"select id where selectionArgs"でこれを行うことができますが、これは愚かな方法になります。

onchange(boolean, 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"}));

率直に言って、コードは質問とほとんど関係がなく、コンテキストを提供しようとしているだけです

4

3 に答える 3

8

プロバイダーメソッドで、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)

于 2014-10-23T18:31:51.907 に答える
1

残念ながら、簡単な解決策を提案することはできません(実行する必要のある完全なコードと更新を認識していないため)、いくつかの方法を試すことができます(そのうちのいくつかは私のアプリケーションに実装しました):

  • IDを指定しContentValuesます-この方法はあなたのケースには当てはまらないようで、notifyChange();を呼び出すループが必要です。
  • クエリを使用してリクエストに固有のものを提供Uriします(一部の特定のアプリのみが、選択に多くのさまざまなクエリを必要とします。通常、クエリパラメータをに含める方がはるかに簡単ですUri)。プログラムの別の部分がその特定の通知を受け取った後、Uriそれが「現在のアイテム」が更新されたかどうかを確認し、適切に動作することができます(たとえば、記事のリストと1つの記事が別々のアクティビティで開かれている最も単純なケース;次に記事のリストを更新しますサーバーからのバックグラウンドで現在開いている記事も更新する必要がある場合があるため、更新されたかどうかを知る必要があります)。受信したばかりのオブザーバー側の特定のアイテムをチェックできるはずです。これは、そのアイテムUri(Uri)に、クエリに使用したパラメーターが含まれているためです。
于 2013-03-27T06:47:53.843 に答える
0

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;
}
于 2018-03-28T00:01:55.140 に答える