1 /* 2 * Copyright (C) 2006 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package android.database; 18 19 import android.annotation.IntDef; 20 import android.annotation.IntRange; 21 import android.annotation.NonNull; 22 import android.annotation.Nullable; 23 import android.content.ContentResolver; 24 import android.net.Uri; 25 import android.os.Bundle; 26 27 import java.io.Closeable; 28 import java.lang.annotation.Retention; 29 import java.lang.annotation.RetentionPolicy; 30 import java.util.Arrays; 31 import java.util.List; 32 33 /** 34 * This interface provides random read-write access to the result set returned 35 * by a database query. 36 * <p> 37 * Cursor implementations are not required to be synchronized so code using a Cursor from multiple 38 * threads should perform its own synchronization when using the Cursor. 39 * </p><p> 40 * Implementations should subclass {@link AbstractCursor}. 41 * </p> 42 */ 43 public interface Cursor extends Closeable { 44 /* 45 * Values returned by {@link #getType(int)}. 46 * These should be consistent with the corresponding types defined in CursorWindow.h 47 */ 48 /** Value returned by {@link #getType(int)} if the specified column is null */ 49 static final int FIELD_TYPE_NULL = 0; 50 51 /** Value returned by {@link #getType(int)} if the specified column type is integer */ 52 static final int FIELD_TYPE_INTEGER = 1; 53 54 /** Value returned by {@link #getType(int)} if the specified column type is float */ 55 static final int FIELD_TYPE_FLOAT = 2; 56 57 /** Value returned by {@link #getType(int)} if the specified column type is string */ 58 static final int FIELD_TYPE_STRING = 3; 59 60 /** Value returned by {@link #getType(int)} if the specified column type is blob */ 61 static final int FIELD_TYPE_BLOB = 4; 62 63 /** @hide */ 64 @IntDef(prefix = { "FIELD_TYPE_" }, value = { 65 FIELD_TYPE_NULL, 66 FIELD_TYPE_INTEGER, 67 FIELD_TYPE_FLOAT, 68 FIELD_TYPE_STRING, 69 FIELD_TYPE_BLOB, 70 }) 71 @Retention(RetentionPolicy.SOURCE) 72 public @interface FieldType {} 73 74 /** 75 * Returns the numbers of rows in the cursor. 76 * 77 * @return the number of rows in the cursor. 78 */ getCount()79 @IntRange(from = 0) int getCount(); 80 81 /** 82 * Returns the current position of the cursor in the row set. 83 * The value is zero-based. When the row set is first returned the cursor 84 * will be at positon -1, which is before the first row. After the 85 * last row is returned another call to next() will leave the cursor past 86 * the last entry, at a position of count(). 87 * 88 * @return the current cursor position. 89 */ getPosition()90 @IntRange(from = -1) int getPosition(); 91 92 /** 93 * Move the cursor by a relative amount, forward or backward, from the 94 * current position. Positive offsets move forwards, negative offsets move 95 * backwards. If the final position is outside of the bounds of the result 96 * set then the resultant position will be pinned to -1 or count() depending 97 * on whether the value is off the front or end of the set, respectively. 98 * 99 * <p>This method will return true if the requested destination was 100 * reachable, otherwise, it returns false. For example, if the cursor is at 101 * currently on the second entry in the result set and move(-5) is called, 102 * the position will be pinned at -1, and false will be returned. 103 * 104 * @param offset the offset to be applied from the current position. 105 * @return whether the requested move fully succeeded. 106 */ move(int offset)107 boolean move(int offset); 108 109 /** 110 * Move the cursor to an absolute position. The valid 111 * range of values is -1 <= position <= count. 112 * 113 * <p>This method will return true if the request destination was reachable, 114 * otherwise, it returns false. 115 * 116 * @param position the zero-based position to move to. 117 * @return whether the requested move fully succeeded. 118 */ moveToPosition(@ntRangefrom = -1) int position)119 boolean moveToPosition(@IntRange(from = -1) int position); 120 121 /** 122 * Move the cursor to the first row. 123 * 124 * <p>This method will return false if the cursor is empty. 125 * 126 * @return whether the move succeeded. 127 */ moveToFirst()128 boolean moveToFirst(); 129 130 /** 131 * Move the cursor to the last row. 132 * 133 * <p>This method will return false if the cursor is empty. 134 * 135 * @return whether the move succeeded. 136 */ moveToLast()137 boolean moveToLast(); 138 139 /** 140 * Move the cursor to the next row. 141 * 142 * <p>This method will return false if the cursor is already past the 143 * last entry in the result set. 144 * 145 * @return whether the move succeeded. 146 */ moveToNext()147 boolean moveToNext(); 148 149 /** 150 * Move the cursor to the previous row. 151 * 152 * <p>This method will return false if the cursor is already before the 153 * first entry in the result set. 154 * 155 * @return whether the move succeeded. 156 */ moveToPrevious()157 boolean moveToPrevious(); 158 159 /** 160 * Returns whether the cursor is pointing to the first row. 161 * 162 * @return whether the cursor is pointing at the first entry. 163 */ isFirst()164 boolean isFirst(); 165 166 /** 167 * Returns whether the cursor is pointing to the last row. 168 * 169 * @return whether the cursor is pointing at the last entry. 170 */ isLast()171 boolean isLast(); 172 173 /** 174 * Returns whether the cursor is pointing to the position before the first 175 * row. 176 * 177 * @return whether the cursor is before the first result. 178 */ isBeforeFirst()179 boolean isBeforeFirst(); 180 181 /** 182 * Returns whether the cursor is pointing to the position after the last 183 * row. 184 * 185 * @return whether the cursor is after the last result. 186 */ isAfterLast()187 boolean isAfterLast(); 188 189 /** 190 * Returns the zero-based index for the given column name, or -1 if the column doesn't exist. 191 * If you expect the column to exist use {@link #getColumnIndexOrThrow(String)} instead, which 192 * will make the error more clear. 193 * 194 * @param columnName the name of the target column. 195 * @return the zero-based column index for the given column name, or -1 if 196 * the column name does not exist. 197 * @see #getColumnIndexOrThrow(String) 198 */ getColumnIndex(String columnName)199 @IntRange(from = -1) int getColumnIndex(String columnName); 200 201 /** 202 * Returns the zero-based index for the given column name, or throws 203 * {@link IllegalArgumentException} if the column doesn't exist. If you're not sure if 204 * a column will exist or not use {@link #getColumnIndex(String)} and check for -1, which 205 * is more efficient than catching the exceptions. 206 * 207 * @param columnName the name of the target column. 208 * @return the zero-based column index for the given column name 209 * @see #getColumnIndex(String) 210 * @throws IllegalArgumentException if the column does not exist 211 */ getColumnIndexOrThrow(String columnName)212 @IntRange(from = 0) int getColumnIndexOrThrow(String columnName) 213 throws IllegalArgumentException; 214 215 /** 216 * Returns the column name at the given zero-based column index. 217 * 218 * @param columnIndex the zero-based index of the target column. 219 * @return the column name for the given column index. 220 */ getColumnName(@ntRangefrom = 0) int columnIndex)221 String getColumnName(@IntRange(from = 0) int columnIndex); 222 223 /** 224 * Returns a string array holding the names of all of the columns in the 225 * result set in the order in which they were listed in the result. 226 * 227 * @return the names of the columns returned in this query. 228 */ getColumnNames()229 String[] getColumnNames(); 230 231 /** 232 * Return total number of columns 233 * @return number of columns 234 */ getColumnCount()235 @IntRange(from = 0) int getColumnCount(); 236 237 /** 238 * Returns the value of the requested column as a byte array. 239 * 240 * <p>The result and whether this method throws an exception when the 241 * column value is null or the column type is not a blob type is 242 * implementation-defined. 243 * 244 * @param columnIndex the zero-based index of the target column. 245 * @return the value of that column as a byte array. 246 */ getBlob(@ntRangefrom = 0) int columnIndex)247 byte[] getBlob(@IntRange(from = 0) int columnIndex); 248 249 /** 250 * Returns the value of the requested column as a String. 251 * 252 * <p>The result and whether this method throws an exception when the 253 * column value is null or the column type is not a string type is 254 * implementation-defined. 255 * 256 * @param columnIndex the zero-based index of the target column. 257 * @return the value of that column as a String. 258 */ getString(@ntRangefrom = 0) int columnIndex)259 String getString(@IntRange(from = 0) int columnIndex); 260 261 /** 262 * Retrieves the requested column text and stores it in the buffer provided. 263 * If the buffer size is not sufficient, a new char buffer will be allocated 264 * and assigned to CharArrayBuffer.data 265 * @param columnIndex the zero-based index of the target column. 266 * if the target column is null, return buffer 267 * @param buffer the buffer to copy the text into. 268 */ copyStringToBuffer(@ntRangefrom = 0) int columnIndex, CharArrayBuffer buffer)269 void copyStringToBuffer(@IntRange(from = 0) int columnIndex, CharArrayBuffer buffer); 270 271 /** 272 * Returns the value of the requested column as a short. 273 * 274 * <p>The result and whether this method throws an exception when the 275 * column value is null, the column type is not an integral type, or the 276 * integer value is outside the range [<code>Short.MIN_VALUE</code>, 277 * <code>Short.MAX_VALUE</code>] is implementation-defined. 278 * 279 * @param columnIndex the zero-based index of the target column. 280 * @return the value of that column as a short. 281 */ getShort(@ntRangefrom = 0) int columnIndex)282 short getShort(@IntRange(from = 0) int columnIndex); 283 284 /** 285 * Returns the value of the requested column as an int. 286 * 287 * <p>The result and whether this method throws an exception when the 288 * column value is null, the column type is not an integral type, or the 289 * integer value is outside the range [<code>Integer.MIN_VALUE</code>, 290 * <code>Integer.MAX_VALUE</code>] is implementation-defined. 291 * 292 * @param columnIndex the zero-based index of the target column. 293 * @return the value of that column as an int. 294 */ getInt(@ntRangefrom = 0) int columnIndex)295 int getInt(@IntRange(from = 0) int columnIndex); 296 297 /** 298 * Returns the value of the requested column as a long. 299 * 300 * <p>The result and whether this method throws an exception when the 301 * column value is null, the column type is not an integral type, or the 302 * integer value is outside the range [<code>Long.MIN_VALUE</code>, 303 * <code>Long.MAX_VALUE</code>] is implementation-defined. 304 * 305 * @param columnIndex the zero-based index of the target column. 306 * @return the value of that column as a long. 307 */ getLong(@ntRangefrom = 0) int columnIndex)308 long getLong(@IntRange(from = 0) int columnIndex); 309 310 /** 311 * Returns the value of the requested column as a float. 312 * 313 * <p>The result and whether this method throws an exception when the 314 * column value is null, the column type is not a floating-point type, or the 315 * floating-point value is not representable as a <code>float</code> value is 316 * implementation-defined. 317 * 318 * @param columnIndex the zero-based index of the target column. 319 * @return the value of that column as a float. 320 */ getFloat(@ntRangefrom = 0) int columnIndex)321 float getFloat(@IntRange(from = 0) int columnIndex); 322 323 /** 324 * Returns the value of the requested column as a double. 325 * 326 * <p>The result and whether this method throws an exception when the 327 * column value is null, the column type is not a floating-point type, or the 328 * floating-point value is not representable as a <code>double</code> value is 329 * implementation-defined. 330 * 331 * @param columnIndex the zero-based index of the target column. 332 * @return the value of that column as a double. 333 */ getDouble(@ntRangefrom = 0) int columnIndex)334 double getDouble(@IntRange(from = 0) int columnIndex); 335 336 /** 337 * Returns data type of the given column's value. 338 * The preferred type of the column is returned but the data may be converted to other types 339 * as documented in the get-type methods such as {@link #getInt(int)}, {@link #getFloat(int)} 340 * etc. 341 * 342 * @param columnIndex the zero-based index of the target column. 343 * @return column value type 344 */ getType(@ntRangefrom = 0) int columnIndex)345 @FieldType int getType(@IntRange(from = 0) int columnIndex); 346 347 /** 348 * Returns <code>true</code> if the value in the indicated column is null. 349 * 350 * @param columnIndex the zero-based index of the target column. 351 * @return whether the column value is null. 352 */ isNull(@ntRangefrom = 0) int columnIndex)353 boolean isNull(@IntRange(from = 0) int columnIndex); 354 355 /** 356 * Deactivates the Cursor, making all calls on it fail until {@link #requery} is called. 357 * Inactive Cursors use fewer resources than active Cursors. 358 * Calling {@link #requery} will make the cursor active again. 359 * @deprecated Since {@link #requery()} is deprecated, so too is this. 360 */ 361 @Deprecated deactivate()362 void deactivate(); 363 364 /** 365 * Performs the query that created the cursor again, refreshing its 366 * contents. This may be done at any time, including after a call to {@link 367 * #deactivate}. 368 * 369 * Since this method could execute a query on the database and potentially take 370 * a while, it could cause ANR if it is called on Main (UI) thread. 371 * A warning is printed if this method is being executed on Main thread. 372 * 373 * @return true if the requery succeeded, false if not, in which case the 374 * cursor becomes invalid. 375 * @deprecated Don't use this. Just request a new cursor, so you can do this 376 * asynchronously and update your list view once the new cursor comes back. 377 */ 378 @Deprecated requery()379 boolean requery(); 380 381 /** 382 * Closes the Cursor, releasing all of its resources and making it completely invalid. 383 * Unlike {@link #deactivate()} a call to {@link #requery()} will not make the Cursor valid 384 * again. 385 */ close()386 void close(); 387 388 /** 389 * return true if the cursor is closed 390 * @return true if the cursor is closed. 391 */ isClosed()392 boolean isClosed(); 393 394 /** 395 * Register an observer that is called when changes happen to the content backing this cursor. 396 * Typically the data set won't change until {@link #requery()} is called. 397 * 398 * @param observer the object that gets notified when the content backing the cursor changes. 399 * @see #unregisterContentObserver(ContentObserver) 400 */ registerContentObserver(ContentObserver observer)401 void registerContentObserver(ContentObserver observer); 402 403 /** 404 * Unregister an observer that has previously been registered with this 405 * cursor via {@link #registerContentObserver}. 406 * 407 * @param observer the object to unregister. 408 * @see #registerContentObserver(ContentObserver) 409 */ unregisterContentObserver(ContentObserver observer)410 void unregisterContentObserver(ContentObserver observer); 411 412 /** 413 * Register an observer that is called when changes happen to the contents 414 * of the this cursors data set, for example, when the data set is changed via 415 * {@link #requery()}, {@link #deactivate()}, or {@link #close()}. 416 * 417 * @param observer the object that gets notified when the cursors data set changes. 418 * @see #unregisterDataSetObserver(DataSetObserver) 419 */ registerDataSetObserver(DataSetObserver observer)420 void registerDataSetObserver(DataSetObserver observer); 421 422 /** 423 * Unregister an observer that has previously been registered with this 424 * cursor via {@link #registerContentObserver}. 425 * 426 * @param observer the object to unregister. 427 * @see #registerDataSetObserver(DataSetObserver) 428 */ unregisterDataSetObserver(DataSetObserver observer)429 void unregisterDataSetObserver(DataSetObserver observer); 430 431 /** 432 * Register to watch a content URI for changes. This can be the URI of a specific data row (for 433 * example, "content://my_provider_type/23"), or a a generic URI for a content type. 434 * 435 * <p>Calling this overrides any previous call to 436 * {@link #setNotificationUris(ContentResolver, List)}. 437 * 438 * @param cr The content resolver from the caller's context. The listener attached to 439 * this resolver will be notified. 440 * @param uri The content URI to watch. 441 */ setNotificationUri(ContentResolver cr, Uri uri)442 void setNotificationUri(ContentResolver cr, Uri uri); 443 444 /** 445 * Similar to {@link #setNotificationUri(ContentResolver, Uri)}, except this version allows 446 * to watch multiple content URIs for changes. 447 * 448 * <p>If this is not implemented, this is equivalent to calling 449 * {@link #setNotificationUri(ContentResolver, Uri)} with the first URI in {@code uris}. 450 * 451 * <p>Calling this overrides any previous call to 452 * {@link #setNotificationUri(ContentResolver, Uri)}. 453 * 454 * @param cr The content resolver from the caller's context. The listener attached to 455 * this resolver will be notified. 456 * @param uris The content URIs to watch. 457 */ setNotificationUris(@onNull ContentResolver cr, @NonNull List<Uri> uris)458 default void setNotificationUris(@NonNull ContentResolver cr, @NonNull List<Uri> uris) { 459 setNotificationUri(cr, uris.get(0)); 460 } 461 462 /** 463 * Return the URI at which notifications of changes in this Cursor's data 464 * will be delivered, as previously set by {@link #setNotificationUri}. 465 * @return Returns a URI that can be used with 466 * {@link ContentResolver#registerContentObserver(android.net.Uri, boolean, ContentObserver) 467 * ContentResolver.registerContentObserver} to find out about changes to this Cursor's 468 * data. May be null if no notification URI has been set. 469 */ getNotificationUri()470 Uri getNotificationUri(); 471 472 /** 473 * Return the URIs at which notifications of changes in this Cursor's data 474 * will be delivered, as previously set by {@link #setNotificationUris}. 475 * 476 * <p>If this is not implemented, this is equivalent to calling {@link #getNotificationUri()}. 477 * 478 * @return Returns URIs that can be used with 479 * {@link ContentResolver#registerContentObserver(android.net.Uri, boolean, ContentObserver) 480 * ContentResolver.registerContentObserver} to find out about changes to this Cursor's 481 * data. May be null if no notification URI has been set. 482 */ getNotificationUris()483 default @Nullable List<Uri> getNotificationUris() { 484 final Uri notifyUri = getNotificationUri(); 485 return notifyUri == null ? null : Arrays.asList(notifyUri); 486 } 487 488 /** 489 * onMove() will only be called across processes if this method returns true. 490 * @return whether all cursor movement should result in a call to onMove(). 491 */ getWantsAllOnMoveCalls()492 boolean getWantsAllOnMoveCalls(); 493 494 /** 495 * Sets a {@link Bundle} that will be returned by {@link #getExtras()}. 496 * 497 * @param extras {@link Bundle} to set, or null to set an empty bundle. 498 */ setExtras(Bundle extras)499 void setExtras(Bundle extras); 500 501 /** 502 * Returns a bundle of extra values. This is an optional way for cursors to provide out-of-band 503 * metadata to their users. One use of this is for reporting on the progress of network requests 504 * that are required to fetch data for the cursor. 505 * 506 * <p>These values may only change when requery is called. 507 * @return cursor-defined values, or {@link android.os.Bundle#EMPTY Bundle.EMPTY} if there 508 * are no values. Never <code>null</code>. 509 */ getExtras()510 Bundle getExtras(); 511 512 /** 513 * This is an out-of-band way for the the user of a cursor to communicate with the cursor. The 514 * structure of each bundle is entirely defined by the cursor. 515 * 516 * <p>One use of this is to tell a cursor that it should retry its network request after it 517 * reported an error. 518 * @param extras extra values, or {@link android.os.Bundle#EMPTY Bundle.EMPTY}. 519 * Never <code>null</code>. 520 * @return extra values, or {@link android.os.Bundle#EMPTY Bundle.EMPTY}. 521 * Never <code>null</code>. 522 */ respond(Bundle extras)523 Bundle respond(Bundle extras); 524 } 525