λ³Έλ¬Έ λ°”λ‘œκ°€κΈ°

빈 ꡬ멍 μ±„μš°κΈ°

[Android] ContentProvider λ¬Έμ„œ 읽기

 

https://developer.android.com/reference/android/content/ContentProvider

 

ContentProvider  |  Android Developers

android.net.wifi.hotspot2.omadm

developer.android.com

 

public abstract class ContentProvider extends Object implements ComponentCallbacks2

 

μ½˜ν…μΈ  ν”„λ‘œλ°”μ΄λ”λŠ” μ•ˆλ“œλ‘œμ΄λ“œ μ• ν”Œλ¦¬μΌ€μ΄μ…˜λ“€ 쀑에 μ€‘μš” κ΅¬μ„±μš”μ†Œλ“€ 쀑 ν•˜λ‚˜λ‘œ, μ• ν”Œλ¦¬μΌ€μ΄μ…˜λ“€μ— μ½˜ν…μΈ λ₯Ό μ œκ³΅ν•©λ‹ˆλ‹€. μ½˜ν…μΈ  ν”„λ‘œλ°”μ΄λ”λŠ” 데이터λ₯Ό μΊ‘μŠν™”ν•˜κ³  단일 ContentResolver μΈν„°νŽ˜μ΄μŠ€λ₯Ό 톡해 μ• ν”Œλ¦¬μΌ€μ΄μ…˜λ“€μ— 이것을 μ œκ³΅ν•©λ‹ˆλ‹€. μ½˜ν…μΈ  ν”„λ‘œλ°”μ΄λ”λŠ” μ—¬λŸ¬ μ• ν”Œλ¦¬μΌ€μ΄μ…˜λ“€ μ‚¬μ΄μ—μ„œ 데이터λ₯Ό κ³΅μœ ν•΄μ•Όν•  λ•Œλ§Œ ν•„μš”ν•©λ‹ˆλ‹€. 예λ₯Ό λ“€μ–΄, μ—°λ½μ²˜ λ°μ΄ν„°λŠ” μ—¬λŸ¬ μ•±λ“€μ—μ„œ μ‚¬μš©λ˜κ³ , μ½˜ν…μΈ  ν”„λ‘œλ°”μ΄λ” μ•ˆμ—μ„œ μ €μž₯λ˜μ–΄μ•Όλ§Œ ν•©λ‹ˆλ‹€. λ§Œμ•½ μ—¬λŸ¬ μ• ν”Œλ¦¬μΌ€μ΄μ…˜λ“€ μ‚¬μ΄μ—μ„œ 데이터λ₯Ό κ³΅μœ ν•  ν•„μš”κ°€ μ—†λ‹€λ©΄ SQLiteDatabaseλ₯Ό 톡해 μ§μ ‘μ μœΌλ‘œ λ°μ΄ν„°λ² μ΄μŠ€λ₯Ό μ‚¬μš©ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

 

μš”μ²­(request)은 ContentResolverλ₯Ό ν†΅ν•΄μ„œ λ§Œλ“€μ–΄μ§€κ³ , μ‹œμŠ€ν…œμ€ 주어진 URI의 κΆŒν•œμ„ μ κ²€ν•˜κ³  μš”μ²­μ„ κΆŒν•œμ„ 가진 λ“±λ‘λœ μ½˜ν…νŠΈ ν”„λ‘œλ°”μ΄λ”λ‘œ λ³΄λƒ…λ‹ˆλ‹€. μ½˜ν…μΈ  ν”„λ‘œλ°”μ΄λ”λŠ” URI의 λ‚˜λ¨Έμ§€ 뢀뢄을 μ›ν•˜λŠ” λŒ€λ‘œ 해석할 수 μžˆμŠ΅λ‹ˆλ‹€. UriMatcher ν΄λž˜μŠ€λŠ” URI νŒŒμ‹±μ„ 도와주죠.

 

