MODE_PRIVATE
,
null
);
db
.execSQL(
"CREATE TABLE IF NOT EXISTS MyTable5 (_id
INTEGER PRIMARY KEY AUTOINCREMENT, Name VARCHAR);"
);
Cursor cursor
=
db
.rawQuery(
"SELECT * FROM Mytable5"
,
null
);
i
=
cursor
.getCount()+
1
;
if
(
cursor
.getCount()>
0
) {
MyCursorAdapter scAdapter
=
new
MyCursorAdapter(
MainActivity
.
this
,
R
.
layout
.
list_item
,
cursor
,
from
,
to
);
listView
= getListView();
listView
.setAdapter(
scAdapter
);
}
db
.close();
btnadd
.setOnClickListener(
new
View
.
OnClickListener
() {
@Override
public void
onClick
(
View
view) {
//
TODO
}
});
}
}
Код метода onClick кнопки ADD будет следующим:
db
.execSQL(
"INSERT INTO MyTable5 VALUES
('"
+
i
+
"','"
+
editadd
.getText().toString()+
"');"
);
//i++;
Cursor cursor
=
db
.rawQuery(
"SELECT * FROM Mytable5"
,
null
);
MyCursorAdapter scAdapter
=
new
MyCursorAdapter(
MainActivity
.
this
,
R
.
layout
.
list_item
,
cursor
,
from
,
to
);
listView
= getListView();
listView
.setAdapter(
scAdapter
);
db
.close();
91
Toast
. makeText(getListView().getContext(),
"a row added to the
table"
,
Toast
.
LENGTH_LONG
).show();
Однако, чтобы избежать метаморфоз с PRIMARY KEY при добавлении
новой записи после удаления некоторых старых нужно написать
дополнительный код в начале этого метода, чтобы найти подходящее
значение для id очередной записи, которое удовлетворяло бы ограничению
на уникальность. Иначе после удаления 2 записи при наличии 1 и 3 записи в
таблице при попытке добавления очередной записи добавится запись с id=2,
после чего при очередном добавлении записи приложение вылетит с
ошибкой, т.к. запись с id=3 в таблице уже есть. Этот код выглядит
следующим образом:
SQLiteDatabase db
=
openOrCreateDatabase(
"DBName"
,
MODE_PRIVATE
,
null
);
Cursor cursor2
=
db
.rawQuery(
"SELECT * FROM Mytable5"
,
null
);
i
=
cursor2
.getCount()+
1
;
//цикл для того, чтобы подбирать значения _id и не допускать
повторения одинаковых значений (primary key как-никак)
for
(
int
k=
1
;k<=
i
;k++) {
Cursor cursor3
=
db
.rawQuery(
"SELECT * FROM Mytable5 WHERE
_id="
+k+
""
,
null
);
if
(
cursor3
.getCount()==
0
) {
i
=k;
break
;
}
}
И, как Вы уже заметили, для того, чтобы приведённый выше код
работал, нужно создать дополнительный класс MyCursorAdapter (чтобы не
пихать весь код в MainActivity.java), занимающийся обработкой нажатий
кнопок EDIT и DELETE в интерфейсе приложения для каждой отдельной
записи:
public class
MyCursorAdapter
extends
SimpleCursorAdapter
{
private int
layout_
;
private
Cursor
cursor
;
String
[]
from
;
int
[]
to
;
92
ListView
listView
;
EditText
edit2
;
public
MyCursorAdapter
(
Context
context,
int
layout,
Cursor
c,
String
[] from,
int
[] to) {
super
(context, layout, c, from, to);
layout_
=layout;
cursor
=c;
}
@Override
public void
bindView
(
View
view,
Context
_context,
Cursor
cursor) {
String data
=
cursor.getString(cursor.getColumnIndex(
"Name"
));
int
id
= cursor.getInt(cursor.getColumnIndex(
"_id"
));
TextView text
=
view.findViewById(
R
.
id
.
textViewListItemText
);
text
.setText(
data
);
Button butdel
= view.findViewById(
R
.
id
.
buttonDelete
);
Button butedit
= view.findViewById(
R
.
id
.
buttonEdit
);
listView
=
MainActivity
.
listView
;
butdel
.setOnClickListener(
new
View
.
OnClickListener
() {
@Override
public void
onClick
(
View
view) {
SQLiteDatabase db
=
_context
.openOrCreateDatabase(
"DBName"
,
MODE_PRIVATE
,
null
);
db
.execSQL(
"DELETE FROM MyTable5 WHERE
_id="
+
id
+
""
);
Cursor cursor
=
db
.rawQuery(
"SELECT * FROM
Mytable5"
,
null
);
from
=
new
String[]{
"Name"
};
to
=
new int
[] {
R
.
id
.
textView
};
MyCursorAdapter scAdapter
=
new
MyCursorAdapter(
_context
,
R
.
layout
.
list_item
,
cursor
,
from
,
to
);
listView
.setAdapter(
scAdapter
);
db
.close();
Toast
. makeText(
_context
,
"row deleted from the db
id="
+
id
,
Toast
.
LENGTH_LONG
).show();
}
});
butedit
.setOnClickListener(
new
View
.
OnClickListener
() {
@Override
public void
onClick
(
View
view) {
AlertDialog
.
Builder dialog
=
new
AlertDialog
.Builder(
_context
);
dialog
.setMessage(
"Enter new value:"
);
dialog
.setTitle(
"Changing the item"
);
LayoutInflater inflater
=
new
LayoutInflater
(
_context
) {
@Override
public
LayoutInflater
cloneInContext
(
Context
context) {
93
return null
;
}
};
View dialogview
=
inflater
.inflate(
R
.
layout
.
dialog
,
null
);
dialog
.setView(
dialogview
);
edit2
=
dialogview
.findViewById(
R
.
id
.
editTextCnahgeDBRecord
);
edit2
.setText(
text
.getText().toString());
dialog
.setNeutralButton(
"OK"
,
new
DialogInterface
.
OnClickListener
() {
@Override
public void
onClick
(
DialogInterface
dialog,
int
i) {
SQLiteDatabase db
=
_context
.openOrCreateDatabase(
"DBName"
,
MODE_PRIVATE
,
null
);
db
.execSQL(
"UPDATE MyTable5 SET
Name='"
+
edit2
.getText().toString()+
"' WHERE _id="
+
id
+
""
);
Cursor cursor
=
db
.rawQuery(
"SELECT *
FROM Mytable5"
,
null
);
from
=
new
String[]{
"Name"
};
to
=
new int
[] {
R
.
id
.
textView
};
MyCursorAdapter scAdapter
=
new
MyCursorAdapter(
_context
,
R
.
layout
.
list_item
,
cursor
,
from
,
to
);
listView
.setAdapter(
scAdapter
);
db
.close();
Toast
. makeText(
_context
,
"row edited from
the db row id="
+
id
,
Toast
.
LENGTH_LONG
).show();
dialog.dismiss();
}
});
dialog
.setIcon(
R
.
mipmap
.
ic_launcher_round
);
AlertDialog alertDialog
=
dialog
.create();
alertDialog
.show();
}
});
}
@Override
public
View
newView
(
Context
context,
Cursor
cursor,
ViewGroup
parent) {
LayoutInflater inflater
= (
LayoutInflater
)
context.getSystemService(context.
LAYOUT_INFLATER_SERVICE
);
View view
=
inflater
.inflate(
layout_
,parent,
false
);
return
view
;
}
}
И всё - приложение, работающее с базой данных и включающее
основные операции SQL завершено. Единственное, что нужно помнить – это
94
приложение не идеально; все операции с записями хорошо бы перенести в
отдельный класс (как и SELECT, и INSERT), причём – в отдельные методы
этого класса, называющиеся соответствующим образом; затем – интерфейс,
конечно же, нужно загружать в отдельном асинхронном потоке, т.к. –
представьте, что у Вас в таблице 1000 строк, а не 10-15; что тогда будет с
работой приложения?
95
Лабораторная работа №16. Облачное мобильное приложение
Задание: Создать простейшее облачное мобильное приложение,
используя Firebase и Android Studio.
Для выполнения этого задания можно выбрать любой облачный сервис,
будь то push-уведомления, база данных реального времени, аналитика
мобильного приложения (не в Google Play, а с помощью сторонних средств,
например, Flurry, MixPanel, Crashlytics и т.д.), использование облачных
сервисов, связанных с тестированием, распознаванием изображений и т.д.
Рассмотрим один из простых примеров – создание push-уведомлений с
помощью Firebase.
Первое, что нужно сделать – это создать новый проект в консоли
Firebase (
https://console.firebase.google.com/
). Добавить проект – назовите как-
то проект, выберите местоположение и нажмите на чекбокс "Я принимаю", а
затем – на кнопку Создать проект, см. рисунок 46. Затем нажмите на
Продолжить.
96
Рисунок 46 – Создание проекта в Firebase
Откроется окно управления проектом, в котором нам нужно нажать на
кнопку с иконкой ОС Андроид над надписью Добавьте приложение. После
этого нам потребуется ввести название пакета, поэтому перейдём в Android
Studio и создадим новый проект с Empty Activity. Добавим в проект
97
опциональное меню с пунктом вызова окна О программе, как обычно. Затем
перейдём в файл манифеста и скопируем значение переменной package,
которое вставим в окно Firebase в строку Название пакета Android.
Дополнительно можно заполнить поля псевдонима и хэша сертификата, но
это необязательно. Нажмём на кнопку Зарегистрировать приложение.
Далее скачаем файл конфигурации google-services.json и поместим его
в корень нашего проекта. Для этого переключим вид в Project Explorer (слева
вверху) c Android на Project, щёлкнем правой кнопкой мыши по папке app и
нажмём Paste, и в открывшемся окне – OK. В режиме Project мы увидим файл
json, а в режиме Android его не видно. Затем переключитесь обратно в режим
Android.
В окне Firebase браузера нажмём Далее.
Теперь надо изменить файлы gradle. Следуйте инструкциям в окне
браузера, так как там может быть более новая версия, чем здесь. Итак, в файл
build.gradle уровня проекта (Project: название) в dependencies надо добавить
строку
classpath 'com.google.gms:google-services:4.0.1'
В файл build.gradle уровня приложения (Module: app) добавьте
следующее в секцию dependencies:
implementation 'com.google.firebase:firebase-core:16.0.1'
implementation 'com.google.firebase:firebase-messaging:17.4.0'
и в самый конце этого файла:
apply plugin: 'com.google.gms.google-services'
98
После этого синхронизируйте проект (Sync Now). В окне браузера
нажмите кнопку Далее. После этого обязательно запустите приложение! При
этом эмулятор или реальное устройство должны быть подлючены к
интернету. Если всё в порядке, в окне проверки связи с приложением
браузера будет выведена соответствующая зелёная надпись (Поздравляем!
Вы добавили сервис Firebase в свое приложение). Если связи с приложением
нет, повторите предыдущие шаги.
Теперь удалим TextView "Hello World!", добавим в интерфейс на его
место кнопку, и напишем внутри обработчика нажатия на неё следующий
код:
String tkn = FirebaseInstanceId. getInstance().getToken();
Toast. makeText(MainActivity.
Достарыңызбен бөлісу: |