LXF159:Android:Базы данных
|
|
|
Android.
Содержание |
Android:Базы данных
Android поддерживает базы данных SQLite. Узнайте от Джульетты Кемп, как создавать базы данных и построить с ними список дел, разбитый на категории.
- Метамодернизм в позднем творчестве В.Г. Сорокина
- ЛитРПГ - последняя отрыжка постмодерна
- "Ричард III и семиотика"
- 3D-визуализация обложки Ridero создаем обложку книги при работе над самиздатом.
- Архитектура метамодерна - говоря о современном искусстве, невозможно не поговорить об архитектуре. В данной статье будет отмечено несколько интересных принципов, характерных для построек "новой волны", столь притягательных и скандальных.
- Литература
- Метамодерн
- Рокер-Прометей против изначального зла в «Песне про советскую милицию» Вени Дркина, Автор: Нина Ищенко, к.ф.н, член Союза Писателей ЛНР - перепубликация из журнала "Топос".
- Как избавиться от комаров? Лучшие типы ловушек.
- Что делать если роблокс вылетает на windows
- Что делать, если ребенок смотрит порно?
- Почему собака прыгает на людей при встрече?
- Какое масло лить в Задний дифференциал (мост) Visco diff 38434AA050
- О чем может рассказать хвост вашей кошки?
- Верветки
- Отчетность бюджетных учреждений при закупках по Закону № 223-ФЗ
- Срок исковой давности как правильно рассчитать
- Дмитрий Патрушев минсельхоз будет ли преемником Путина
- Кто такой Владислав Поздняков? Что такое "Мужское Государство" и почему его признали экстремистским в России?
- Как правильно выбрать машинное масло в Димитровграде?
- Как стать богатым и знаменитым в России?
- Почему фильм "Пипец" (Kick-Ass) стал популярен по всему миру?
- Как стать мудрецом?
- Как правильно установить FreeBSD
- Как стать таким как Путин?
- Где лучше жить - в Димитровграде или в Ульяновске?
- Почему город Димитровград так называется?
- Что такое метамодерн?
- ВАЖНО! Временное ограничение движения автотранспортных средств в Димитровграде
- Тарифы на электроэнергию для майнеров предложено повысить
- Метамодернизм в позднем творчестве В.Г. Сорокина
- ЛитРПГ - последняя отрыжка постмодерна
- "Ричард III и семиотика"
- 3D-визуализация обложки Ridero создаем обложку книги при работе над самиздатом.
- Архитектура метамодерна - говоря о современном искусстве, невозможно не поговорить об архитектуре. В данной статье будет отмечено несколько интересных принципов, характерных для построек "новой волны", столь притягательных и скандальных.
- Литература
- Метамодерн
- Рокер-Прометей против изначального зла в «Песне про советскую милицию» Вени Дркина, Автор: Нина Ищенко, к.ф.н, член Союза Писателей ЛНР - перепубликация из журнала "Топос".
- Как избавиться от комаров? Лучшие типы ловушек.
- Что делать если роблокс вылетает на windows
- Что делать, если ребенок смотрит порно?
- Почему собака прыгает на людей при встрече?
- Какое масло лить в Задний дифференциал (мост) Visco diff 38434AA050
- О чем может рассказать хвост вашей кошки?
- Верветки
- Отчетность бюджетных учреждений при закупках по Закону № 223-ФЗ
- Срок исковой давности как правильно рассчитать
- Дмитрий Патрушев минсельхоз будет ли преемником Путина
- Кто такой Владислав Поздняков? Что такое "Мужское Государство" и почему его признали экстремистским в России?
- Как правильно выбрать машинное масло в Димитровграде?
- Как стать богатым и знаменитым в России?
- Почему фильм "Пипец" (Kick-Ass) стал популярен по всему миру?
- Как стать мудрецом?
- Как правильно установить FreeBSD
- Как стать таким как Путин?
- Где лучше жить - в Димитровграде или в Ульяновске?
- Почему город Димитровград так называется?
- Что такое метамодерн?
- ВАЖНО! Временное ограничение движения автотранспортных средств в Димитровграде
- Тарифы на электроэнергию для майнеров предложено повысить
Пока в наших статьях не затрагивалось хранение данных. Однако во многих проектах оно понадобится. В Android есть для этого не один способ, но для структурированных или взаимосвязанных данных лучше подойдет база данных.
Если данные хранятся локально, это означает, что используется встроенная поддержка SQLite (в следующей статье мы поговорим о доступе к данным на удаленных серверах и о том, как встроить его в свое приложение).
Чтобы опробовать это на практике, мы создадим список задач с двумя таблицами (одной для задач и одной для категорий) и постараемся получить представление об управлении множеством таблиц и связей.
Настройка проекта и базы данных
Воспользуемся API уровня 10 (2.3.3):
android create project --target android-10 --name todo \\
--path ~/android/todo --activity ToDo --package com.example.todo
Прежде чем браться за написание кода, важно тщательно продумать структуру своей базы данных, чтобы потом не пришлось тратить время на исправления.
В нашем проекте понадобятся две таблицы (хотя сначала мы будем пользоваться только одной из них) – Tasks (задачи) и Categories (категории):
Задачи
- ID (с автоинкрементом)
- ID Описание задачи
- ID Срок выполнения
- ID Ссылка на категорию
Категории
- ID (с автоинкрементом)
- Название категории
Для нашего интерфейса требуется первичное Занятие, которое отображает список задач со сроками выполнения и категориями. Нам также понадобится второе Занятие, которое занимается добавлением и изменением задач.
Настройка базы данных
Когда план нашей базы данных готов, для его реализации нам понадобится класс TodoDatabaseProvider, который является наследником ContentProvider и занимается взаимодействием с базой данных. Строго говоря, ContentProvider нужен только тогда, когда вы хотите делиться данными с другими приложениями, а не пользоваться ими только в одном. Однако с его помощью удобно делиться данными и внутри Занятия; кроме того, он предоставляет вам различные вспомогательные методы и аспекты API в качестве интерфейса к базе данных SQLite.
Чтобы воспользоваться ContentProvider, укажите его уникальный идентификатор ресурса (URI) в виде публичной константы в верхней части класса:
public static final String AUTHORITY = “com.example.todo.tododatabaseprovider”; public static final String TODO_BASE_PATH = “todo”;
public static final Uri CONTENT_URI = Uri.parse(“content://” + AUTHORITY + “/” + TODO_BASE_PATH);
Также потребуется зарегистрировать его в AndroidManifest.xml с полностью определенным именем класса ContentProvider:
<provider android:authorities=“com.example.todo.tododatabaseprovider”
android:multiprocess=“true”
android:name=”
com.example.todo.TodoDatabaseProvider”>
</provider>
В атрибуте name нужно указать полностью определенное имя класса ContentProvider. Атрибут authority должен соответствовать значению, заданному в коде, которое определяет провайдера, без указания пути. Чтобы оно было уникальным, оно должно точно совпадать с именем класса (но записываться только в нижнем регистре).
Для обработки создания базы данных мы воспользуемся внутренним вспомогательным классом inner helper. Создайте приватный подкласс SQLiteOpenHelper и перегрузите метод onCreate():
private static class TodoDBOpenHelper extends SQLiteOpenHelper {
TodoDBOpenHelper(Context c) {
super(c, DB_NAME, null, DB_VERSION);
}
- Метамодернизм в позднем творчестве В.Г. Сорокина
- ЛитРПГ - последняя отрыжка постмодерна
- "Ричард III и семиотика"
- 3D-визуализация обложки Ridero создаем обложку книги при работе над самиздатом.
- Архитектура метамодерна - говоря о современном искусстве, невозможно не поговорить об архитектуре. В данной статье будет отмечено несколько интересных принципов, характерных для построек "новой волны", столь притягательных и скандальных.
- Литература
- Метамодерн
- Рокер-Прометей против изначального зла в «Песне про советскую милицию» Вени Дркина, Автор: Нина Ищенко, к.ф.н, член Союза Писателей ЛНР - перепубликация из журнала "Топос".
- Как избавиться от комаров? Лучшие типы ловушек.
- Что делать если роблокс вылетает на windows
- Что делать, если ребенок смотрит порно?
- Почему собака прыгает на людей при встрече?
- Какое масло лить в Задний дифференциал (мост) Visco diff 38434AA050
- О чем может рассказать хвост вашей кошки?
- Верветки
- Отчетность бюджетных учреждений при закупках по Закону № 223-ФЗ
- Срок исковой давности как правильно рассчитать
- Дмитрий Патрушев минсельхоз будет ли преемником Путина
- Кто такой Владислав Поздняков? Что такое "Мужское Государство" и почему его признали экстремистским в России?
- Как правильно выбрать машинное масло в Димитровграде?
- Как стать богатым и знаменитым в России?
- Почему фильм "Пипец" (Kick-Ass) стал популярен по всему миру?
- Как стать мудрецом?
- Как правильно установить FreeBSD
- Как стать таким как Путин?
- Где лучше жить - в Димитровграде или в Ульяновске?
- Почему город Димитровград так называется?
- Что такое метамодерн?
- ВАЖНО! Временное ограничение движения автотранспортных средств в Димитровграде
- Тарифы на электроэнергию для майнеров предложено повысить
@Override public void onCreate(SQLiteDatabase db) { db.execSQL(“CREATE TABLE” + TASK_TABLE_NAME + “ (“ + ID + “ INTEGER PRIMARY KEY,” + COL_TASK + “ TEXT,” + COL_DUEDATE + “ DATE,” + COL_CREATEDATE + “ INTEGER,” COL_CATEGORY_LINK + “ INTEGER REFERENCES ” + CATEGORY_TABLE + “(” + COL_CATEGORY_ID + “)” + “);”); db.execSQL(“CREATE TABLE” + CATEGORY_TABLE_NAME + “ (“ + ID + “ INTEGER PRIMARY KEY,” + COL_CATEGORY + “ TEXT” + “);”); db.execSQL(“INSERT INTO “ + CATEGORY_TABLE + “VALUES(1, ‘work’);”); db.execSQL(“INSERT INTO “ + CATEGORY_TABLE + “VALUES(2, ‘personal’);”); } }
Данный запрос также создает две записи в таблице Category. Поскольку это ContentProvider, ID должен иметь суффикс “_id” в обеих таблицах; в противном случае SQL выдаст ошибку. Такое происходит в связи с особенностями ContentProvider, а не частных баз данных в Android. После этого реализуйте методы onCreate() и query() класса ContentProvider в нашем классе TodoDatabaseProvider:
private static final int TODOS = 100;
private static final int TODO_ID = 101;
private static final UriMatcher matcher =
new UriMatcher(UriMatcher.NO_MATCH);
static {
matcher.addURI(AUTHORITY, TODO_BASE_PATH, TODOS);
matcher.addURI(AUTHORITY, TODO_BASE_PATH + “/#”, TODO_ID);
}
@Override
public boolean onCreate() {
db = new TodoDBOpenHelper(getContext());
return true;
}
@Override
public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
SQLiteQueryBuilder builder = new SQLiteQueryBuilder();
builder.setTables(TASK_TABLE);
int uriType = matcher.match(uri);
switch (uriType) {
case TODO_ID:
builder.appendWhere(ID + “=” + uri.getLastPathSegment());
break;
case TODOS:
break;
default:
throw new IllegalArgumentException(“Unknown URI” + uri);
}
Cursor cursor = builder.query(db.getReadableDatabase(),
projection, selection, selectionArgs, null, null, sortOrder);
cursor.setNotificationUri(getContext().getContentResolver(), uri);
return cursor;
}
UriMatcher обрабатывает уникальные идентификаторы ресурсов и формирует целое число, в соответствии с конкретным типом URI. Он помечает URI из Authority и путь заданным целым числом.
В этом случае мы сопоставляем URI вида “com.example.todo.TodoDatabaseProvider/todo” (которые, следовательно, ссылаются на весь список) с целым числом 100, а URI вида “com.example.todo.TodoDatabaseProvider/todo/1” (которые, следовательно, ссылаются на отдельный элемент todo) с целым числом 101. Это означает, что затем мы сможем обработать их должным образом с помощью операторов switch в методе query().
Если URI соответствует отдельному заданию, мы добавляем к SQL-запросу выражение where, которое осуществляет поиск по условию ‘id=#’; в противном случае выражения where нет, и мы запрашиваем весь список задач.
SQLiteQueryBuilder, как следует из названия, помогает строить запросы для SQLite. Мы велим ему использовать таблицу Task, добавляем где необходимо выражение where, а затем генерируем Cursor из результатов SQL-запроса. setNotificationUri() регистрирует Cursor для отслеживания любых изменений в содержимом заданного URI.
Нам также нужны методы insert() и update():
@Override
public Uri insert(Uri uri, ContentValues values) {
int uriType = matcher.match(uri);
if (uriType != TODOS) {
throw new IllegalArgumentException(“Invalid URI for insert”);
}
SQLiteDatabase sqlDB = db.getWritableDatabase();
long newID = sqlDB.insert(TASK_TABLE, COL_TASK, values);
if (newID > 0) {
Uri newUri = ContentUris.withAppendedId(uri, newID);
getContext().getContentResolver().notifyChange(uri, null);
return newUri;
} else {
throw new SQLException(“Failed to insert row into “ + uri + “result “ + newID);
}
}
@Override
public int update(Uri uri, ContentValues values, String selection,
String[] selectionArgs) {
int uriType = matcher.match(uri);
if (uriType != TODO_ID) {
throw new IllegalArgumentException(“Invalid URI for update”);
}
long id = ContentUris.parseId(uri);
String where = ID + “=’” + id + “’”;
SQLiteDatabase sqlDB = db.getWritableDatabase();
int result = sqlDB.update(TASK_TABLE, values, where, null);
return result;
}
Метод insert() проверяет URI, идентифицирующий всю таблицу (поскольку мы вставляем новую строку, а не выбираем из существующих), получает доступную для записи базу данных из приватного экземпляра TodoDbOpenHelper (db) и затем пробует добавить данные – Insert.
Переменная COL_TASK требуется нам потому, что абсолютно пустую строку SQL в таблицу добавлять не станет. Если значения values пусты (как обычно и происходит в нашем случае), в COL_TASK попадет явный NULL. Если возвращаемое значение ненулевое, это идентификатор вновь добавленной строки; затем метод notifyChange() оповещает все зарегистрированные методы-наблюдатели об обновлении строки. В противном случае метод завершается неудачно, и мы получаем исключение.
update() проверяет URI, идентифицирующий отдельную задачу, и строит выражение where с идентификатором задачи. Мы опять же получаем доступную для записи базу данных и обновляем ее необходимыми значениями. Результатом будет количество обновленных строк.
Пользовательский интерфейс к базе данных
- Метамодернизм в позднем творчестве В.Г. Сорокина
- ЛитРПГ - последняя отрыжка постмодерна
- "Ричард III и семиотика"
- 3D-визуализация обложки Ridero создаем обложку книги при работе над самиздатом.
- Архитектура метамодерна - говоря о современном искусстве, невозможно не поговорить об архитектуре. В данной статье будет отмечено несколько интересных принципов, характерных для построек "новой волны", столь притягательных и скандальных.
- Литература
- Метамодерн
- Рокер-Прометей против изначального зла в «Песне про советскую милицию» Вени Дркина, Автор: Нина Ищенко, к.ф.н, член Союза Писателей ЛНР - перепубликация из журнала "Топос".
- Как избавиться от комаров? Лучшие типы ловушек.
- Что делать если роблокс вылетает на windows
- Что делать, если ребенок смотрит порно?
- Почему собака прыгает на людей при встрече?
- Какое масло лить в Задний дифференциал (мост) Visco diff 38434AA050
- О чем может рассказать хвост вашей кошки?
- Верветки
- Отчетность бюджетных учреждений при закупках по Закону № 223-ФЗ
- Срок исковой давности как правильно рассчитать
- Дмитрий Патрушев минсельхоз будет ли преемником Путина
- Кто такой Владислав Поздняков? Что такое "Мужское Государство" и почему его признали экстремистским в России?
- Как правильно выбрать машинное масло в Димитровграде?
- Как стать богатым и знаменитым в России?
- Почему фильм "Пипец" (Kick-Ass) стал популярен по всему миру?
- Как стать мудрецом?
- Как правильно установить FreeBSD
- Как стать таким как Путин?
- Где лучше жить - в Димитровграде или в Ульяновске?
- Почему город Димитровград так называется?
- Что такое метамодерн?
- ВАЖНО! Временное ограничение движения автотранспортных средств в Димитровграде
- Тарифы на электроэнергию для майнеров предложено повысить
Мы создали базу данных и методы для доступа к ней; теперь нужно создать интерфейс пользователя для доступа к базе данных. Как указано выше, наш первоначальный интерфейс – список задач и пункт меню для добавления нового элемента списка.
Мы уже в основном с этим справились (если вам нужна помощь, ознакомьтесь с кодом на DVD). Для получения данных из базы и создания списка мы вызовем метод populateList() из метода onCreate(). (Данные для категорий мы пока не получаем; займемся этим позже).
private static final String[] TODO_PROJECTION = newString[] {
TodoDatabaseProvider.ID,
TodoDatabaseProvider.COL_TASK,
TodoDatabaseProvider.COL_DUEDATE
};
private void populateList() {
Cursor cursor = managedQuery(TodoDatabaseProvider.CONTENT_URI,
TODO_PROJECTION, null, null, null);
String[] colNames = { TodoDatabaseProvider.COL_TASK,
TodoDatabaseProvider.COL_DUEDATE };
int[] viewIDs = { R.id.taskname, R.id.duedate };
SimpleCursorAdapter adapter = new SimpleCursorAdapter(
this,
R.layout.todo_item,
cursor,
colNames,
viewIDs
); setListAdapter(adapter);
}
Всю черную работу выполнили за вас классы Cursor и SimpleCursorAdapter (учтите: чтобы это работало автоматически, ваше Занятие должно наследовать ListActivity).
- Метамодернизм в позднем творчестве В.Г. Сорокина
- ЛитРПГ - последняя отрыжка постмодерна
- "Ричард III и семиотика"
- 3D-визуализация обложки Ridero создаем обложку книги при работе над самиздатом.
- Архитектура метамодерна - говоря о современном искусстве, невозможно не поговорить об архитектуре. В данной статье будет отмечено несколько интересных принципов, характерных для построек "новой волны", столь притягательных и скандальных.
- Литература
- Метамодерн
- Рокер-Прометей против изначального зла в «Песне про советскую милицию» Вени Дркина, Автор: Нина Ищенко, к.ф.н, член Союза Писателей ЛНР - перепубликация из журнала "Топос".
- Как избавиться от комаров? Лучшие типы ловушек.
- Что делать если роблокс вылетает на windows
- Что делать, если ребенок смотрит порно?
- Почему собака прыгает на людей при встрече?
- Какое масло лить в Задний дифференциал (мост) Visco diff 38434AA050
- О чем может рассказать хвост вашей кошки?
- Верветки
- Отчетность бюджетных учреждений при закупках по Закону № 223-ФЗ
- Срок исковой давности как правильно рассчитать
- Дмитрий Патрушев минсельхоз будет ли преемником Путина
- Кто такой Владислав Поздняков? Что такое "Мужское Государство" и почему его признали экстремистским в России?
- Как правильно выбрать машинное масло в Димитровграде?
- Как стать богатым и знаменитым в России?
- Почему фильм "Пипец" (Kick-Ass) стал популярен по всему миру?
- Как стать мудрецом?
- Как правильно установить FreeBSD
- Как стать таким как Путин?
- Где лучше жить - в Димитровграде или в Ульяновске?
- Почему город Димитровград так называется?
- Что такое метамодерн?
- ВАЖНО! Временное ограничение движения автотранспортных средств в Димитровграде
- Тарифы на электроэнергию для майнеров предложено повысить
- Метамодернизм в позднем творчестве В.Г. Сорокина
- ЛитРПГ - последняя отрыжка постмодерна
- "Ричард III и семиотика"
- 3D-визуализация обложки Ridero создаем обложку книги при работе над самиздатом.
- Архитектура метамодерна - говоря о современном искусстве, невозможно не поговорить об архитектуре. В данной статье будет отмечено несколько интересных принципов, характерных для построек "новой волны", столь притягательных и скандальных.
- Литература
- Метамодерн
- Рокер-Прометей против изначального зла в «Песне про советскую милицию» Вени Дркина, Автор: Нина Ищенко, к.ф.н, член Союза Писателей ЛНР - перепубликация из журнала "Топос".
- Как избавиться от комаров? Лучшие типы ловушек.
- Что делать если роблокс вылетает на windows
- Что делать, если ребенок смотрит порно?
- Почему собака прыгает на людей при встрече?
- Какое масло лить в Задний дифференциал (мост) Visco diff 38434AA050
- О чем может рассказать хвост вашей кошки?
- Верветки
- Отчетность бюджетных учреждений при закупках по Закону № 223-ФЗ
- Срок исковой давности как правильно рассчитать
- Дмитрий Патрушев минсельхоз будет ли преемником Путина
- Кто такой Владислав Поздняков? Что такое "Мужское Государство" и почему его признали экстремистским в России?
- Как правильно выбрать машинное масло в Димитровграде?
- Как стать богатым и знаменитым в России?
- Почему фильм "Пипец" (Kick-Ass) стал популярен по всему миру?
- Как стать мудрецом?
- Как правильно установить FreeBSD
- Как стать таким как Путин?
- Где лучше жить - в Димитровграде или в Ульяновске?
- Почему город Димитровград так называется?
- Что такое метамодерн?
- ВАЖНО! Временное ограничение движения автотранспортных средств в Димитровграде
- Тарифы на электроэнергию для майнеров предложено повысить
Проекция определяет, какие столбцы запроса нужно вернуть. SimpleCursorAdapter получает cursor, массив строк столбцов, которые нужно отобразить, и идентификаторы представлений viewed, которым должны соответствовать данные этих столбцов. Затем список чудесным образом заполняется.
Проекция определяет, какие столбцы запроса нужно вернуть. SimpleCursorAdapter получает cursor, массив строк столбцов, которые нужно отобразить, и идентификаторы представлений viewed, которым должны соответствовать данные этих столбцов. Затем список чудесным образом заполняется.
Добавление элемента
Теперь мы можем отобразить список заданий, но в нем ничего нет. Для добавления задания воспользуемся новым Занятием – TodoEditor:
@Override public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
final Intent intent = getIntent();
final String action = intent.getAction();
if (Intent.ACTION_INSERT.equals(action)) {
state = STATE_INSERT;
uri = getContentResolver().insert(TodoDatabaseProvider.
CONTENT_URI, null);
if (uri == null) {
Log.e(TAG, “Failed to insert new todo into”
+ TodoDatabaseProvider.CONTENT_URI);
finish();
return;
}
setResult(RESULT_OK, (new Intent()).setAction(uri.toString()));
} else {
Log.e(TAG, “Unrecognised action “ + action + “, exiting”);
finish();
return;
}
cursor = managedQuery(uri, TODO_PROJECTION, null, null, null);
setContentView(R.layout.todo_editor);
text = (EditText) findViewById(R.id.todo);
date = (EditText) findViewById(R.id.duedate);
if (savedInstanceState != null) {
initialTodo = savedInstanceState.getString(INITIAL_TODO);
}
}
Здесь производится вызов провайдера базы данных и предпринимаются действия в соответствии с его результатом. Обратите внимание, что в начале мы вставляем строку, а затем обновляем ее, когда решаем сохранить элемент списка.
Вызовите этот код из Todo.java, добавив пункт меню New Item [Новый элемент]. Мы также снова добавляем пункты меню с помощью MenuInflater (см. код на DVD) для реализации сохранения, удаления и отмены (Save, Delete и Cancel). При сохранении вызывается метод updateTodo():
private final void updateTodo(String task, String duedate) {
ContentValues values = new ContentValues();
if (state == STATE_INSERT) {
values.put(TodoDatabaseProvider.COL_CREATEDATE, System.currentTimeMillis());
values.put(TodoDatabaseProvider.COL_TASK, task);
values.put(TodoDatabaseProvider.COL_DUEDATE, duedate);
}
getContentResolver().update(uri, values, null, null);
}
ContentValues получает значения, которые мы хотим добавить, а затем с помощью getContentResolver() мы получаем провайдера базы данных и вызываем его метод update(). После этого активным занятием снова станет ToDo, и мы увидим в списке новый элемент.
У нас почти закончилось место для статьи. Пока мы работали только с таблицей задач без ссылки на категории; чтобы отобразить категорию для каждой задачи, нам нужно изменить метод populateList(), чтобы он получал эту информацию.
Для этого сначала нужно написать запрос join, который ссылается на две таблицы. managedQuery() не поддерживает работу с несколькими таблицами, и нам придется написать специальный SQL-запрос. Все это, а также код, который понадобится вам для удаления и изменения записей в базе данных, можно найти на LXFDVD (или на www.linuxformat.com).
Домашнее задание
Это приложение работает прекрасно, но оно довольно простое. Вот несколько вещей, которые вы можете захотеть попробовать, чтобы лучше освоить работу API:
- Категория не может быть пустой, ее нужно задавать.
- Пользователь не может редактировать доступные категории. Для их обработки и для корректной работы с Намерениями для вызова корректных Занятий вы скорее всего создадите новое Занятие (редактировать список/редактировать категорию).
- После завершения задачи ее можно только удалить. Как насчет проставления галочки?
- Чтобы даты сохранялись корректно, их нужно вводить в специальном формате. Вместо этого хорошо бы подошел календарь или другая форма ввода.
Взгляните на виджет даты в Android.
В следующей статье этой серии мы посмотрим, как получать информацию из удаленной базы данных и записывать в нее данные. |