κ΅¬ν˜„λ˜μ–΄μ•Ό ν•˜λŠ” μ£Όμš” λ©”μ†Œλ“œλ“€μž…λ‹ˆλ‹€.

  • onCreate() : ν”„λ‘œλ°”μ΄λ”λ₯Ό μ΄ˆκΈ°ν™”ν•˜λŠ”λ° ν˜ΈμΆœλ©λ‹ˆλ‹€. 
  • query(Uri, String[], Bundel, CancellationSignal) : ν˜ΈμΆœμžμ—κ²Œ 데이터λ₯Ό λ°˜ν™˜ν•©λ‹ˆλ‹€.
  • insert(Uri, ContentValues) : 컨텐츠 ν”„λ‘œλ°”μ΄λ”λ‘œ μƒˆ 데이터λ₯Ό μ‚½μž…ν•©λ‹ˆλ‹€.
  • update(Uri, ContentValues, Bundle) : μ½˜ν…μΈ  ν”„λ‘œλ°”μ΄λ” μ•ˆμ˜ μ‘΄μž¬ν•˜λŠ” 데이터λ₯Ό μ—…λ°μ΄νŠΈν•©λ‹ˆλ‹€.
  • delete(Uri, Bundle) : μ½˜ν…μΈ  ν”„λ‘œλ°”μ΄λ”μ˜ 데이터λ₯Ό μ‚­μ œν•©λ‹ˆλ‹€.
  • getType(Uri) : μ½˜ν…μΈ  ν”„λ‘œλ°”μ΄λ” μ•ˆμ˜ λ°μ΄ν„°μ˜ MIME νƒ€μž…μ„ λ°˜ν™˜ν•©λ‹ˆλ‹€.

 

❗

(insert(Uri, ContentValues), update(Uri,ContentValues, Bundle)κ³Ό 같은) 데이터 μ ‘κ·Ό λ©”μ†Œλ“œλ“€μ€ ν•œλ²ˆμ— λ§Žμ€ μ“°λ ˆλ“€μ—μ„œ 호좜될 수 있고, λ°˜λ“œμ‹œ thread-safeν•΄μ•Όλ§Œ ν•©λ‹ˆλ‹€. (onCreate() 같은) λ‹€λ₯Έ λ©”μ†Œλ“œλ“€μ€ μ• ν”Œλ¦¬μΌ€μ΄μ…˜μ˜ 메인 μ“°λ ˆλ“œμ—μ„œλ§Œ 호좜되고, λ„ˆλ¬΄ κΈ΄ μž‘μ—…μ„ μˆ˜ν–‰ν•˜λŠ” 것은 λ°˜λ“œμ‹œ ν”Όν•΄μ•Όλ§Œν•©λ‹ˆλ‹€. μ˜ˆμƒλ˜λŠ” μ“°λ ˆλ“œ λ™μž‘λ“€μ€ λ©”μ†Œλ“œ μ„€λͺ…듀을 λ³΄μ„Έμš”.

 

ContentResolver둜의 μš”μ²­λ“€μ€ μžλ™μœΌλ‘œ μ μ ˆν•œ μ½˜ν…μΈ  ν”„λ‘œλ°”μ΄λ” μΈμŠ€ν„΄μŠ€μ— μ „λ‹¬λ˜κ³ , ν•˜μœ„ ν΄λž˜μŠ€λ“€μ€ ν”„λ‘œμ„ΈμŠ€ κ°„μ˜ ν˜ΈμΆœλ“€μ˜ μƒμ„Έν•œ 것듀에 λŒ€ν•΄μ„œλŠ” κ±±μ •ν•  ν•„μš”κ°€ μ—†μŠ΅λ‹ˆλ‹€.

 

onCreate

public abstract boolean onCreate()

 

μŠ€νƒ€νŠΈμ—… λ•Œμ— 컨텐츠 ν”„λ‘œλ°”μ΄λ”λ₯Ό μ΄ˆκΈ°ν™”ν•˜κΈ° μœ„ν•΄ κ΅¬ν˜„ν•˜μ„Έμš”. 이 λ©”μ„œλ“œλŠ” μ• ν”Œλ¦¬μΌ€μ΄μ…˜μ˜ μ‹œμž‘(launch) μ‹œκ°„μ— μ• ν”Œλ¦¬μΌ€μ΄μ…˜μ˜ 메인 μ“°λ ˆλ“œμ—μ„œ λͺ¨λ“  λ“±λ‘λœ μ½˜ν…μΈ  ν”„λ‘œλ°”μ΄λ”λ“€μ„ ν˜ΈμΆœλ©λ‹ˆλ‹€. λ„ˆλ¬΄ κΈ΄ μž‘μ—…μ„ μˆ˜ν–‰ν•˜λ©΄ μ•ˆλ©λ‹ˆλ‹€. κ·Έλ ‡κ²Œ ν•œλ‹€λ©΄ μŠ€νƒ€νŠΈμ—…μ΄ μ§€μ—°λ©λ‹ˆλ‹€.

 

