Obraz zawierający tekst, Czcionka, Grafika

Opis wygenerowany automatycznie 

Kierunek Informatyka

 

Instrukcja do ćwiczeń laboratoryjnych nr:

8

Nazwa przedmiotu:
Programowanie aplikacji mobilnych

Temat: Obsługa lokalnej bazy danych SQLiteRoom oraz SQLiteOpenHelper

Tryb studiów: stacjonarne

Czas trwanie ćw.

2x45 min

Autor materiałów: dr Marcin Skuba

1. Treści programowe: 

Baza danych SQLite, bibliotekę Room Persistence Library, encje, DAO  (Data Access Objects), pobieranie, zapisywanie danych oraz starszej metody SQLiteOpenHelper.

 

2. Cel zajęć:

Celem zajęć jest poznanie mechanizmu zarządzania informacjami w lokalnej bazie danych SQLite używając architektury Room.

 

3. Materiały dydaktyczne

SQLite jest bardzo „lekkim”, darmowym systemem zarządzania relacyjną bazą danych wykorzystującym bibliotekę napisaną w języku C pozwalająca na używanie języka SQL. System uruchamia bazę danych bez uruchamiania oddzielnego procesu. Jest to podstawa do używania go np. w systemach wbudowanych. Wszystko co jest potrzebne znajduję się w jednym pliku. Programując w systemie operacyjnym Android możemy używać SQLite bez instalowania dodatkowych sterowników. Bazę tą możemy używać również w aplikacjach desktopowych w różnych językach programowania. SQLite jest rekomendowane przez Google jako lokalna baza danych.    

 

Dokumentacja: https://developer.android.com/training/data-storage/room#kts

 

ü Room

 

 

 

 

 

Room został stworzony, aby pomóc deweloperom w tworzeniu solidnych, skalowalnych i łatwych w utrzymaniu baz danych na platformie Android.

 

Niezbędne zależności (kotlin):

val room_version = "2.8.3"
implementation("androidx.room:room-runtime:$room_version")
annotationProcessor("androidx.room:room-compiler:$room_version")

 

 

I. Entity

 

1. Adnotacja @Entity

 

2. Adnotacja @PrimaryKey

 

public class User {
   
@PrimaryKey(autoGenerate = true)
   
private int id;

}

 

Definicja klucza złożonego klucza głównego primaryKeys:

 

@Entity(primaryKeys = {"firstName", "lastName"})
public class User {
   
public String firstName;
   
public String lastName;
}

 

3. Adnotacja @ColumnInfo

 

@ColumnInfo(name = "first_name")
private String firstName;

@ColumnInfo(name = "last_name")
private String lastName;

 

4. Adnotacja @Ignore

 

@Entity
public class User {
   
@PrimaryKey
   
public int id;

   
public String firstName;
   
public String lastName;

   
@Ignore
   
Bitmap picture;
}

 

Gdy klasa główna dziedziczy pola z klasy nadrzędnej, zazwyczaj łatwiej jest użyć ignoredColumn właściwości atrybutu @Entity

 

@Entity(ignoredColumns = "picture")
public class RemoteUser extends User {
   
@PrimaryKey
   
public int id;

   
public boolean hasVpn;
}

 

------------------------------------------------------------------------

Obiekt reprezentujący tabelę – jednostka danych entitiy:

 

Plik User.java

 

import androidx.room.ColumnInfo;
import androidx.room.Entity;
import androidx.room.PrimaryKey;

