Что такое Cursor и как с ним работать?

Cursor – это интерфейс для чтения и записи значений результата запроса в базу данных.

Метод ContentResolver.query() возвращает объект типа Cursor, который содержит столбцы, заданные параметром projection, и строки, соответствующие критерию параметра selection.

val projection = arrayOf("first_name", "last_name")
val selection = "first_name = ?"
val selectionArgs = arrayOf(searchEditText.getText().toString())
val cursor = contentResolver.query("content://my_contacts/contacts", projection, selection, selectionArgs, null)


Курсор из примера выше имеет два столбца, т.е. cursor.getColumnCount() == 2.
Чтобы получить имена столбцов используется метод cursor.getColumnNames(). В примере выше результат – ["first_name", "last_name"].

Если по критерию selection нет данных, то метод query() возвращает пустой курсор, т.е. cursor.getCount() == 0.

Для получения значений строки нужно переместить курсор на желаемую строку результата. Для этого используются методы moveToFirst(), moveToLast(), moveToNext(), moveToPrevious(), moveToPosition(position: Int), move(offset: Int).

Каждый из этих методов перемещает курсор на заданную строку, после чего можно прочитать значения этой строки по столбцам. Для этого используются методы-геттеры с индексом столбца в качестве аргумента, например getString(columnIndex: Int).

Прочитаем полное имя первого контакта в курсоре из примера выше:

cursor.moveToFirst()
val firstNameColumnIndex = cursor.getColumnIndex("first_name")
val lastNameColumnIndex = cursor.getColumnIndex("last_name")
val firstName = cursor.getString(firstNameColumnIndex)
val lastName = cursor.getString(lastNameColumnIndex)
val fullName = "$firstName $lastName"