μ½˜ν…μΈ  ν”„λ‘œλ°”μ΄λ”κ°€ (query(Uri, String[], Bundle, CancellationSignal), insert(Uri, ContentValues)등을 톡해) μ‚¬μš©λ˜κΈ° μ „κΉŒμ§€ (λ°μ΄ν„°λ² μ΄μŠ€λ₯Ό μ—΄κ±°λ‚˜, μ—…κ·Έλ ˆμ΄λ“œ ν•˜κ±°λ‚˜, μŠ€μΊ”ν•˜λŠ” κ²ƒμ²˜λŸΌ ) μ€‘μš”ν•˜μ§€ μ•Šμ€ μ΄ˆκΈ°ν™”λŠ” μ—°κΈ°ν•΄μ•Ό ν•©λ‹ˆλ‹€. μ§€μ—°λœ μ΄ˆκΈ°ν™”λŠ” μ• ν”Œλ¦¬μΌ€μ΄μ…˜μ˜ μŠ€νƒ€νŠΈμ—…μ„ λΉ λ₯΄κ²Œ μœ μ§€ν•˜κ³ , ν”„λ‘œλ°”μ΄λ”κ°€ λΆˆν•„μš”ν•˜λ‹€λ©΄ λΆˆν•„μš”ν•œ μž‘μ—…μ„ ν”Όν•˜κ³ , (full disk와 같은) λ°μ΄ν„°λ² μ΄μŠ€ μ—λŸ¬κ°€ μ•± 싀행을 μ€‘μ§€μ‹œν‚€λŠ” 것을 λ§‰μŠ΅λ‹ˆλ‹€ . 

 

SQLiteλ₯Ό μ‚¬μš©ν•œλ‹€λ©΄, SQLiteOpenHelperλŠ” λ°μ΄ν„°λ² μ΄μŠ€λ₯Ό μ‰½κ²Œ κ΄€λ¦¬ν•˜λ„λ‘ ν•˜κ³  처음 μ‚¬μš©ν•  λ•ŒκΉŒμ§€ μžλ™μœΌλ‘œ 싀행을 μ§€μ—°μ‹œν‚€λŠ”λ° 도움이 λ˜λŠ” μœ ν‹Έλ¦¬ν‹° ν΄λž˜μŠ€μž…λ‹ˆλ‹€. λ§Œμ•½ SQLiteOpenHelperλ₯Ό μ‚¬μš©ν•œλ‹€λ©΄, 이 λ©”μ„œλ“œμ—μ„œ SQLiteOpenHelper.getReadableDatabase() λ˜λŠ” SQLiteOpenHelper.getWritableDatabase()λ₯Ό ν˜ΈμΆœν•˜λŠ” 건 ν”Όν•΄μ•Όλ§Œ ν•©λ‹ˆλ‹€. (λŒ€μ‹ μ—, 처음 μ˜€ν”ˆλ  λ•Œ λ°μ΄ν„°λ² μ΄μŠ€λ₯Ό μ΄ˆκΈ°ν™”ν•˜λ €λ©΄ SQLiteOpenHelper.onOpen(SQLiteDatabase)λ₯Ό μ˜€λ²„λΌμ΄λ“œν•˜μ„Έμš”.)

 

query

1

public Cursor query (Uri uri, String[] projection, Bundel queryArgs, 
                                          CancellationSignal cacellationSignal)