// 1. Określamy nazwę tabeli w bazie danych
@Entity(tableName = "users")
public class User {

   
// 2. Definicja Klucza Głównego (Primary Key)
    // autoGenerate = true oznacza, że SQLite automatycznie wygeneruje unikalny ID
   
@PrimaryKey(autoGenerate = true)
   
private int id;

   
// 3. Definicja kolumn tabeli
    // Określamy nazwę kolumny w bazie
   
@ColumnInfo(name = "first_name")
   
private String firstName;

   
@ColumnInfo(name = "last_name")
   
private String lastName;

   
@ColumnInfo(name = "age")
   
private int age;
   
// Konstruktor do tworzenia obiektu
    // Room użyje tego konstruktora do wstawiania danych do bazy
    // oraz do odczytu danych z bazy (lub konstruktora bez argumentów, jeśli jest obecny)
   
public User(String firstName, String lastName, int age) {
       
this.firstName = firstName;
       
this.lastName = lastName;
       
this.age = age;
    }

   
// --- Gettery i Settery ---
    // W Javie są one niezbędne, aby Room mógł odczytywać i ustawiać wartości pól.
   
public int getId() {
       
return id;
    }
   
// Room wymaga settera dla Primary Key, jeśli używamy autoGenerate = true
   
public void setId(int id) {
       
this.id = id;
    }
   
public String getFirstName() {
       
return firstName;
    }
   
public void setFirstName(String firstName) {
       
this.firstName = firstName;
    }
   
public String getLastName() {
       
return lastName;
    }
   
public void setLastName(String lastName) {
       
this.lastName = lastName;
    }
   
public int getAge() {
       
return age;
    }
  
public void setAge(int age) {
       
this.age = age;
    }
}

 

 

II. Główny punkt dostępu   

 

Poniższy kod definiuje klasę AppDatabase, która jest głównym punktem dostępu i konfiguracji dla bazy danych Room w systemie Android.

AppDatabase jest centralną klasą, która łączy Twoje encje (User) i DAO (UserDao), zarządzając bazą danych SQLite.

 

Plik AppDatabase.java

 

 

import androidx.room.Database;
import androidx.room.RoomDatabase;

@Database(entities = {User.class}, version = 2)
public abstract class AppDatabase extends RoomDatabase {
   
public abstract UserDao userDao();
}

 

 

Element

Opis

extends RoomDatabase

Abstrakcyjna klasa bazy danych Room. Room automatycznie generuje jej implementację podczas kompilacji.

@Database(...)

Adnotacja konfigurująca bazę danych.

entities = {User.class}

Określa, że w tej bazie danych znajduje się jedna tabela, reprezentowana przez encję User. Jeśli byłoby więcej tabel, byłyby one tutaj wymienione.

version = 1

Ustala wersję schematu bazy danych. Wymaga zwiększenia tego numeru, jeśli zmieniasz strukturę tabel (np. dodajesz kolumny), co wymusza uruchomienie migracji.

public abstract UserDao userDao();

Abstrakcyjna metoda służąca do uzyskiwania dostępu do DAO (UserDao). Pozwala to na wykonywanie operacji na danych (zapytań) w tabeli User.

 

 

III. DAO (Data Access Objects)  

 

DAO (ang. Data Access Object – Obiekt Dostępu do Danych) to wzorzec projektowy w programowaniu oraz kluczowy komponent biblioteki Room w systemie Android.

 

 

DAO to "słownik" lub "katalog" wszystkich operacji, które możesz wykonać na danych w swojej bazie, oddzielając w ten sposób logikę dostępu do danych od reszty aplikacji.

 

--------------------------------------------------------------------------------------------

Przykład pokazujący deklarację interfejsu do obsługi danych reprezentowanych przez klasę User:

 

Plik UserDao.java


import androidx.lifecycle.LiveData;
import androidx.room.Dao;
import androidx.room.Delete;
import androidx.room.Insert;
import androidx.room.Query;
import androidx.room.Update;
import java.util.List;

