В прошлой теме был определен провайдер контента. Рассмотрим, как его использовать. Сначала определим простейший визуальный интерфейс для тестирования возможностей провайдера в файле activity_main.xml:
<?xml version="1.0" encoding="utf-8"?> <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="match_parent" > <Button android:id="@+id/getButton" android:layout_width="0dp" android:layout_height="wrap_content" android:text="Get" android:onClick="getAll" app:layout_constraintBottom_toTopOf="@id/addButton" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent" app:layout_constraintTop_toTopOf="parent" /> <Button android:id="@+id/addButton" android:layout_width="0dp" android:layout_height="wrap_content" android:text="Add" android:onClick="add" app:layout_constraintBottom_toTopOf="@id/updateButton" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent" app:layout_constraintTop_toBottomOf="@id/getButton" /> <Button android:id="@+id/updateButton" android:layout_width="0dp" android:layout_height="wrap_content" android:text="Update" android:onClick="update" app:layout_constraintBottom_toTopOf="@id/deleteButton" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent" app:layout_constraintTop_toBottomOf="@id/addButton" /> <Button android:id="@+id/deleteButton" android:layout_width="0dp" android:layout_height="wrap_content" android:text="Delete" android:onClick="delete" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent" app:layout_constraintTop_toBottomOf="@id/updateButton" /> </androidx.constraintlayout.widget.ConstraintLayout>
Здесь определен набор кнопок для вывода списка друзей, а также добавления, обновления и удаления. Каждая кнопка будет вызывать соответсствующий метод в классе MainActivity.
Теперь изменим код класса MainActivity. Для упрощения результаты будем выводить в окне Logcat с помощью метода Log.d():
package com.example.friendsproviderapp; import androidx.appcompat.app.AppCompatActivity; import android.content.ContentResolver; import android.content.ContentValues; import android.database.Cursor; import android.net.Uri; import android.os.Bundle; import android.util.Log; import android.view.View; public class MainActivity extends AppCompatActivity { private static final String TAG = "MainActivity"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); } // получение всех public void getAll(View view){ String[] projection = { FriendsContract.Columns._ID, FriendsContract.Columns.NAME, FriendsContract.Columns.EMAIL, FriendsContract.Columns.PHONE }; ContentResolver contentResolver = getContentResolver(); Cursor cursor = contentResolver.query(FriendsContract.CONTENT_URI, projection, null, null, FriendsContract.Columns.NAME); if(cursor != null){ Log.d(TAG, "count: " + cursor.getCount()); // перебор элементов while(cursor.moveToNext()){ for(int i=0; i < cursor.getColumnCount(); i++){ Log.d(TAG, cursor.getColumnName(i) + " : " + cursor.getString(i)); } Log.d(TAG, "========================="); } cursor.close(); } else{ Log.d(TAG, "Cursor is null"); } } // Добавление public void add(View view){ ContentResolver contentResolver = getContentResolver(); ContentValues values = new ContentValues(); values.put(FriendsContract.Columns.NAME, "Sam"); values.put(FriendsContract.Columns.EMAIL, "sam@gmail.com"); values.put(FriendsContract.Columns.PHONE, "+13676254985"); Uri uri = contentResolver.insert(FriendsContract.CONTENT_URI, values); Log.d(TAG, "Friend added"); } // Обновление public void update(View view){ ContentResolver contentResolver = getContentResolver(); ContentValues values = new ContentValues(); values.put(FriendsContract.Columns.EMAIL, "sammy@gmail.com"); values.put(FriendsContract.Columns.PHONE, "+55555555555"); String selection = FriendsContract.Columns.NAME + " = 'Sam'"; int count = contentResolver.update(FriendsContract.CONTENT_URI, values, selection, null); Log.d(TAG, "Friend updated"); } // Удаление public void delete(View view){ ContentResolver contentResolver = getContentResolver(); String selection = FriendsContract.Columns.NAME + " = ?"; String[] args = {"Sam"}; int count = contentResolver.delete(FriendsContract.CONTENT_URI, selection, args); Log.d(TAG, "Friend deleted"); } }
Разберем отдельные действия, выполняемые в данном коде.
public void getAll(View view){ String[] projection = { FriendsContract.Columns._ID, FriendsContract.Columns.NAME, FriendsContract.Columns.EMAIL, FriendsContract.Columns.PHONE }; ContentResolver contentResolver = getContentResolver(); Cursor cursor = contentResolver.query(FriendsContract.CONTENT_URI, projection, null, null, FriendsContract.Columns.NAME); if(cursor != null){ Log.d(TAG, "count: " + cursor.getCount()); // перебор элементов while(cursor.moveToNext()){ for(int i=0; i < cursor.getColumnCount(); i++){ Log.d(TAG, cursor.getColumnName(i) + " : " + cursor.getString(i)); } Log.d(TAG, "========================="); } cursor.close(); } else{ Log.d(TAG, "Cursor is null"); } }
Взаимодействие с провайдером контента осуществляется через объект ContentResolver. Для получения данных вызывается метод query(), по сути он представляет вызов метод query провайдера контента. В метод query передается uri - путь к данным, projection - набор столбцов для извлечения, выражение выборки и параметры для него и название столбца, по которому проводится сортировка.
Метод возвращает курсор Cursor, который с помощью метода moveToNext()
можно перебрать и получить отдельные данные. Метод getColumnName()
возвращает название столбца, а getString()
- собственно значение этого столбца:
Получение одного объекта по id:
String[] projection = { FriendsContract.Columns._ID, FriendsContract.Columns.NAME, FriendsContract.Columns.EMAIL, FriendsContract.Columns.PHONE }; ContentResolver contentResolver = getContentResolver(); Cursor cursor = contentResolver.query(FriendsContract.buildFriendUri(2), projection, null, null, FriendsContract.Columns.NAME); if(cursor != null){ while(cursor.moveToNext()){ for(int i=0; i < cursor.getColumnCount(); i++){ Log.d(TAG, cursor.getColumnName(i) + " : " + cursor.getString(i)); } } cursor.close(); }
В данном случае получаем объект с _id=2.
Добавление данных:
ContentResolver contentResolver = getContentResolver(); ContentValues values = new ContentValues(); values.put(FriendsContract.Columns.NAME, "Sam"); values.put(FriendsContract.Columns.EMAIL, "sam@gmail.com"); values.put(FriendsContract.Columns.PHONE, "+13676254985"); Uri uri = contentResolver.insert(FriendsContract.CONTENT_URI, values);
Для добавления применяется метод insert
, который принимает путь URI и добавляемые данные в виде ContentValues.
Обновление данных:
ContentResolver contentResolver = getContentResolver(); ContentValues values = new ContentValues(); values.put(FriendsContract.Columns.EMAIL, "sammy@gmail.com"); values.put(FriendsContract.Columns.PHONE, "+55555555555"); String selection = FriendsContract.Columns.NAME + " = 'Sam'"; int count = contentResolver.update(FriendsContract.CONTENT_URI, values, selection, null);
В данном случае обновляются данные у всех объектов, у которых "Name=Sam". Критерий обновления передается через третий параметр.
Естественно с помощью выражения SQL можно задать любою логику выборки объектов для обновления. И для большего удобства мы можем вводить в него данные с помощью параметров, которые задаются знаком вопроса:
ContentResolver contentResolver = getContentResolver(); ContentValues values = new ContentValues(); values.put(FriendsContract.Columns.NAME, "Sam"); String selection = FriendsContract.Columns.NAME + " = ?"; String args[] = {"Sam Scromby"}; int count = contentResolver.update(FriendsContract.CONTENT_URI, values, selection, args);
В этом случае с помощью четвертого параметра передается массив значений для параметров выражения выборки.
Но в примерах выше обновлялись все строки в бд, которые имели, например, имя "Sam". Но также можно обновлять и один объект по id. Например, обновим строку с _id=3:
ContentResolver contentResolver = getContentResolver(); ContentValues values = new ContentValues(); values.put(FriendsContract.Columns.NAME, "Sam"); values.put(FriendsContract.Columns.EMAIL, "sam@gmail.com"); int count = contentResolver.update(FriendsContract.buildFriendUri(3), values, null, null);
Удаление данных по общему условию:
ContentResolver contentResolver = getContentResolver(); String selection = FriendsContract.Columns.NAME + " = ?"; String[] args = {"Sam"}; int count = contentResolver.delete(FriendsContract.CONTENT_URI, selection, args);
В данном случае удаляются все строки, у которых Name=Sam.
Удаление по id:
ContentResolver contentResolver = getContentResolver(); int count = contentResolver.delete(FriendsContract.buildFriendUri(2), null, null);
В данном случае удаляется строка с _id=2.