Ограничение доступа
Ролевой механизм
Загрузка модулей410013796724260
|
Вернуться к описанию Хранение данных и файлов в Android
Пример SQLite в AndroidНа странице представлен пример использование БД SQLite в приложение Android. Описание методов взаимодействия с БД описано на странице SQLite в Android. Чтобы было легче связать описание примера с его интерфейсом сразу же рассмотрим графическое представление. Интерфейс представленияВ примере рассматривается создание БД, создание таблицы БД, добавление и удаление записей таблицы. На следующем скриншоте представлен интерфейс примера после старта в Android Studio. В верхней части формы в табличном виде отображаются записи таблицы. Ниже, в виде подкрашенного прямоугольника распологается компонент TextView для логирования сообщений. В самом низу располагаются кнопки выполнения транзакций : Создание БД и таблицы, Удаление таблицы и БД, Добавление записи в таблицу и Удаление записи из таблицы.
Бизнес-логика функционирования примера интуитивно понятна. В примере невозможность выполнения какой-либо транзакции обеспечивается блокированием соответствующей кнопки и наоборот, если кнопка доступна, то можно выполнить соответствующую транзакцию. Таким образом, пока не создана БД и таблица, пока не добавлена запись в таблицу кнопку удаления записи останется заблокированой. В примере используется три тестовые записи для добавления. После того, как будет добавлена последняя 3-я запись кнопка Добавления блокируется. Описание кодаНиже представлен проект/модуль store-sql в IDE Android Studio. ![]() В проекте определены следующие объекты :
Интерфейс примера на уровне среды разработки (IDE) определяет главный ресурсный файл activity_main.xml. В режиме исполнения примера главный модуль активности MainActivity.java формирует интерфейс и определяет бизнес-логику управления компонентами. Остальные ресурсные файлы играют вспомогательную роль для представления интерфейса компонентов (цвет, фон, текст). Листинг colors.xmlРесурсный файл colors.xml создается автоматически средой Android Studio при формировании нового модуля/проекта. В контект файла добавлен цвет gray_light для подкраски фона прямоугольника.
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="purple_200">#FFBB86FC</color>
<color name="purple_500">#FF6200EE</color>
<color name="purple_700">#FF3700B3</color>
<color name="teal_200">#FF03DAC5</color>
<color name="teal_700">#FF018786</color>
<color name="black">#FF000000</color>
<color name="white">#FFFFFFFF</color>
<color name="gray_light">#FFEEEEEE</color>
</resources>
Листинг strings.xmlРесурсный файл strings.xml создается автоматически, также как и colors.xml, средой Android Studio при формировании нового модуля/проекта. В модуле переопределен заголок (app_name) и добавлены строки определения текста меток и кнопок интерфейса.
<resources>
<resources>
<string name="app_name">Пример с SQLite</string>
<string name="bntCreate">Создать БД</string>
<string name="btnDrop">Удалить БД</string>
<string name="tvDB">Таблица БД SQLite</string>
<string name="tvLog">Протоколирование</string>
<string name="btnAddRec">Добавить запись</string>
<string name="btnDelRec">Удалить запись</string>
<string name="btnRecNext">Следующая запись</string>
<string name="btnRecPrev">Предыдущая запись</string>
<string name="tvBtnDB">Управление БД</string>
<string name="tvBtnRecs">Управление записями</string>
<string name="tdName">Имя</string>
<string name="tdPosition">Должность</string>
<string name="tdPhone">Телефон</string>
</resources>
border_gray.xmlРесурсный файл border_gray.xml создан для формирования интерфейса компонента TextView в виде закрашенного прямоугольника. Располагается файл в разделе res/drawable. Главная секция XML-файла имеет тег shape. Внутреннее содержимое файла определяет цвет фона, цвет обрамляющего прямоугольника и радиус скругления углов прямоугольника. Ниже представлен листинг файла border_gray.xml (в свернутом виде). Листинг border_gray.xml
<?xml version="1.0" encoding="utf-8"?>
<shape
xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle" >
<!-- View background color -->
<solid
android:color="@color/gray_light" >
</solid>
<!-- View border color and width -->
<stroke
android:width="1dp"
android:color="@color/black" >
</stroke>
<!-- The radius makes the corners rounded -->
<corners
android:radius="3dp" >
</corners>
</shape>
Для создания ресурсного файла border_gray.xml с помощью IDE Android Studio необходимо выделить в проекте запись res/drawable и в контекстном меню выбрать пункт New/Drawable Resource File. В открывшемся диалоговом окне, как это представлено на следующем скриншоте, необходимо определить File name, наименование корневого элемента Root name и нажать ОК. После того, как файл будет создан, его можно открыть и отредактировать. Ресурсный файл border_white.xml отличается только цветом фона.
activity_main.xmlНа следующем скриншоте представлен ресурсный файл activity_main.xml в режиме Design. Данный ресурс определяет интерфейс приложения/модуля в режиме run-time. Особый комментарий здесь не требуется; только отмечу, что таблица записей формируется из разметки TableLayout и компонентов TableRow и TextView. Пример тестовый для проверки методов взаимодействия с SQLite, поэтому не судите строго за дизайн. Для редактирования компонента в режиме Design его можно выделить в дереве компонентов Component Tree (слева снизу), и определить свойства в панели атрибутов, не представленной на скриншоте. Также компоненты можно редактировать непосредственно в файле, переключаясь в режим Code.
Ниже (в свернутом виде) представлен листинг activity_main.xml. После переключения редактора ресурсного файла из режима Design в режим Code свойства визуальных компонентов интерфейса можно редактировать непосредственно в файле. IDE Android Studio "помогает" при прямом редактировании свойств компонента представлением всплывающих подсказок. Листинг activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
<?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"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:verticalScrollbarPosition="right"
tools:context=".MainActivity">
<TextView
android:id="@+id/tvDB"
android:layout_width="211dp"
android:layout_height="25dp"
android:layout_marginStart="16dp"
android:layout_marginTop="8dp"
android:text="@string/tvDB"
android:textStyle="bold"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TableLayout
android:id="@+id/tlGrid"
android:layout_width="375dp"
android:layout_height="114dp"
android:layout_marginStart="16dp"
android:layout_marginTop="4dp"
android:background="@drawable/border_white"
android:stretchColumns="*"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/tvDB">
<TableRow
android:id="@+id/trHeader"
android:layout_width="match_parent"
android:layout_height="16dp"
android:orientation="horizontal">
<TextView
android:layout_weight="1"
android:background="@drawable/cell_gray"
android:gravity="center"
android:padding="6dip"
android:text="@string/tdName"
android:textAlignment="center"
android:textColor="#444444"
android:textStyle="bold" />
<TextView
android:layout_weight="1"
android:background="@drawable/cell_gray"
android:gravity="center"
android:padding="6dip"
android:text="@string/tdPosition"
android:textAlignment="center"
android:textColor="#444444"
android:textStyle="bold" />
<TextView
android:layout_weight="1"
android:background="@drawable/cell_gray"
android:gravity="center"
android:padding="6dip"
android:text="@string/tdPhone"
android:textAlignment="center"
android:textColor="#444444"
android:textStyle="bold" />
</TableRow>
<TableRow
android:id="@+id/trRow1"
android:layout_width="match_parent"
android:orientation="horizontal">
<TextView
android:id="@+id/tvCell00"
android:background="@drawable/cell_white"
android:padding="4dip"
android:textAlignment="textStart"
android:textColor="#444444"
android:textStyle="bold" />
<TextView
android:id="@+id/tvCell01"
android:background="@drawable/cell_white"
android:padding="4dip"
android:textAlignment="textStart"
android:textColor="#444444"
android:textStyle="bold" />
<TextView
android:id="@+id/tvCell02"
android:background="@drawable/cell_white"
android:padding="4dip"
android:textAlignment="textStart"
android:textColor="#444444"
android:textStyle="bold" />
</TableRow>
<TableRow
android:id="@+id/trRow2"
android:layout_width="match_parent"
android:orientation="horizontal">
<TextView
android:id="@+id/tvCell10"
android:layout_weight="1"
android:background="@drawable/cell_white"
android:padding="4dip"
android:textAlignment="textStart"
android:textColor="#444444"
android:textStyle="bold" />
<TextView
android:id="@+id/tvCell11"
android:layout_weight="1"
android:background="@drawable/cell_white"
android:padding="4dip"
android:textAlignment="textStart"
android:textColor="#444444"
android:textStyle="bold" />
<TextView
android:id="@+id/tvCell12"
android:layout_weight="1"
android:background="@drawable/cell_white"
android:padding="4dip"
android:textAlignment="textStart"
android:textColor="#444444"
android:textStyle="bold" />
</TableRow>
<TableRow
android:id="@+id/trRow3"
android:layout_width="match_parent"
android:orientation="horizontal">
<TextView
android:id="@+id/tvCell20"
android:layout_weight="1"
android:background="@drawable/cell_white"
android:padding="4dip"
android:textAlignment="textStart"
android:textColor="#444444"
android:textStyle="bold" />
<TextView
android:id="@+id/tvCell21"
android:layout_weight="1"
android:background="@drawable/cell_white"
android:padding="4dip"
android:textAlignment="textStart"
android:textColor="#444444"
android:textStyle="bold" />
<TextView
android:id="@+id/tvCell22"
android:layout_weight="1"
android:background="@drawable/cell_white"
android:padding="4dip"
android:textAlignment="textStart"
android:textColor="#444444"
android:textStyle="bold" />
</TableRow>
</TableLayout>
<TextView
android:id="@+id/tvLogCaption"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="8dp"
android:text="@string/tvLog"
android:textStyle="bold"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/tlGrid" />
<EditText
android:id="@+id/edtLog"
android:layout_width="375dp"
android:layout_height="96dp"
android:layout_marginStart="16dp"
android:layout_marginTop="8dp"
android:background="@drawable/border_gray"
android:ems="10"
android:gravity="start|top"
android:inputType="textMultiLine"
android:padding="4dp"
android:scrollbarAlwaysDrawHorizontalTrack="false"
android:textSize="12sp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/tvLogCaption"
tools:ignore="SpeakableTextPresentCheck" />
<TextView
android:id="@+id/tvBtnDB"
android:layout_width="374dp"
android:layout_height="25dp"
android:layout_marginStart="16dp"
android:layout_marginTop="16dp"
android:text="@string/tvBtnDB"
android:textStyle="bold"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/edtLog" />
<Button
android:id="@+id/btnCreate"
android:layout_width="180dp"
android:layout_height="56dp"
android:layout_marginStart="16dp"
android:layout_marginTop="8dp"
android:onClick="onBtnCreateClick"
android:text="@string/bntCreate"
android:textSize="12sp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/tvBtnDB" />
<Button
android:id="@+id/btnDrop"
android:layout_width="180dp"
android:layout_height="56dp"
android:layout_marginStart="24dp"
android:layout_marginTop="8dp"
android:onClick="onBtnDropClick"
android:text="@string/btnDrop"
android:textSize="12sp"
app:layout_constraintStart_toEndOf="@+id/btnCreate"
app:layout_constraintTop_toBottomOf="@+id/tvBtnDB" />
<TextView
android:id="@+id/tvBtnRecs"
android:layout_width="376dp"
android:layout_height="18dp"
android:layout_marginStart="16dp"
android:layout_marginTop="16dp"
android:text="@string/tvBtnRecs"
android:textStyle="bold"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/btnCreate" />
<Button
android:id="@+id/btnAddRec"
android:layout_width="180dp"
android:layout_height="56dp"
android:layout_marginStart="16dp"
android:layout_marginTop="8dp"
android:onClick="onBtnAddRecClick"
android:text="@string/btnAddRec"
android:textSize="12sp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/tvBtnRecs" />
<Button
android:id="@+id/btnDelRec"
android:layout_width="180dp"
android:layout_height="56dp"
android:layout_marginStart="24dp"
android:layout_marginTop="8dp"
android:onClick="onBtnDelRecClick"
android:text="@string/btnDelRec"
android:textSize="12sp"
app:layout_constraintStart_toEndOf="@+id/btnAddRec"
app:layout_constraintTop_toBottomOf="@+id/tvBtnRecs" />
</androidx.constraintlayout.widget.ConstraintLayout>
MainActivity.javaФайл MainActivity.java (представлен ниже в свернутом виде) наследует свойства активности AppCompatActivity, формирует интерфейс примера и определяет бизнес-логику его компонентов. Активность MainActivity включает следующие методы :
Детального описания кода активности не требуется, он «прозрачен». Листинг MainActivity.java
import androidx.appcompat.app.AppCompatActivity;
import android.content.ContentValues;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
public class MainActivity extends AppCompatActivity
{
Button btnCreate = null;
Button btnDrop = null;
Button btnAddRec = null;
Button btnDelRec = null;
EditText edtLog = null;
TextView tvCell00 = null;
TextView tvCell01 = null;
TextView tvCell02 = null;
TextView tvCell10 = null;
TextView tvCell11 = null;
TextView tvCell12 = null;
TextView tvCell20 = null;
TextView tvCell21 = null;
TextView tvCell22 = null;
SQLiteDatabase db = null;
final String DB_NAME = "my.db";
final String TABLE_NAME = "users";
final String TABLE_CREATE =
"CREATE TABLE IF NOT EXISTS users("
+ "name varchar(128), "
+ "position varchar (64), "
+ "phone varchar (16))";
final String SQL_SELECT =
"select name, position, phone from users";
final String[][] DATA =
{{"Сергей С." , "Менеджер" ,
"+X(123) 987-76-54"},
{"Виталий В.", "Администратор" ,
"+X(987) 111-22-33"},
{"Петр А." , "Экспедитор" ,
"+X(654) 444-55-66"}};
final String TABLE_CHECK = "select DISTINCT tbl_name "
+ "from sqlite_master "
+ "where tbl_name = '%s'";
final String TABLE_COUNT = "select count(*) "
+ "from users";
final String TABLE_DROP = "DROP TABLE users";
final String LOG_TAG = "DEVELOPMENT";
int record_idx = -1;
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btnCreate = findViewById(R.id.btnCreate);
btnDrop = findViewById(R.id.btnDrop );
btnAddRec = findViewById(R.id.btnAddRec);
btnDelRec = findViewById(R.id.btnDelRec);
tvCell00 = findViewById(R.id.tvCell00 );
tvCell01 = findViewById(R.id.tvCell01 );
tvCell02 = findViewById(R.id.tvCell02 );
tvCell10 = findViewById(R.id.tvCell10 );
tvCell11 = findViewById(R.id.tvCell11 );
tvCell12 = findViewById(R.id.tvCell12 );
tvCell20 = findViewById(R.id.tvCell20 );
tvCell21 = findViewById(R.id.tvCell21 );
tvCell22 = findViewById(R.id.tvCell22 );
edtLog = findViewById(R.id.edtLog );
checkPermition();
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
private void checkPermition()
{
btnCreate.setEnabled(db == null);
btnDrop .setEnabled(db != null);
if (db == null) {
btnAddRec .setEnabled(false);
btnDelRec .setEnabled(false);
} else {
int record_count = selectCount();
btnAddRec.setEnabled(record_count < 3);
btnDelRec.setEnabled(record_idx >= 0);
}
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
private void logTransaction(final String text)
{
String log;
if (edtLog.getText().length() > 0)
log = edtLog.getText() + "\n" + text;
else
log = text;
edtLog.setText(log);
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
private boolean createTable()
{
db.execSQL(TABLE_CREATE);
String sql = String.format(TABLE_CHECK,
TABLE_NAME);
Cursor cursor = db.rawQuery(sql, null);
boolean result = cursor.getCount() > 0;
cursor.close();
return result;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
private boolean dropTable()
{
db.execSQL(TABLE_DROP);
String sql = String.format(TABLE_CHECK,
TABLE_NAME);
Cursor cursor = db.rawQuery(sql, null);
boolean result = cursor.getCount() == 0;
cursor.close();
record_idx = -1;
return result;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
private int selectCount()
{
if (db == null)
return 0;
Cursor cursor = db.rawQuery(TABLE_COUNT, null);
cursor.moveToFirst();
int count= cursor.getInt(0);
cursor.close();
Log.d(LOG_TAG, "Записей в таблице : " + count);
return count;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
public void onBtnCreateClick(View v)
{
edtLog.setText("");
db = openOrCreateDatabase(DB_NAME,
MODE_PRIVATE, null);
if (db != null) {
logTransaction("БД создана успешно");
if (createTable())
logTransaction("Таблица создана успешно");
checkPermition();
}
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
public void onBtnDropClick(View v) {
if (dropTable())
logTransaction("Таблица удалена");
if (deleteDatabase(DB_NAME)) {
db = null;
logTransaction("БД удалена");
checkPermition();
}
clearTable();
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
public void onBtnAddRecClick(View v)
{
record_idx++;
Log.d(LOG_TAG, "record_idx = " + record_idx);
if (record_idx >= DATA.length) {
record_idx--;
return;
}
ContentValues record = new ContentValues();
record.put("name" , DATA[record_idx][0]);
record.put("position", DATA[record_idx][1]);
record.put("phone" , DATA[record_idx][2]);
long rc = db.insert(TABLE_NAME, null, record);
Log.d(LOG_TAG, "rc = " + rc);
if (rc > 0) {
logTransaction("Добавлена строка");
drawRowData((int)rc - 1);
}
checkPermition();
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
public void onBtnDelRecClick(View v)
{
String table = "users";
String where = "name=?";
String[] whereArgs = null;
if (record_idx == 2)
whereArgs = new String[]
{(String) tvCell20.getText()};
else if (record_idx == 1)
whereArgs = new String[]
{(String) tvCell10.getText()};
else if (record_idx == 0)
whereArgs = new String[]
{(String) tvCell00.getText()};
int rc = db.delete(table, where, whereArgs);
logTransaction("Строка удалена : rc = " + rc + ",
row.count = " + selectCount());
clearRow(record_idx);
record_idx--;
checkPermition();
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
private void drawRowData(final int row)
{
int count = selectCount();
Cursor cursor = db.rawQuery(SQL_SELECT, null);
if ((cursor != null) && (cursor.getCount() > 0)) {
cursor.moveToPosition(row);
if (row == 0) {
tvCell00.setText(cursor.getString(0));
tvCell01.setText(cursor.getString(1));
tvCell02.setText(cursor.getString(2));
} else if (row == 1) {
tvCell10.setText(cursor.getString(0));
tvCell11.setText(cursor.getString(1));
tvCell12.setText(cursor.getString(2));
} else if (row == 2) {
tvCell20.setText(cursor.getString(0));
tvCell21.setText(cursor.getString(1));
tvCell22.setText(cursor.getString(2));
}
}
cursor.close();
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
private void clearRow(final int row)
{
Log.d(LOG_TAG, "clearRow : row = " + row);
if (row == 0) {
tvCell00.setText("");
tvCell01.setText("");
tvCell02.setText("");
} else if (row == 1) {
tvCell10.setText("");
tvCell11.setText("");
tvCell12.setText("");
} else if (row == 2) {
tvCell20.setText("");
tvCell21.setText("");
tvCell22.setText("");
}
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
private void clearTable()
{
tvCell00.setText("");
tvCell01.setText("");
tvCell02.setText("");
tvCell10.setText("");
tvCell11.setText("");
tvCell12.setText("");
tvCell20.setText("");
tvCell21.setText("");
tvCell22.setText("");
}
}
В модуле используется средство просмотра отладочных сообщений Logcat с тегом LOG_TAG для вывода дополнительной информации о состоянии внешнего хранилища, а также путей к файлам. |