// Adnotacja @Dao oznacza, że ten interfejs jest Data Access Object dla Room
@Dao
public interface UserDao {

   
/**
     * Wstawia jednego lub więcej użytkowników do bazy danych.
     *
@param user Użytkownik do wstawienia.
     *
@return Zwraca ID nowo wstawionego wiersza.
     */
   
@Insert
   
long insert(User user);

   
/**
     * Wstawia wielu użytkowników do bazy danych.
     *
@param user obiekty użytkowników do wstawienia.
     */
   
@Insert
   
void insertUsers(User ... user);

   
/**
     * Wstawia wielu użytkowników do bazy danych.
     *
@param users jest listą użytkowników do wstawienia.
     */
   
@Insert
   
void insertAll(List<User> users);

   
/**
     * Aktualizuje istniejącego użytkownika.
     *
@param user Użytkownik do zaktualizowania (zgodnie z jego ID).
     *
@return Liczba zaktualizowanych wierszy (zazwyczaj 1).
     */
   
@Update
   
int update(User user);

   
/**
     * Usuwa użytkownika z bazy danych.
     *
@param user Użytkownik do usunięcia.
     *
@return Liczba usuniętych wierszy (zazwyczaj 1).
     */
   
@Delete
   
int delete(User user);

   
// --- Metody zapytań
   
/**
     * Pobiera wszystkich użytkowników z tabeli "users".
     * Zwraca Listę obiektów User.
     */
   
@Query("SELECT * FROM users ORDER BY last_name ASC")
    List<User>
getAllUsersList();

   
/**
     * Pobiera wszystkich użytkowników z tabeli "users".
     * Zwraca LiveData, aby umożliwić reaktywne obserwowanie zmian w danych.
     */
   
@Query("SELECT * FROM users ORDER BY last_name ASC")
    LiveData<List<User>>
getAllUsers();

   
/**
     * Pobiera pojedynczego użytkownika na podstawie jego ID.
     *
@param userId ID użytkownika.
     *
@return Obiekt User lub null, jeśli nie znaleziono.
     */
   
@Query("SELECT * FROM users WHERE id = :userId")
    User
getUserById(int userId);

   
/**
     * Usuwa wszystkie rekordy z tabeli "users".
     */
   
@Query("DELETE FROM users")
   
void deleteAll();
}

 

IV. Room Database  

 

Utworzenie instancji bazy danych oraz wykorzystanie zadeklarowanych wcześniej zasobów:

 

Plik MainActivity.java

 

import android.os.Bundle;
import android.widget.TextView;
import androidx.appcompat.app.AppCompatActivity;
import androidx.room.Room;
import java.util.ArrayList;
import java.util.List;

public class MainActivity extends AppCompatActivity {

   
private TextView textView;

   
@Override
   
protected void onCreate(Bundle savedInstanceState) {
       
super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

       
textView = findViewById(R.id.textView);

 

         // Utworzenie obiektu db reprezentującego bazę danych „baza”
        AppDatabase
db = Room.databaseBuilder(getApplicationContext(),
                AppDatabase.class,
"baza").build();

        // Uchwyt do zasobów DAO
        UserDao
userDao = db.userDao();


       
new Thread(new Runnable() {
           
@Override
           
public void run() {

//                userDao.deleteAll();
               
User user1 = new User("Jan", "Ptak", 33);
               
userDao.insert(user1);
//
//                user1.setFirstName("Janusz");
//                user1.setId(1);
//                userDao.update(user1);

               
User user2 = new User("Wincenty", "Kowalski", 22);
                User user3 =
new User("Monika", "Nowak", 49);
               
userDao.insertUsers(user2, user3);

                User user4 =
new User("Mariola", "Zychowaska", 23);
                User user5 =
new User("Monika", "Nowakowska", 44);
                List<User> lista =
new ArrayList<>();
                lista.add(user4);
                lista.add(user5);
               
userDao.insertAll(lista);

                User userNew =
userDao.getUserById(1);
               
if (userNew!=null) {
                    String dane = userNew.toString();
                    runOnUiThread(() ->
textView.setText(dane));
                }

                List<User> users =
userDao.getAllUsersList();
               
for (User user: users) {
                    runOnUiThread(() ->
textView.append(user.toString()+"\n"));
                }

            }
        }).start();

    }
}

------------------------------------------------------------------------------------------

ü Łączenie danych z dwóch tabel

 

Tabela users:

Obraz zawierający tekst, zrzut ekranu, Czcionka

Zawartość wygenerowana przez AI może być niepoprawna.

 

Tabela Work:

 

 

Plik AppDatabase.java

 

import androidx.room.Database;
import androidx.room.RoomDatabase;

@Database(entities = {User.class, Work.class}, version = 4)
public abstract class AppDatabase extends RoomDatabase {
   
public abstract UserDao userDao();
}

 

 

Klasa Work.java

 

import androidx.room.Entity;
import androidx.room.PrimaryKey;

@Entity
public class Work{
   
@PrimaryKey(autoGenerate = true)
   
public int id;
   
public String  name;
   
public int id_user;
   
public Work(String  name, int id_user) {
       
this.name = name;
       
this.id_user = id_user;
    }
  }

 