Bundle μ•ˆμ— λ“€μ–΄κ°€λŠ” μΈμˆ˜λ“€μ˜ 쿼리 μš”μ²­μ„ μ²˜λ¦¬ν•˜λ €λ©΄ 이것을 κ΅¬ν˜„ν•˜μ„Έμš”. μΈμˆ˜λ“€μ€ 전톡적인 SQL μŠ€νƒ€μΌμ˜ 쿼리 μΈμˆ˜λ“€μœΌ 포함할 κ²λ‹ˆλ‹€. μ‘΄μž¬ν•  λ•Œμ— query(android.net.Uri, java.lang.String[], java.lang.String, java.lang.String[], java.lang.String, android.os.CancellationSignal)에 μ„±λ¦½λœ μ œμ•½μ— 따라 μ²˜λ¦¬λ˜μ–΄μ•Ό ν•©λ‹ˆλ‹€. 

 

전톡적인 SQL μΈμˆ˜λ“€μ€ λ²ˆλ“€ μ•ˆμ—μ„œ λ‹€μŒμ˜ ν‚€λ‘œ ν‘œν˜„λ  수 μžˆμŠ΅λ‹ˆλ‹€.

  • ContentResolver.QUERY_ARG_SQL_SELECTION
  • ContentResolver.QUERY_ARG_SQL_SELECTION_ARGS
  • ContentResolver.QUERY_ARG_SQL_SORT_ORDER

Processes and Threadsμ—μ„œ 기술된 바와 같이, 이 λ©”μ„œλ“œλŠ” μ—¬λŸ¬ μ“°λ ˆλ“œμ—μ„œ 호좜 κ°€λŠ₯ν•©λ‹ˆλ‹€.

 

ν΄λΌμ΄μ–ΈνŠΈ 호좜 예: 

//  μΈλ±μŠ€κ°€ 30인 ν–‰μ—μ„œ μ‹œμž‘ν•΄ 20개의 λ ˆμ½”λ“œλ₯Ό μš”μ²­ν•©λ‹ˆλ‹€.
Bundle queryArgs = new Bundle();
queryArgs.putInt(ContentResolver.QUERY_ARG_OFFSET, 30);
queryArgs.putInt(ContentResolver.QUERY_ARG_LIMIT, 20);

Cursor cursor = getContentReslver().query(
        contentUri,    // Content UriλŠ” κ°œλ³„ μ½˜ν…μΈ  ν”„λ‘œλ°”μ΄λ”μ— 따라 λ‹€λ¦…λ‹ˆλ‹€.
        projection,    // String[] 은 λ°˜ν™˜ν•  열이 μ–΄λ–€ 것인지 κΈ°μˆ ν•©λ‹ˆλ‹€.
        queryArgs,     // 쿼리 μΈμžλ“€
        null);         // μ·¨μ†Œ(cancellation) signal.

κ΅¬ν˜„ μ˜ˆμ‹œ :

int recordsetSize = 0x1000;  //  μ‹€μ œ 값은 κ΅¬ν˜„μ— 따라 λ‹€λ¦…λ‹ˆλ‹€.
queryArgs = queryArgs != null ? queryArgs : Bundle.EMPTY;  // queryArgsκ°€ non-nullμž„μ„
                                                           // ν™•μ‹€νžˆ ν•©λ‹ˆλ‹€.
                                                           
int offset = queryArgs.getInt(ContentResolver.QUERY_ARG_OFFSET, 0);
int limit = queryArgs.getInt(ContentResolve.QUERY_ARG_LIMIT, Integer.MIN_VALUE);

MatrixCursor c = new MatrixCursor(PROJECTION, limit);

// μ»€μ„œ μ•ˆμ— λ“€μ–΄κ°€λŠ” μ•„μ΄ν…œμ˜ 숫자λ₯Ό κ³„μ‚°ν•©λ‹ˆλ‹€.
int numItems = MathUtils.constrain(recordsetSize - offset, 0, limit);

// νŽ˜μ΄μ§€ 수λ₯Ό 맀긴 κ²°κ³Ό 집합을 λΉŒλ“œν•©λ‹ˆλ‹€.
for (int i = offset; i < offset + numItems; i++) {
    // λ°μ΄ν„°λ‘œλΆ€ν„° 행을 μ±„μ›λ‹ˆλ‹€.
}

Bundle extras = new Bundle();
c.setExtras(extras);