Plik UserDao.java

//…należy dodać do istniejącego pliku

@Query("SELECT first_name, name FROM users INNER JOIN work ON users.id = work.id_user")
List<UserWork>
getUserWork();

 

 

Plik UserWork.java

 

public class UserWork {
   
public String first_name;
   
public String name;

}

 

Plik MainActivity.java

// ……

new Thread(new Runnable() {
   
@Override
   
public void run() {


        User user1 =
new User("Jan", "Kowalski", 33);
        User user2 =
new User("Janina", "Kowalski", 36);
        User user3 =
new User("Balbina", "Nowak", 41);
       
userDao.insertUsers(user1, user2, user3);

        Work work1 =
new Work("Sprzatanie", 2);
        Work work2 =
new Work("Pranie", 3);

       
userDao.insertWork(work1);
       
userDao.insertWork(work2);

        List<UserWork> userWorks =
userDao.getUserWork();
       
for (UserWork userWork : userWorks) {
            runOnUiThread(()->
textView.append(userWork.first_name + " " + userWork.name + "\n"));
        }
    }
}).start();

 

Obraz zawierający tekst, zrzut ekranu

Zawartość wygenerowana przez AI może być niepoprawna.

 

--------------------------------------------------------------------------------------------

ü Metoda wykorzystująca klasę SQLiteOpenHelper

 

Tworzenie i modyfikacja bazy danych wspierane jest przez klasę SQLiteOpenHelper.

Pusta klasa obsługująca bazę danych wygenerowana automatycznie poprzez narzędzia InteliJ Idea:

 

public class BazaDanych extends SQLiteOpenHelper{

   
public BazaDanych(Context context, String name, SQLiteDatabase.CursorFactory factory, int version) {
       
super(context, name, factory, version);
    }

   
@Override
   
public void onCreate(SQLiteDatabase db) {
    }

   
@Override
   
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {

    }
}

 

Stałe

Definicja stałych pozwala na zebranie wszystkich wykorzystywanych w bazie danych nazw tabel, kolumn, jak również samej bazy danych na początku klasy. W przypadku zmiany np. nazwy tabeli musimy tej zmiany dokonać raz przy deklaracji. Jest to dobry zwyczaj, który na dłuższą metę sprawia, iż zmiany dokonujemy w jednym miejscu zwiększając tym samym czytelność kodu.

Stała DATABASE_VERSION określa wersję bazy danych. Jeśli numer nie będzie się zgadzał z tym ostatnio użytym program wywoła metodę onUpdate co spowoduje zamianę istniejącej bazy na nową pusta w nowej wersji.

 

    private static final int DATABASE_VERSION = 1;

    private static final String DATABASE_NAME = "lista_zakupow";

    private static final String TABLE_ARTICLES = "baza_towarow";

 

    private static final String KEY_ID = "id";

    private static final String KEY_NAME = "name";

    private static final String KEY_CHECK = "checkk";

    private static final String KEY_NR_LIST = "nr_list";

 

 

Modyfikacja konstruktora

Ponieważ nazwa tabeli oraz wersja są zdefiniowane w klasie BazaDanych modyfikujemy konstruktor tak aby podczas wywoływania przekazywany był tyko kontekst klasy, w której tworzona jest instancja bazy danych. Kontekst to obiekt przechowujący informację o stanie obiektu. W naszym przypadku przekazujemy kontekst do aktywności, w której używać będziemy bazy danych. 

 

    public BazaDanych(Context context) {

        super(context, DATABASE_NAME, null, DATABASE_VERSION);

    }

 

Modyfikacja metody onCreate w klasie BazaDanych:

Metoda onCreate wywoływana jest na początku wtedy, gdy baza danych jeszcze nie istnieje. 

 

 String CREATE_CONTACTS_TABLE = "CREATE TABLE " + TABLE_ARTICLES + "("+

KEY_ID + " INTEGER PRIMARY KEY AUTOINCREMENT," +

KEY_NAME + " TEXT,"+

KEY_CHECK+ " INTEGER," +

KEY_NR_LIST+" INTEGER"+ ")";

 

        db.execSQL(CREATE_CONTACTS_TABLE);

 

Modyfikacja klasy onUpdate

onUpdate – metoda ściśle związana z wersją bazy danych. Zawarty tu kod powoduje usunięcie istniejącej tabeli oraz wywołując metody onCreate tworzy nową pustą. Zmieniając wartość stałej DATABASE_VERSION (przed kompilacją) musimy pamiętać o zrobieniu kopi tabeli. Najlepiej zrobić kopię całej bazy danych   

 

        db.execSQL("DROP TABLE IF EXISTS " + TABLE_ARTICLES);

        onCreate(db);

 

Pomocnicza klasa Towar

Klasa pomocna w organizowaniu danych zebranych w ramach jednego towaru.

 

public class Towar {

   
private String nazwa;
   
private boolean check=false;

   
public Towar(String nazwa, boolean check) {
       
super();
       
this.nazwa = nazwa;
       
this.check=check;
    }
   
public String getNazwa() {
       
return nazwa;
    }
   
public boolean isCheck() {
       
return check;
    }
   
public void setCheck(boolean check) {
       
this.check = check;
    }
   
public void setNazwa(String nazwa) {
       
this.nazwa = nazwa;
    }
}

 

Metoda dodająca dane do bazy danych:

 

public void dodajTowar(Towar towar, int nrListy) {
    SQLiteDatabase db =
this.getWritableDatabase();

    ContentValues values =
new ContentValues();

    values.put(KEY_NAME, towar.getNazwa());
    values.put(KEY_CHECK, towar.isCheck());
    values.put(KEY_NR_LIST, nrListy);

   
//db.insert(TABLE_ARTICLES, null, values);
   
db.insertOrThrow(TABLE_ARTICLES, null, values);

    db.close();
    Log.d(
">>>> Baza danych: ", "Dodano dane !!!");
}

 

Metoda usuwająca dane z bazy danych:

 

public void deleteTowar(Towar towar, int nrListy) {
    SQLiteDatabase db =
this.getWritableDatabase();
    db.delete(TABLE_ARTICLES, KEY_NAME +
" = ? and " + KEY_NR_LIST + " =?", new String[]{String.valueOf(towar.getNazwa()), "" + nrListy});
    db.close();
}

 

Metoda pobierająca dane z bazy danych w formie ciągu znaków:

 

public String getAllRecords(int nrListy) {
    SQLiteDatabase db =
this.getReadableDatabase();
    String string=
"";

    Cursor cursor = db.query(TABLE_ARTICLES,
null, KEY_NR_LIST + "=?",
           
new String[] { String.valueOf(nrListy) }, null, null, null, null);

    cursor.moveToFirst();
   
int nr=1;

   
do{
       
boolean check =false;
       
if(cursor.getInt(2)>1)
            check=
true;

        string+=nr+
". "+cursor.getString(1)+" "+check +"\n";
        nr++;
        Log.d(
">>>> Baza danych", "Pobrano dane: "+ string);
    }
while(cursor.moveToNext());
   
return string;
}

 

Metoda pobierająca dane z bazy danych w formie listy:

 

public int updateTowar(Towar towar, String staraNazwa, int nr_listy) {
    SQLiteDatabase db =
this.getWritableDatabase();

    ContentValues values =
new ContentValues();
    values.put(KEY_NAME, towar.getNazwa());

   
int check=0;
   
if(towar.isCheck()) check=1;
    values.put(KEY_CHECK, check);

   
return db.update(TABLE_ARTICLES, values, KEY_NAME + " = ? and "+KEY_NR_LIST+" =?" , new String[] {staraNazwa, ""+nr_listy});
}

 

Metoda aktualizująca dane w bazy danych:

 

public int updateTowar(Towar towar, String staraNazwa, int nr_listy) {
    SQLiteDatabase db =
this.getWritableDatabase();

    ContentValues values =
new ContentValues();
    values.put(KEY_NAME, towar.getNazwa());

   
int check=0;
   
if(towar.isCheck()) check=1;
    values.put(KEY_CHECK, check);

   
return db.update(TABLE_ARTICLES, values, KEY_NAME + " = ? and "+KEY_NR_LIST+" =?" , new String[] {staraNazwa, ""+nr_listy});
}