// μ§€μ •λœλ‹€λ©΄(if honored. μ€‘μš”ν•˜λ‹€κ³  μΈμ •λ°›λŠ”λ‹€λ©΄) μ–΄λ– ν•œ QUERY_ARG_* ν‚€λ“  포함될 수 μžˆμŠ΅λ‹ˆλ‹€.
// μ‹€μ œ κ΅¬ν˜„μ—μ„œ, queryArgs μ•ˆμ— ν‘œν˜„λ˜κ³  Cursor 좜λ ₯에도 ν‘œν˜„λ˜λŠ” 두 가지λ₯Ό λ§Œμ‘±ν•˜λŠ” ν‚€λ“€λ§Œ
// ν¬ν•¨μ‹œν‚€μ„Έμš”. λ§Œμ•½ QUERY_ARG_OFFSET이 queryArgs μ•ˆμ— ν¬ν•¨λ˜μ—ˆμ–΄λ„ (-273κ³Ό 같은) μœ νš¨ν•˜μ§€
// μ•Šμ€ 값을 ν¬ν•¨ν•˜κ³  있기 λ•Œλ¬Έμ— λ¬΄μ‹œλ  것이고, QUERY_ARG_OFFSET은 μƒλž΅λ˜μ–΄μ•Όλ§Œ ν•©λ‹ˆλ‹€.
extras.putStringArray(ContentResolver.EXTRA_HONORED_ARGS, new String[]{
    ContentResolver.QUERY_ARG_OFFSET,
    ContentResolver.QUERY_ARG_LIMIT
});

extras.putInt(ContentResolover.EXTRA_TOTAL_COUNT, recordsetSize);

cursor.setNotificationUri(getContext().getContentResolver(), uri);

return cursor;

μžμ„Έν•œ κ΅¬ν˜„μ€ query(android.net.Uri, java.lang.String[], java.lang.String, java.lang.String[], java.lang.String, android.os.CancellationSignal)을 λ³΄μ„Έμš”.

 

2

public Cursor query(Uri uri, String[] projection, String, selection, Strign[] selectionArgs, 
                                       Strign sortOrder, CancellationSignal cancellationSignal)

μ·¨μ†Œλ₯Ό μ§€μ›ν•˜λŠ” ν΄λΌμ΄μ–ΈνŠΈμ˜ 쿼리 μš”μ²­μ„ μ²˜λ¦¬ν•˜λ €λ©΄ 이것을 κ΅¬ν˜„ν•˜μ„Έμš”.

 

Build.VERSION_CODES_O 이상을 νƒ€κ²ŒνŒ…ν•˜λŠ” 앱듀은 이 λ©”μ„œλ“œ λŒ€μ‹ μ— query(android.net.Uri, java.lang.String[], android.os.Bundle, android.os.CancellationSignal)을 μ˜€λ²„λΌμ΄λ“œν•˜μ„Έμš”.

 

Processes and Threadsμ—μ„œ 기술된 바와 같이, 이 λ©”μ„œλ“œλŠ” μ—¬λŸ¬ μ“°λ ˆλ“œμ—μ„œ 호좜 κ°€λŠ₯ν•©λ‹ˆλ‹€.

 

ν΄λΌμ΄μ–ΈνŠΈ 호좜 예:

// νŠΉμ • λ ˆμ½”λ“œλ₯Ό μš”μ²­ν•©λ‹ˆλ‹€.
Cursor managedCursor = managedQuery(
        ContentUris.withAppendedId(Contract.People.CONTENT_URI, 2),
        projection,  // λ°˜ν™˜ν•˜λŠ” 열이 μ–΄λ–€ 열인지
        null,        // WHERE 절(clause. 문ꡬ)
        null,        // WHERE 절 κ°’μ˜ λŒ€μ²΄
        People.NAME + " ASC");  // μ •λ ¬ μˆœμ„œ

κ΅¬ν˜„ 예:

// SQLiteAueryBuilderλŠ” μ μ ˆν•œ SQL ꡬ문을 μƒμ„±ν•˜λŠ” 것을 λ„μ™€μ£ΌλŠ” 클래슀 μž…λ‹ˆλ‹€.
SQLIteQueryBuilder qBuilder = new SQLiteQueryBuilder();

// μš°λ¦¬κ°€ 쿼리λ₯Ό 진행할 ν…Œμ΄λΈ”μ„ μ„€μ •ν•©λ‹ˆλ‹€.
qBuilder.setTables(DATABASE_TABEL_NAME);