Przykładowa klasa Aktywności z jednym komponentem graficznym TextView wykorzystująca obiekt bazy danych (zapisywanie, pobieranie i wyświetlanie danych):

 

public class MainActivity extends AppCompatActivity {

   
@Override
   
protected void onCreate(Bundle savedInstanceState) {
       
super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        TextView textView = (TextView) findViewById(R.id.textView2);
        BazaDanych bazaDanych =
new BazaDanych(this);

        Towar towar1 =
new Towar("Mleko", false);
        bazaDanych.dodajTowar(towar1,
1);
        Towar towar2 =
new Towar("Maslo", false);
        bazaDanych.dodajTowar(towar2,
1);

        Towar towar3 =
new Towar("Woda", false);
        bazaDanych.dodajTowar(towar3,
2);
        Towar towar4 =
new Towar("Sok", false);
        bazaDanych.dodajTowar(towar4,
2);

        List<Towar> towarList =
new ArrayList<Towar>();
        towarList=bazaDanych.getAllTowary(
1);

       
for (int i = 0; i < towarList.size(); i++) {
            System.out.println(towarList.get(i));
            textView.append(towarList.get(i).getNazwa().toString()+” “+towarList.get(i).isCheck()+
"\n");
        }
    }

 

 

PRZYKŁADOWY PROGRAM:

 

                   Obraz zawierający gadżet, Urządzenie elektroniczne, multimedia, Komunikator

Zawartość wygenerowana przez AI może być niepoprawna.

 

Klasa BazaDanych:

 

import android.content.ContentValues;
import
android.content.Context;
import
android.database.Cursor;
import
android.database.sqlite.SQLiteDatabase;
import
android.database.sqlite.SQLiteOpenHelper;

public class
BazaDanych extends SQLiteOpenHelper {

   
private static final int DATABASE_VERSION = 2;
    private static final
String DATABASE_NAME = "lista_zakupow";
    private static final
String TABLE_ARTICLES = "baza_towarow";
    private static final
String KEY_ID = "id";
    private static final
String KEY_NAME = "name";
    private static final
String KEY_CHECK = "checkk";
    private static final
String KEY_NR_LIST = "nr_list";

    public
BazaDanych(Context context) {
       
super(context, DATABASE_NAME, null, DATABASE_VERSION);
   
}

   
@Override
   
public void onCreate(SQLiteDatabase db) {
        String CREATE_CONTACTS_TABLE =
"CREATE TABLE " + BazaDanych.TABLE_ARTICLES + "("+
                BazaDanych.KEY_ID
+ " INTEGER PRIMARY KEY AUTOINCREMENT," +
                BazaDanych.KEY_NAME
+ " TEXT,"+
                BazaDanych.KEY_CHECK+
" INTEGER," +
                BazaDanych.KEY_NR_LIST+
" INTEGER"+ ")";
       
db.execSQL(CREATE_CONTACTS_TABLE);
   
}

   
@Override
   
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        db.execSQL(
"DROP TABLE IF EXISTS " + TABLE_ARTICLES);
       
onCreate(db);
   
}

   
public void dodajTowar(Towar towar, int nrListy) {
        SQLiteDatabase db =
this.getWritableDatabase();
       
ContentValues values = new ContentValues();
       
values.put(KEY_NAME, towar.getNazwa());
       
values.put(KEY_CHECK, towar.isCheck());
       
values.put(KEY_NR_LIST, nrListy);
       
//db.insert(TABLE_ARTICLES, null, values);
       
db.insertOrThrow(TABLE_ARTICLES, null, values);
       
db.close();
    
}

   
public void deleteTowar(Towar towar, int nrListy) {

        SQLiteDatabase db =
this.getWritableDatabase();
       
db.delete(TABLE_ARTICLES, KEY_NAME + " = ? and " + KEY_NR_LIST + " =?", new String[]{String.valueOf(towar.getNazwa()), "" + nrListy});
       
db.close();
   
}

   
public String getAllRecords(int nrListy) {
        SQLiteDatabase db =
this.getReadableDatabase();
       
String string="";
       
Cursor cursor = db.query(TABLE_ARTICLES, null, KEY_NR_LIST + "=?",
                new
String[] { String.valueOf(nrListy) }, null, null, null, null);
       
cursor.moveToFirst();
        int
nr=1;
        do
{
           
boolean check =false;
            if
(cursor.getInt(2)>1)
                check=
true;
           
string+=nr+". "+cursor.getString(1)+" "+check +"\n";
           
nr++;
       
} while(cursor.moveToNext());
        return
string;
   
}
}

 