// λ§Œμ•½ νŠΉμ • λ ˆμ½”λ“œ μˆ«μžμ—μ„œ 쿼리가 λλ‚œλ‹€λ©΄, μš°λ¦¬λŠ” νŠΉμ • λ ˆμ½”λ“œμ— λŒ€ν•œ μš”μ²­μ„ 받을 것이고, 
// 쿼리 μ•ˆμ— WHERE μ ˆμ„ μ„€μ •ν•©λ‹ˆλ‹€.
if((URI_MATCHER.match(uri)) == SPECIFIC_MESSAGE) {
    qBuilder.appendWhere("_id=" + uri.getPathLeafId());
}

// 쿼리λ₯Ό λ§Œλ“€μ–΄ μ€λ‹ˆλ‹€.
Cursor c = qBuilde.query(mDb,
        projection,
        selection,
        selectionArgs,
        groupBy,
        having,
        sortOrder);
c.setNotificationUri(getCotext().getContentResolver(), uri);
return c;

λ§Œμ•½ 이 λ©”μ„œλ“œλ₯Ό κ΅¬ν˜„ν•œλ‹€λ©΄, μ·¨μ†Œ μ‹ ν˜Έ μ˜€λ²„λ‘œλ“œκ°€ λΆˆκ°€λŠ₯ν•œ μ˜› λ²„μ „μ˜ μ•ˆλ“œλ‘œμ΄λ“œ ν”„λ ˆμž„μ›Œν¬μ—μ„œ μ •ν™•ν•œ μž‘μ—… μˆ˜ν–‰μ„ ν™•μ‹€ν•˜κ²Œ ν•˜κΈ° μœ„ν•΄μ„œ μ·¨μ†Œ μ‹ ν˜Έλ₯Ό 받지 μ•ŠλŠ” query(android.net.Uri, java.lang.String[], java.lang.String, java.lang.String[], java.lang.String)의 버전도 λ°˜λ“œμ‹œ κ΅¬ν˜„ν•΄μ•Όν•©λ‹ˆλ‹€.

 

3

public abstract Cursor query(Uri uri,Sring[] projection, String selection, 
                                                String[] selectionArgs, String sortOrder)

ν΄λΌμ΄μ–ΈνŠΈμ—μ„œ 쿼리 μš”μ²­μ„ μ²˜λ¦¬ν•˜κΈ° μœ„ν•΄μ„œ 이것을 κ΅¬ν˜„ν•˜μ„Έμš”.

Build.VERSION_CODES.O 이상을 νƒ€κ²ŒνŒ…ν•˜λŠ” 앱듀은 query(android.net.Uri, java.lang.String[], android.os.Bundle, android.os.CancellationSignal)을 μ˜€λ²„λΌμ΄λ“œ ν•΄μ•Όν•˜κ³ , 이 λ©”μ„œλ“œμ˜ κ΅¬ν˜„μ˜ 일뢀뢄을 μ œκ³΅ν•΄μ•Ό ν•©λ‹ˆλ‹€.

 

Processes and Threadsμ—μ„œ 기술된 바와 같이, 이 λ©”μ„œλ“œλŠ” μ—¬λŸ¬ μ“°λ ˆλ“œμ—μ„œ 호좜 κ°€λŠ₯ν•©λ‹ˆλ‹€.

 

ν΄λΌμ΄μ–ΈνŠΈ 호좜 예:

// νŠΉμ • λ ˆμ½”λ“œλ₯Ό μš”μ²­ν•©λ‹ˆλ‹€.
Cursor managedCursor = managedQuery(
        ContentUris.withAppendedId(Contacts.People.CONTENT_URI, 2),
        projection,  // λ°˜ν™˜λ  행이 μ–΄λ–€ 것인지
        null,        // WHERE 절
        null,        // WHERE 절 κ°’ λŒ€μ²΄
        People.NAME + " ASC");  // μ •λ ¬ μˆœμ„œ

κ΅¬ν˜„ 예:

// SQLiteAueryBuilderλŠ” μ μ ˆν•œ SQL ꡬ문을 μƒμ„±ν•˜λŠ” 것을 λ„μ™€μ£ΌλŠ” 클래슀 μž…λ‹ˆλ‹€.
SQLIteQueryBuilder qBuilder = new SQLiteQueryBuilder();

// μš°λ¦¬κ°€ 쿼리λ₯Ό 진행할 ν…Œμ΄λΈ”μ„ μ„€μ •ν•©λ‹ˆλ‹€.
qBuilder.setTables(DATABASE_TABEL_NAME);

// λ§Œμ•½ νŠΉμ • λ ˆμ½”λ“œ μˆ«μžμ—μ„œ 쿼리가 λλ‚œλ‹€λ©΄, μš°λ¦¬λŠ” νŠΉμ • λ ˆμ½”λ“œμ— λŒ€ν•œ μš”μ²­μ„ 받을 것이고, 
// 쿼리 μ•ˆμ— WHERE μ ˆμ„ μ„€μ •ν•©λ‹ˆλ‹€.
if((URI_MATCHER.match(uri)) == SPECIFIC_MESSAGE) {
    qBuilder.appendWhere("_id=" + uri.getPathLeafId());
}

// 쿼리λ₯Ό λ§Œλ“€μ–΄ μ€λ‹ˆλ‹€.
Cursor c = qBuilde.query(mDb,
        projection,
        selection,
        selectionArgs,
        groupBy,
        having,
        sortOrder);
c.setNotificationUri(getCotext().getContentResolver(), uri);
return c;

 

insert

public Uri insert (Uri uri, ContentValues values, Bundle extras)
public abstract Uri insert(Uri uri,ConentValues values)

μƒˆλ‘œμš΄ ν–‰ ν•˜λ‚˜λ₯Ό μ‚½μž…ν•˜λŠ” μš”μ²­μ„ μ²˜λ¦¬ν•˜λ €λ©΄ 이것을 κ΅¬ν˜„ν•˜μ„Έμš”. μ˜λ‘€μ μœΌλ‘œ, μ‚½μž… ν›„μ—λŠ” notifyChanged()λ₯Ό ν˜ΈμΆœν•˜μ„Έμš”. Processes and Threadsμ—μ„œ 기술된 바와 같이, 이 λ©”μ„œλ“œλŠ” μ—¬λŸ¬ μ“°λ ˆλ“œμ—μ„œ 호좜 κ°€λŠ₯ν•©λ‹ˆλ‹€.

 

update

public int update (Uri uri, ContentValues values, Bundel extras)
public int update (Uri uri, ContentValues values, String selection, String[] selectionArgs)

ν•˜λ‚˜ μ΄μƒμ˜ ν–‰λ“€(rows)을 μ—…λ°μ΄νŠΈ ν•˜λŠ” μš”μ²­λ“€μ„ μ²˜λ¦¬ν•˜λ €λ©΄ 이것을 κ΅¬ν˜„ν•˜μ„Έμš”. 이 κ΅¬ν˜„μ€ 제곡된 κ°’μ„μ˜ map에 따라  μ—΄λ“€(columns)을 μ„€μ •ν•˜κΈ° μœ„ν•΄ 선택(selection)κ³Ό μΌμΉ˜ν•˜λŠ” λͺ¨λ“  행듀을 μ—…λ°μ΄νŠΈν•΄μ•Ό ν•©λ‹ˆλ‹€. μ˜λ‘€μ μœΌλ‘œ, μ—…λ°μ΄νŠΈ ν›„μ—λŠ” notifyChange()λ₯Ό ν˜ΈμΆœν•˜μ„Έμš”. Processes and Threadsμ—μ„œ 기술된 바와 같이, 이 λ©”μ„œλ“œλŠ” μ—¬λŸ¬ μ“°λ ˆλ“œμ—μ„œ 호좜 κ°€λŠ₯ν•©λ‹ˆλ‹€.

 

delete

public abstract int delete (Uri uri, String selection, String[] selectionArgs)
public int delete (Uri uri, Bundel extra)