Klasa Towar:

 

public class Towar {

   
private String nazwa;
    private boolean
check=false;

    public
Towar(String nazwa, boolean check) {
       
super();
        this.nazwa
= nazwa;
        this.check
=check;
   
}

   
public String getNazwa() {
       
return nazwa;
   
}

   
public boolean isCheck() {
       
return check;
   
}

   
public void setCheck(boolean check) {
       
this.check = check;
   
}

   
public void setNazwa(String nazwa) {
       
this.nazwa = nazwa;
   
}
}

 

 

Klasa gówna MainActivity:

 

import androidx.appcompat.app.AppCompatActivity;

import
android.os.Bundle;
import
android.widget.TextView;

public class
MainActivity extends AppCompatActivity {

   
@Override
   
protected void onCreate(Bundle savedInstanceState) {
       
super.onCreate(savedInstanceState);
       
setContentView(R.layout.activity_main);

       
BazaDanych db = new BazaDanych(this);

      
Towar mleko = new Towar("Mleko", true);
       
db.dodajTowar(mleko, 1);
       
Towar chleb = new Towar("Chleb", true);
       
db.dodajTowar(chleb, 1);

       
String towary = db.getAllRecords(1);
       
TextView textViewTowar = (TextView)findViewById(R.id.textViewTowar);

       
textViewTowar.setText(towary);
   
}
}

 

plik 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"
   
xmlns:tools="http://schemas.android.com/tools"
   
android:layout_width="match_parent"
   
android:layout_height="match_parent"
   
android:background="#123"
   
tools:context=".MainActivity">

    <TextView
       
android:id="@+id/textView2"
       
android:layout_width="wrap_content"
       
android:layout_height="36dp"
       
android:layout_marginTop="16dp"
       
android:text="Lista zakupów"
        
android:textColor="#fff"
       
android:textSize="27dp"
       
app:layout_constraintBottom_toBottomOf="parent"
       
app:layout_constraintLeft_toLeftOf="parent"
       
app:layout_constraintRight_toRightOf="parent"
       
app:layout_constraintTop_toTopOf="parent"
       
app:layout_constraintVertical_bias="0.04000002" />

    <TextView
       
android:id="@+id/textViewTowar"
       
android:layout_width="0dp"
       
android:layout_height="0dp"
       
android:layout_marginTop="24dp"
       
android:layout_marginBottom="16dp"
       
android:text="TextView"
       
android:textSize="24dp"
       
android:textColor="#fff"
       
app:layout_constraintBottom_toBottomOf="parent"
       
app:layout_constraintEnd_toEndOf="parent"
       
app:layout_constraintStart_toStartOf="parent"
       
app:layout_constraintTop_toBottomOf="@+id/textView2" />

</androidx.constraintlayout.widget.ConstraintLayout>

 

-------------------------------------------------------------------

4. Zadania

 

Zadanie 1.

Napisz aplikację przechowującą i zarządzającą danymi studenta: imie, nazwisko, kierunek, rok_studiow. Wszystkie dane powinny być wprowadzane z widoku. Dostępne funkcje to: dodawanie, usuwanie, aktualizacja, pobieranie rekordów z poziomu interfejsu użytkownika. 

 

Zadanie 2.

Napisz aplikację, która pozwoli przechowywać dane w dwóch tabelach bazy danych o nazwie „serwis_komputerowy” .
Pierwsza tabela to „
naprawy”, w którym możemy zapisać takie dane, jak:

- nazwa_naprawy,

- cena,

- id_klienta.

 

Druga tabela to klient z następującymi polami:

- imie,

- nazwisko,

- pesel.

Zaprojektuj interfejs użytkownika, który pozwoli zarządzać danymi, tzn. wprowadzać dane do obu tabel oraz wyświetlać dane łącząc dwie tabele.