ν•˜λ‚˜ μ΄μƒμ˜ ν–‰λ“€(rows)을 μ‚­μ œν•˜λŠ” μš”μ²­λ“€μ„ μ²˜λ¦¬ν•˜λ €λ©΄ 이것을 κ΅¬ν˜„ν•˜μ„Έμš”. 이 κ΅¬ν˜„μ€ μ‚­μ œ μž‘μ—…μ„ ν•  λ•Œμ—  선택 μ‘°ν•­(selection clause)을 μ μš©ν•΄ κ·Έ μž‘μ—…μ΄ ν•œ 디렉터리 μ•ˆμ—μ„œ μ—¬λŸ¬ 행듀이 영ν–₯을 주도둝 ν•΄μ•Ό ν•©λ‹ˆλ‹€. μ˜λ‘€μ μœΌλ‘œ, μ‚­μ œ ν›„μ—λŠ” notifyChanged()λ₯Ό ν˜ΈμΆœν•˜μ„Έμš”. Processes and Threadsμ—μ„œ 기술된 바와 같이, 이 λ©”μ„œλ“œλŠ” μ—¬λŸ¬ μ“°λ ˆλ“œμ—μ„œ 호좜 κ°€λŠ₯ν•©λ‹ˆλ‹€.

 

이 κ΅¬ν˜„μ€ νŠΉμ„± 행이 μ‚­μ œλ˜λŠ” κ²½μš°μ— URI 끝의 ν–‰ IDλ₯Ό νŒŒμ‹±ν•  μ±…μž…μ΄ μžˆμŠ΅λ‹ˆλ‹€. 즉, ν΄λΌμ΄μ–ΈνŠΈκ°€ contnet://contacts/people.22λ₯Ό 보내고 κ΅¬ν˜„μ€ SQL ꡬ문을 생성할 λ•Œμ— λ ˆμ½”λ“œ 숫자(22)λ₯Ό νŒŒμ‹±ν•  μ±…μž…μ΄ 있죠.

 

getType

public abstract String getType (Uri uri)

주어진 URIμ—μ„œ λ°μ΄ν„°μ˜ MIME νƒ€μž…μ— λŒ€ν•œ μš”μ²­μ„ μ²˜λ¦¬ν•˜λ €λ©΄ 이것을 κ΅¬ν˜„ν•˜μ„Έμš”. λ°˜ν™˜λœ MIME νƒ€μž…μ€ 단일 λ ˆμ½”λ“œμ˜ 경우 vnd.android.cursor.item으둜 μ‹œμž‘ν•˜κ±°λ‚˜, μ—¬λŸ¬ ν•­λͺ©λ“€μΈ κ²½μš°μ— vnd.android.cursor.dir/둜 μ‹œμž‘ν•΄μ•Όν•©λ‹ˆλ‹€. 이 λ©”μ†Œλ“œλŠ” Processes and Threads μ—μ„œ 기술된 λŒ€λ‘œ, μ—¬λŸ¬ μ“°λ ˆλ“œμ—μ„œ ν˜ΈμΆœν•  수 μžˆμŠ΅λ‹ˆλ‹€.

 

μ• ν”Œλ¦¬μΌ€μ΄μ…˜μ΄ 이 정보(MIME νƒ€μž…)에 μ ‘κ·Όν•˜λŠ”λ° ν•„μš”ν•œ κΆŒν•œμ€ μ—†μŠ΅λ‹ˆλ‹€. λ§Œμ•½ μ½˜ν…μΈ  ν”„λ‘œλ°”μ΄λ”κ°€ 읽기 그리고/λ˜λŠ” μ“°κΈ° κΆŒν•œλ“€μ΄ ν•„μš”ν•˜κ±°λ‚˜, μ½˜ν…μΈ  ν”„λ‘œλ°”μ΄λ”κ°€ exported λ˜μ§€ μ•ŠλŠ”λ‹€λ©΄, λͺ¨λ“  μ• ν”Œλ¦¬μΌ€μ΄μ…˜λ“€μ€ μ ‘κ·Ό κΆŒν•œκ³Ό 상관없이 이 λ©”μ†Œλ“œλ₯Ό 계속 ν˜ΈμΆœν•  수 μžˆμŠ΅λ‹ˆλ‹€. μ΄λ ‡κ²Œ μΈν…νŠΈλ“€μ΄ λ°œμ†‘λ  λ•Œ URI의 MIME νƒ€μž…μ„ 검색할 수 μžˆμŠ΅λ‹ˆλ‹€.