Przejdź do głównej treści
INF.04-01-21.06-SGCzerwiec 2021 · 24 kroki · ok. 70 min · 33 kryteria z klucza

Rozwiązanie krok po kroku: Aplikacja konsolowa i mobilna (Java + Android)

Rozwiązujemy arkusz z sortowaniem przez wybieranie i formularzem rejestracji konta w wersji Java + Android Studio. Ten sam arkusz CKE wydało w dwóch sesjach - czerwiec 2021 (INF.04-01-21.06-SG) i styczeń 2022 (INF.04-01-22.01-SG) - więc rozwiązanie jest jedno dla obu.

W konsoli klasa z tablicą dziesięciu liczb jako polem, prywatna metoda szukająca największej wartości i metoda sortująca tablicę malejąco przez wybieranie - bez gotowych funkcji sortowania. W aplikacji mobilnej formularz z adresem e-mail i dwoma polami hasła, który sprawdza znak @ i zgodność haseł. Do tego dokumentacja obu metod według wzoru z arkusza, zrzuty i dokument egzamin.

Kroki idą zdanie po zdaniu za treścią arkusza - każdy zaczyna się poleceniem z arkusza, a kod pokazuje dokładnie te linie, które je spełniają. Najpierw piszemy najprostszą wersję, której wymaga klucz, a w etapie „Dobre praktyki” poprawiamy to, czego klucz nie sprawdza.

Co widać w podglądzie. Wyniki programu konsolowego pochodzą z prawdziwego uruchomienia kodu z danego kroku (JDK 21) z liczbami wpisanymi z klawiatury, a posortowaną tablicę porównaliśmy z sortowaniem wykonanym niezależnie. Ekran telefonu to symulacja w przeglądarce zbudowana z pliku XML danego kroku; jej zachowanie odpowiada kodowi Javy z kroku - możesz wpisywać adres i hasła i klikać „ZATWIERDŹ”. Każdy stan aplikacji zbudowaliśmy też w Android Studio (Gradle) i sprawdziliśmy na emulatorze Pixel 8.

Arkusz pozwala też na C++, C# albo Pythona w konsoli i na .NET MAUI w części mobilnej - ten wariant to jedna z możliwych dróg.

Jak liczą się punkty. Klucz ma 33 kryteria (R.1.1 - R.4.9), każde za 1 punkt. Próg zdania części praktycznej to 75%, czyli 25 punktów - można stracić 8 kryteriów i nadal zdać. Przy każdym kroku jest napisane, które kryteria spełnia; egzaminator ocenia spełnienie kryteriów z klucza, nie zgodność z tym kodem.

  1. Etap 1: Przygotowanie

    Krok 1 · po tym etapie masz 0 z 33 kryteriów (pkt)

    Krok 1: Folder z numerem PESEL i trzy podfoldery

    ok. 2 min
    Polecenie z arkusza

    W folderze z numerem PESEL powinny się znajdować podfoldery dokumentacja, konsola, mobilna.

    Na pulpicie zakładamy folder o nazwie z numerem PESEL, a w nim konsola, mobilna i dokumentacja. W tym arkuszu do folderów aplikacji kopiujemy całe projekty, a zrzuty konsola.jpg, mobilna.jpg i dokument egzamin trafiają do folderu dokumentacja. Arkusz nie ma archiwum z materiałami.

  2. Etap 2: Aplikacja konsolowa

    Kroki 2-8 · po tym etapie masz 13 z 33 kryteriów (pkt)

    Krok 2: Projekt konsola w Javie

    ok. 3 min
    Polecenie z arkusza

    Napisz program sortujący tablicę metodą przez wybieranie według zamieszczonej dokumentacji. Program wykonywany w konsoli. Obiektowy język programowania zgodny z zainstalowanym na stanowisku egzaminacyjnym: C++ lub C# lub Java lub Python.

    Wybieramy Javę - tę samą, w której napiszemy aplikację mobilną. W IntelliJ IDEA: New Project → Java, nazwa konsola. Plik Main.java z metodą main uruchomi program; sortowanie umieścimy w osobnej klasie.

    konsola/src/Main.java Java nowy plik
    public class Main {
        public static void main(String[] args) {
        }
    }
  3. Krok 3: Klasa NumberSorter z tablicą 10 liczb jako polem

    Kryteria: , ,

    R.2.4 Program zawiera klasę, w której znajdują się: pole tablica 10-elementowa o typie całkowitym oraz przynajmniej dwie metody, metoda szukająca ma zasięg prywatny lub protected

    R.1.4 Nazewnictwo zmiennych jest znaczące. Wyjątkami od reguły są zmienne bufor, tmp, iteratory pętli itp. Kryterium nie jest spełnione tylko wtedy, gdy nazwy zmiennych nic nie znaczą, np. x, a, tab, fun

    R.1.5 Zastosowano typy zmiennych pasujące do problemu (np. dowolny typ całkowity dla tablicy; typ całkowity dla iteratora pętli; typ całkowity dla indeksu tablicy)

    ok. 3 min
    Polecenie z arkusza

    Sortowana jest tablica 10 liczb całkowitych. Tablica jest polem klasy.

    Nowa klasa w osobnym pliku (New → Java Class) - w Javie klasa publiczna musi mieć plik o tej samej nazwie. Tablica dziesięciu liczb całkowitych int[] jest polem klasy (R.2.4, R.1.5): istnieje tak długo jak obiekt, więc wszystkie metody klasy korzystają z tej samej tablicy bez przekazywania jej w parametrach. Pole jest prywatne - z zewnątrz klasy nikt jej nie podmieni.

    konsola/src/NumberSorter.java Java nowy plik
    public class NumberSorter {
        private int[] numbers = new int[10];
    }
  4. Krok 4: Wczytanie tablicy z klawiatury

    Kryteria: , ,

    R.1.7 Program po uruchomieniu podejmuje zrozumiałą interakcję z użytkownikiem. Widoczny jest komunikat o wprowadzeniu danych do tablicy. Jeżeli kod nie uruchamia się z powodu błędów kompilacji - sprawdzić w kodzie aplikacji

    R.2.5 Zapisano przynajmniej jedną pętlę wykonującą się na wszystkich n- elementach lub n-1 elementach tablicy

    R.1.3 Nazewnictwo funkcji jest znaczące

    ok. 3 min
    Polecenie z arkusza

    Tablica jest wczytywana z klawiatury po uprzednim wypisaniu odpowiedniego komunikatu.

    Metoda readNumbers w pętli po wszystkich elementach (R.2.5) wypisuje komunikat z numerem liczby i wczytuje ją Scanner-em (R.1.7). Warunek i < numbers.length zamiast i < 10 - pętla zawsze pasuje do rozmiaru tablicy. W main tworzymy obiekt i wywołujemy metodę.

    Podgląd to prawdziwe uruchomienie z dziesięcioma liczbami.

    konsola/src/Main.java Java zmienione: 2 linie
    public class Main {
        public static void main(String[] args) {
            NumberSorter sorter = new NumberSorter();
            sorter.readNumbers();
        }
    }
    konsola/src/NumberSorter.java Java zmienione: 10 linii
    import java.util.Scanner;
    
    public class NumberSorter {
        private int[] numbers = new int[10];
    
        public void readNumbers() {
            Scanner scanner = new Scanner(System.in);
            for (int i = 0; i < numbers.length; i++) {
                System.out.print("Podaj liczbę nr " + (i + 1) + ": ");
                numbers[i] = scanner.nextInt();
            }
        }
    }
    Wynik programu po tym kroku
    > java Main
    Podaj liczbę nr 1: 12
    Podaj liczbę nr 2: -4
    Podaj liczbę nr 3: 7
    Podaj liczbę nr 4: 33
    Podaj liczbę nr 5: 0
    Podaj liczbę nr 6: 7
    Podaj liczbę nr 7: 19
    Podaj liczbę nr 8: -15
    Podaj liczbę nr 9: 5
    Podaj liczbę nr 10: 28
  5. Krok 5: Prywatna metoda findMaxIndex

    Kryteria: , ,

    R.2.1 Program składa się z przynajmniej jednej metody: metody do sortowania lub metody szukania wartości maksymalnej w tablicy. Zawartość metody jest zgodna z jej przeznaczeniem. Dopuszcza się niedokończoną metodę, ale wskazującą na proces sortowania lub wyszukiwania

    R.2.2 Funkcja szukająca zwraca wartość maksymalną w tablicy lub zwraca indeks tej wartości

    R.2.4 Program zawiera klasę, w której znajdują się: pole tablica 10-elementowa o typie całkowitym oraz przynajmniej dwie metody, metoda szukająca ma zasięg prywatny lub protected

    ok. 3 min
    Polecenie z arkusza

    Klasa zawiera co najmniej dwie metody: sortującą i szukającą wartość najwyższą. Widzialność metody szukającej ogranicza się jedynie do klasy. Metoda szukająca zwraca wartość, w zależności od przyjętej taktyki może być to wartość maksymalna lub index wartości maksymalnej.

    Metoda szuka największej liczby od pozycji start do końca tablicy i zwraca jej indeks, a nie samą wartość - sortowanie będzie musiało wiedzieć, gdzie stoi maksimum, żeby zamienić je miejscami (R.2.2). Zaczynamy od założenia, że największa jest liczba na pozycji start, i porównujemy z kolejnymi.

    „Widzialność ogranicza się do klasy” to modyfikator private (R.2.4). Arkusz zabrania gotowych funkcji szukających maksimum, więc piszemy pętlę sami.

    konsola/src/NumberSorter.java Java zmienione: 10 linii
    import java.util.Scanner;
    
    public class NumberSorter {
        private int[] numbers = new int[10];
    
        public void readNumbers() {
            Scanner scanner = new Scanner(System.in);
            for (int i = 0; i < numbers.length; i++) {
                System.out.print("Podaj liczbę nr " + (i + 1) + ": ");
                numbers[i] = scanner.nextInt();
            }
        }
    
        private int findMaxIndex(int start) {
            int maxIndex = start;
            for (int i = start + 1; i < numbers.length; i++) {
                if (numbers[i] > numbers[maxIndex]) {
                    maxIndex = i;
                }
            }
            return maxIndex;
        }
    }

    Wynik programu bez zmian - taki jak po kroku 4.

  6. Krok 6: Sortowanie malejąco przez wybieranie

    Kryteria: , , ,

    R.2.3 Zastosowano algorytm sortowania przez wybieranie. Należy założyć że funkcja szukająca zwraca poprawną wartość

    R.2.5 Zapisano przynajmniej jedną pętlę wykonującą się na wszystkich n- elementach lub n-1 elementach tablicy

    R.2.6 Zapisano realizację zamiany miejscami wartości w tablicy, zastosowano do tego zmienną buforową lub w inny sposób, który nie powoduje utraty danych

    R.1.2 Kod zapisano z wcięciami dla zagłębień bloków

    ok. 4 min
    Polecenie z arkusza

    Algorytm przedstawia się następująco: wyszukaj minimalną wartość z tablicy spośród elementów od i do końca tablicy, zamień wartość minimalną, z elementem na pozycji i. Gdy zamiast wartości minimalnej wybierana będzie maksymalna, wówczas tablica będzie posortowana od największego do najmniejszego elementu. Sortowanie odbywa się malejąco, nie wykorzystuje gotowych funkcji do sortowania oraz do szukania maksimum.

    Algorytm z arkusza w wersji malejącej (R.2.3): dla każdej pozycji i szukamy największej liczby w części od i do końca i zamieniamy ją z liczbą na pozycji i. Po pierwszym obrocie największa liczba stoi na początku, po drugim - druga co do wielkości, i tak dalej. Ostatniej pozycji nie trzeba sprawdzać (została sama), stąd numbers.length - 1 obrotów (R.2.5).

    Zamiana wymaga zmiennej buforowej: numbers[i] = numbers[maxIndex] nadpisałoby wartość z pozycji i, więc najpierw odkładamy ją do buffer (R.2.6).

    Typowe błędy

    Zamiana bez bufora (numbers[i] = numbers[maxIndex]; numbers[maxIndex] = numbers[i];) gubi jedną z liczb - w tablicy pojawia się dwa razy maksimum.

    konsola/src/NumberSorter.java Java zmienione: 9 linii
    import java.util.Scanner;
    
    public class NumberSorter {
        private int[] numbers = new int[10];
    
        public void readNumbers() {
            Scanner scanner = new Scanner(System.in);
            for (int i = 0; i < numbers.length; i++) {
                System.out.print("Podaj liczbę nr " + (i + 1) + ": ");
                numbers[i] = scanner.nextInt();
            }
        }
    
        private int findMaxIndex(int start) {
            int maxIndex = start;
            for (int i = start + 1; i < numbers.length; i++) {
                if (numbers[i] > numbers[maxIndex]) {
                    maxIndex = i;
                }
            }
            return maxIndex;
        }
    
        public void sortDescending() {
            for (int i = 0; i < numbers.length - 1; i++) {
                int maxIndex = findMaxIndex(i);
                int buffer = numbers[i];
                numbers[i] = numbers[maxIndex];
                numbers[maxIndex] = buffer;
            }
        }
    }

    Wynik programu bez zmian - taki jak po kroku 4.

  7. Krok 7: Wypisanie posortowanej tablicy

    Kryteria: ,

    R.2.7 Program kompiluje się i uruchamia w konsoli. Po wczytaniu 10 elementów tablicy są one wyświetlone w kolejności malejącej

    R.1.1 Kod źródłowy zapisano w sposób czytelny: instrukcje w osobnych liniach, stosowane spacje pomiędzy operatorami, konsekwentnie stosowana wybrana konwencja dla nawiasów klamrowych instrukcji blokowej (wystarczy, że stosowane dla większości przypadków, należy pominąć pojedyncze odstępstwa od normy)

    ok. 2 min
    Polecenie z arkusza

    Wszystkie elementy posortowanej tablicy są wyświetlane na ekranie.

    printNumbers wypisuje tablicę w jednym wierszu pętlą for-each (for (int number : numbers) - kolejno każdy element, bez indeksu). W main po wczytaniu sortujemy i wypisujemy.

    Podgląd to prawdziwe uruchomienie: liczby wychodzą od największej do najmniejszej, także ujemne i powtórzona siódemka - wynik zgadza się z sortowaniem wykonanym niezależnie (R.2.7).

    konsola/src/Main.java Java zmienione: 2 linie
    public class Main {
        public static void main(String[] args) {
            NumberSorter sorter = new NumberSorter();
            sorter.readNumbers();
            sorter.sortDescending();
            sorter.printNumbers();
        }
    }
    konsola/src/NumberSorter.java Java zmienione: 8 linii
    import java.util.Scanner;
    
    public class NumberSorter {
        private int[] numbers = new int[10];
    
        public void readNumbers() {
            Scanner scanner = new Scanner(System.in);
            for (int i = 0; i < numbers.length; i++) {
                System.out.print("Podaj liczbę nr " + (i + 1) + ": ");
                numbers[i] = scanner.nextInt();
            }
        }
    
        private int findMaxIndex(int start) {
            int maxIndex = start;
            for (int i = start + 1; i < numbers.length; i++) {
                if (numbers[i] > numbers[maxIndex]) {
                    maxIndex = i;
                }
            }
            return maxIndex;
        }
    
        public void sortDescending() {
            for (int i = 0; i < numbers.length - 1; i++) {
                int maxIndex = findMaxIndex(i);
                int buffer = numbers[i];
                numbers[i] = numbers[maxIndex];
                numbers[maxIndex] = buffer;
            }
        }
    
        public void printNumbers() {
            System.out.print("Posortowana tablica: ");
            for (int number : numbers) {
                System.out.print(number + " ");
            }
            System.out.println();
        }
    }
    Wynik programu po tym kroku
    > java Main
    Podaj liczbę nr 1: 12
    Podaj liczbę nr 2: -4
    Podaj liczbę nr 3: 7
    Podaj liczbę nr 4: 33
    Podaj liczbę nr 5: 0
    Podaj liczbę nr 6: 7
    Podaj liczbę nr 7: 19
    Podaj liczbę nr 8: -15
    Podaj liczbę nr 9: 5
    Podaj liczbę nr 10: 28
    Posortowana tablica: 33 28 19 12 7 7 5 0 -4 -15
  8. Krok 8: Folder konsola

    ok. 2 min
    Polecenie z arkusza

    Kod aplikacji (cały folder projektu) przygotuj do nagrania na płytę (skopiuj do folderu z numerem PESEL, do podfolderu konsola).

    W tym arkuszu kopiujemy cały folder projektu do folderu konsola (bez pakowania do archiwum). Kopię robimy na końcu, po dopisaniu komentarzy z części III.

    Wynik programu bez zmian - taki jak po kroku 7.

  9. Etap 3: Aplikacja mobilna

    Kroki 9-18 · po tym etapie masz 23 z 33 kryteriów (pkt)

    Krok 9: Nowy projekt Rejestracja w Android Studio

    ok. 3 min
    Polecenie z arkusza

    Wykonaj aplikację mobilną za pomocą środowiska programistycznego dostępnego na stanowisku egzaminacyjnym oraz uruchom ją w dostępnym emulatorze systemu mobilnego.

    New Project → szablon Empty Views Activity (z widokami w XML - szablon Empty Activity tworzy projekt w Jetpack Compose, bez pliku układu). Nazwa Rejestracja, pakiet com.example.rejestracja, język Java. Będziemy zmieniać MainActivity.java (logika) i res/layout/activity_main.xml (wygląd).

    Szablon włącza tryb edge-to-edge: kod w onCreate dodaje do głównego widoku (R.id.main) odstępy od pasków systemowych.

    Rejestracja/app/src/main/java/com/example/rejestracja/MainActivity.java Java nowy plik
    package com.example.rejestracja;
    
    import android.os.Bundle;
    
    import androidx.activity.EdgeToEdge;
    import androidx.appcompat.app.AppCompatActivity;
    import androidx.core.graphics.Insets;
    import androidx.core.view.ViewCompat;
    import androidx.core.view.WindowInsetsCompat;
    
    public class MainActivity extends AppCompatActivity {
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            EdgeToEdge.enable(this);
            setContentView(R.layout.activity_main);
            ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main), (v, insets) -> {
                Insets systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars());
                v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom);
                return insets;
            });
        }
    }
    Rejestracja/app/src/main/res/layout/activity_main.xml XML nowy plik
    <?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:id="@+id/main"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".MainActivity">
    
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Hello World!"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent" />
    
    </androidx.constraintlayout.widget.ConstraintLayout>
    Ekran telefonu po tym kroku

    Symulacja ekranu w przeglądarce - w Android Studio / Visual Studio wygląd może się nieco różnić.

  10. Krok 10: Pionowy LinearLayout i napis Rejestruj konto

    Kryteria: , ,

    R.3.1 Zastosowano język znaczników XML/XAML lub inny do opisu interfejsu użytkownika oraz kod zawiera przynajmniej jeden element

    R.3.2 Zastosowano rozkład liniowy (np. StackLayout, LinearLayout lub inny o tej idei) Uwaga: jeżeli jest to możliwe uruchomić aplikację na tym samym urządzeniu, na którym uruchamiał zdający. Należy uwzględnić różnice pomiędzy emulacjami - takie cechy jak marginesy, wielkości bloków itp. nie bierzemy pod uwagę. Na emulacji może nie być widoczny cały ekran, przewinąć lub sprawdzić w kodzie, czy zawarto wszystkie wymagane elementy. Kryteria R.3.1 ÷ R.3.5 można sprawdzić w kodzie źródłowym oraz posiłkować się zrzutem ekranu, sprawdzane elementy muszą być zapisane zgodnie ze składnią. Gdy aplikacja nie uruchamia się, a zdający zapisał zrzut ekranu z uruchomienia aplikacji należy sprawdzić powód braku kompilacji. Jeśli występują błędy w plikach źródłowych zdającego kryteria 3.6 ÷ 3.10 nie są spełnione. Jeżeli błędy występują w innych plikach sprawdzić w kodzie oraz na zrzucie ekranu Uwaga: R.2.1 - R.2.6 należy sprawdzić w kodzie programu, sprawdzane elementy muszą być zapisane zgodnie ze składnią.

    R.3.3 Zastosowano kontrolki: tekstu, pola edycyjnego, przycisku. Tekst "Rejestruj konto" ma biały kolor czcionki i kolor tła Teal (#008080), Tekst "Rejestruj konto" jest zapisany większą czcionką niż pozostałe

    ok. 3 min
    Polecenie z arkusza

    Interfejs użytkownika zapisany za pomocą języka znaczników wspieranego w danym środowisku (np. XAML, XML). Zastosowany typ rozkładu liniowy (Linear / Stack lub inny o tej idei). Napis „Rejestruj konto”. Zastosowany kolor tła dla napisu „Rejestruj konto”: Teal (#008080), zgodnie z Obrazem 1a. Czcionka napisu „Rejestruj konto” jest wizualnie większa od pozostałych.

    W widoku Code zamieniamy ConstraintLayout na LinearLayout pionowy (R.3.1, R.3.2) - formularz to elementy jeden pod drugim. Zostawiamy android:id="@+id/main", którego szuka kod szablonu.

    Pierwszy element: TextView „Rejestruj konto” na całą szerokość, z tłem Teal #008080, białym tekstem i czcionką 24sp - większą od pozostałych napisów (domyślnie 14sp) (R.3.3).

    Typowe błędy

    Usunięcie android:id="@+id/main" razem ze starym układem kończy się awarią przy starcie - findViewById(R.id.main) zwraca null.

    Rejestracja/app/src/main/res/layout/activity_main.xml XML zmienione: 9 linii
    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:id="@+id/main"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        tools:context=".MainActivity">
    
        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:background="#008080"
            android:padding="4dp"
            android:text="Rejestruj konto"
            android:textColor="#FFFFFF"
            android:textSize="24sp" />
    
    </LinearLayout>
    Ekran telefonu po tym kroku

    Symulacja ekranu w przeglądarce - w Android Studio / Visual Studio wygląd może się nieco różnić.

  11. Krok 11: Napis Podaj e-mail i pole z podpowiedzią

    Kryteria: ,

    R.3.3 Zastosowano kontrolki: tekstu, pola edycyjnego, przycisku. Tekst "Rejestruj konto" ma biały kolor czcionki i kolor tła Teal (#008080), Tekst "Rejestruj konto" jest zapisany większą czcionką niż pozostałe

    R.3.4 Pola edycyjne są rozciągnięte na całą szerokość ekranu. Pole do wprowadzenia adresu e-mail ma podpowiedź "email" (hint, placeholder). Pola do wpisywania hasła realizują ukrywanie hasła (typ password)

    ok. 3 min
    Polecenie z arkusza

    Napis „Podaj e-mail:”, a pod nim pole edycyjne z podpowiedzią o treści „email”. Zastosowany kolory czcionki: czarny i biały, zgodnie z Obrazem 1a. Pola edycyjne są rozciągnięte na całą szerokość ekranu.

    Etykieta (TextView, czarny tekst) i pod nią pole edycyjne EditText:

    • layout_width="match_parent" - pole na całą szerokość ekranu (R.3.4),
    • android:hint="email" - podpowiedź widoczna, dopóki pole jest puste (R.3.4),
    • inputType="textEmailAddress" - klawiatura telefonu pokaże od razu znak @,
    • identyfikator emailInput - po nim odczytamy wpisany adres.
    Rejestracja/app/src/main/res/layout/activity_main.xml XML zmienione: 14 linii
    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:id="@+id/main"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        tools:context=".MainActivity">
    
        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:background="#008080"
            android:padding="4dp"
            android:text="Rejestruj konto"
            android:textColor="#FFFFFF"
            android:textSize="24sp" />
    
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="8dp"
            android:text="Podaj e-mail:"
            android:textColor="#000000" />
    
        <EditText
            android:id="@+id/emailInput"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:hint="email"
            android:inputType="textEmailAddress" />
    
    </LinearLayout>
    Ekran telefonu po tym kroku

    Symulacja ekranu w przeglądarce - w Android Studio / Visual Studio wygląd może się nieco różnić.

  12. Krok 12: Dwa pola hasła z ukrywaniem znaków

    Kryteria:

    R.3.4 Pola edycyjne są rozciągnięte na całą szerokość ekranu. Pole do wprowadzenia adresu e-mail ma podpowiedź "email" (hint, placeholder). Pola do wpisywania hasła realizują ukrywanie hasła (typ password)

    ok. 2 min
    Polecenie z arkusza

    Napis „Podaj hasło:”, a pod nim pole edycyjne do wprowadzenia hasła, realizuje ukrywanie hasła jak na obrazach 1a i 1b. Napis „Powtórz hasło:”, a pod nim pole edycyjne do wprowadzenia hasła, realizuje ukrywanie hasła jak na obrazach 1a i 1b.

    Dwie pary etykieta + pole w tym samym stylu. Ukrywanie znaków daje android:inputType="textPassword" - zamiast liter pole pokazuje kropki (R.3.4). Wpisz coś w podglądzie. Pola mają osobne identyfikatory: passwordInput i repeatPasswordInput.

    Rejestracja/app/src/main/res/layout/activity_main.xml XML zmienione: 26 linii
    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:id="@+id/main"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        tools:context=".MainActivity">
    
        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:background="#008080"
            android:padding="4dp"
            android:text="Rejestruj konto"
            android:textColor="#FFFFFF"
            android:textSize="24sp" />
    
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="8dp"
            android:text="Podaj e-mail:"
            android:textColor="#000000" />
    
        <EditText
            android:id="@+id/emailInput"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:hint="email"
            android:inputType="textEmailAddress" />
    
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="8dp"
            android:text="Podaj hasło:"
            android:textColor="#000000" />
    
        <EditText
            android:id="@+id/passwordInput"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:inputType="textPassword" />
    
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="8dp"
            android:text="Powtórz hasło:"
            android:textColor="#000000" />
    
        <EditText
            android:id="@+id/repeatPasswordInput"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:inputType="textPassword" />
    
    </LinearLayout>
    Ekran telefonu po tym kroku

    Symulacja ekranu w przeglądarce - w Android Studio / Visual Studio wygląd może się nieco różnić.

  13. Krok 13: Przycisk ZATWIERDŹ i obszar komunikatów

    Kryteria: , ,

    R.3.3 Zastosowano kontrolki: tekstu, pola edycyjnego, przycisku. Tekst "Rejestruj konto" ma biały kolor czcionki i kolor tła Teal (#008080), Tekst "Rejestruj konto" jest zapisany większą czcionką niż pozostałe

    R.3.6 Aplikacja kompiluje się i uruchamia w emulatorze, jej wygląd jest zgodny z obrazem 1 w arkuszu egzaminacyjnym. Zawiera wszystkie elementy. Przycisk i pole komunikatów są wyśrodkowane

    R.3.7 W stanie początkowym aplikacji pod przyciskiem jest wyświetlany numer PESEL zdającego

    ok. 2 min
    Polecenie z arkusza

    Przycisk o treści „ZATWIERDŹ”, jest on wyśrodkowany. Obszar do wyświetlania komunikatów, jest on wyśrodkowany. W obszarze do wyświetlania komunikatów pojawia się napis: Na początku działania aplikacji: „Autor”, dalej wstawiony numer PESEL zdającego.

    Przycisk i TextView na komunikaty, oba wyśrodkowane w poziomie atrybutem layout_gravity="center_horizontal". Komunikat ma na starcie tekst „Autor” i numer zdającego - na egzaminie numer PESEL, tu Bartosz Bryniarski (R.3.7). Ekran ma już wszystkie elementy z obrazu 1a (R.3.6).

    Rejestracja/app/src/main/res/layout/activity_main.xml XML zmienione: 15 linii
    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:id="@+id/main"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        tools:context=".MainActivity">
    
        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:background="#008080"
            android:padding="4dp"
            android:text="Rejestruj konto"
            android:textColor="#FFFFFF"
            android:textSize="24sp" />
    
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="8dp"
            android:text="Podaj e-mail:"
            android:textColor="#000000" />
    
        <EditText
            android:id="@+id/emailInput"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:hint="email"
            android:inputType="textEmailAddress" />
    
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="8dp"
            android:text="Podaj hasło:"
            android:textColor="#000000" />
    
        <EditText
            android:id="@+id/passwordInput"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:inputType="textPassword" />
    
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="8dp"
            android:text="Powtórz hasło:"
            android:textColor="#000000" />
    
        <EditText
            android:id="@+id/repeatPasswordInput"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:inputType="textPassword" />
    
        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center_horizontal"
            android:layout_marginTop="16dp"
            android:text="ZATWIERDŹ" />
    
        <TextView
            android:id="@+id/messageText"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center_horizontal"
            android:layout_marginTop="8dp"
            android:text="Autor Bartosz Bryniarski" />
    
    </LinearLayout>
    Ekran telefonu po tym kroku

    Symulacja ekranu w przeglądarce - w Android Studio / Visual Studio wygląd może się nieco różnić.

  14. Krok 14: Kontrolki w polach aktywności i metoda confirm

    Kryteria:

    R.3.5 Obsłużono przycisk za pomocą zdarzenia onClick. Po jego wciśnięciu wywoływana jest funkcja obsługująca zdarzenie

    ok. 3 min
    Polecenie z arkusza

    Po wybraniu przycisku ZATWIERDŹ jest sprawdzane: Czy e-mail zawiera znak @. Czy podane hasło jest równe powtórzonemu hasłu.

    Trzy pola edycyjne i obszar komunikatów zapisujemy w polach aktywności i wypełniamy w onCreate metodą findViewById - szuka widoku po identyfikatorze z XML.

    Kliknięcie wiążemy w XML atrybutem android:onClick="confirm": Android wywoła publiczną metodę confirm(View view) aktywności (R.3.5). Na razie jest pusta - sprawdzenia dopiszemy w kolejnych krokach.

    Typowe błędy

    Literówka w nazwie metody w android:onClick kompiluje się, ale aplikacja zamyka się przy pierwszym kliknięciu.

    Rejestracja/app/src/main/java/com/example/rejestracja/MainActivity.java Java zmienione: 16 linii
    package com.example.rejestracja;
    
    import android.os.Bundle;
    import android.view.View;
    import android.widget.EditText;
    import android.widget.TextView;
    
    import androidx.activity.EdgeToEdge;
    import androidx.appcompat.app.AppCompatActivity;
    import androidx.core.graphics.Insets;
    import androidx.core.view.ViewCompat;
    import androidx.core.view.WindowInsetsCompat;
    
    public class MainActivity extends AppCompatActivity {
    
        private EditText emailInput;
        private EditText passwordInput;
        private EditText repeatPasswordInput;
        private TextView messageText;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            EdgeToEdge.enable(this);
            setContentView(R.layout.activity_main);
            ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main), (v, insets) -> {
                Insets systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars());
                v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom);
                return insets;
            });
    
            emailInput = findViewById(R.id.emailInput);
            passwordInput = findViewById(R.id.passwordInput);
            repeatPasswordInput = findViewById(R.id.repeatPasswordInput);
            messageText = findViewById(R.id.messageText);
        }
    
        public void confirm(View view) {
        }
    }
    Rejestracja/app/src/main/res/layout/activity_main.xml XML zmienione: 1 linia
    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:id="@+id/main"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        tools:context=".MainActivity">
    
        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:background="#008080"
            android:padding="4dp"
            android:text="Rejestruj konto"
            android:textColor="#FFFFFF"
            android:textSize="24sp" />
    
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="8dp"
            android:text="Podaj e-mail:"
            android:textColor="#000000" />
    
        <EditText
            android:id="@+id/emailInput"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:hint="email"
            android:inputType="textEmailAddress" />
    
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="8dp"
            android:text="Podaj hasło:"
            android:textColor="#000000" />
    
        <EditText
            android:id="@+id/passwordInput"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:inputType="textPassword" />
    
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="8dp"
            android:text="Powtórz hasło:"
            android:textColor="#000000" />
    
        <EditText
            android:id="@+id/repeatPasswordInput"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:inputType="textPassword" />
    
        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center_horizontal"
            android:layout_marginTop="16dp"
            android:onClick="confirm"
            android:text="ZATWIERDŹ" />
    
        <TextView
            android:id="@+id/messageText"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center_horizontal"
            android:layout_marginTop="8dp"
            android:text="Autor Bartosz Bryniarski" />
    
    </LinearLayout>
    Ekran telefonu po tym kroku

    Symulacja ekranu w przeglądarce - w Android Studio / Visual Studio wygląd może się nieco różnić.

  15. Krok 15: Sprawdzenie znaku @ w adresie

    Kryteria:

    R.3.8 Po wybraniu przycisku, gdy email nie zawiera znaku '@', wyświetlany jest komunikat "Nieprawidłowy adres e-mail"

    ok. 2 min
    Polecenie z arkusza

    Po zatwierdzeniu, gdy e-mail jest niepoprawny: „Nieprawidłowy adres e-mail”.

    getText() pola edycyjnego zwraca obiekt tekstu (Editable), a toString() zamienia go na zwykły String. Metoda contains("@") odpowiada, czy napis zawiera znak @; wykrzyknik zaprzecza warunek. Brak @ - komunikat z arkusza (R.3.8). Wpisz w podglądzie ewa.poczta.pl i kliknij „ZATWIERDŹ”.

    Rejestracja/app/src/main/java/com/example/rejestracja/MainActivity.java Java zmienione: 4 linie
    package com.example.rejestracja;
    
    import android.os.Bundle;
    import android.view.View;
    import android.widget.EditText;
    import android.widget.TextView;
    
    import androidx.activity.EdgeToEdge;
    import androidx.appcompat.app.AppCompatActivity;
    import androidx.core.graphics.Insets;
    import androidx.core.view.ViewCompat;
    import androidx.core.view.WindowInsetsCompat;
    
    public class MainActivity extends AppCompatActivity {
    
        private EditText emailInput;
        private EditText passwordInput;
        private EditText repeatPasswordInput;
        private TextView messageText;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            EdgeToEdge.enable(this);
            setContentView(R.layout.activity_main);
            ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main), (v, insets) -> {
                Insets systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars());
                v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom);
                return insets;
            });
    
            emailInput = findViewById(R.id.emailInput);
            passwordInput = findViewById(R.id.passwordInput);
            repeatPasswordInput = findViewById(R.id.repeatPasswordInput);
            messageText = findViewById(R.id.messageText);
        }
    
        public void confirm(View view) {
            String email = emailInput.getText().toString();
            if (!email.contains("@")) {
                messageText.setText("Nieprawidłowy adres e-mail");
            }
        }
    }
    Ekran telefonu po tym kroku

    Symulacja ekranu w przeglądarce - w Android Studio / Visual Studio wygląd może się nieco różnić.

  16. Krok 16: Sprawdzenie zgodności haseł

    Kryteria:

    R.3.9 Po wybraniu przycisku, gdy hasła się różnią, wyświetlany jest komunikat "Hasła się różnią"

    ok. 2 min
    Polecenie z arkusza

    Po zatwierdzeniu, gdy hasła się różnią: „Hasła się różnią”.

    Napisy w Javie porównujemy metodą equals - operator == porównałby, czy to ten sam obiekt w pamięci, a dwa pola zawsze dają dwa różne obiekty, nawet z tymi samymi literami (R.3.9). Gałąź else if sprawdza hasła dopiero wtedy, gdy adres jest poprawny.

    Typowe błędy

    password == repeatedPassword jest zawsze fałszywe dla tekstów z dwóch pól - aplikacja zawsze odpowie „Hasła się różnią”.

    Rejestracja/app/src/main/java/com/example/rejestracja/MainActivity.java Java zmienione: 4 linie
    package com.example.rejestracja;
    
    import android.os.Bundle;
    import android.view.View;
    import android.widget.EditText;
    import android.widget.TextView;
    
    import androidx.activity.EdgeToEdge;
    import androidx.appcompat.app.AppCompatActivity;
    import androidx.core.graphics.Insets;
    import androidx.core.view.ViewCompat;
    import androidx.core.view.WindowInsetsCompat;
    
    public class MainActivity extends AppCompatActivity {
    
        private EditText emailInput;
        private EditText passwordInput;
        private EditText repeatPasswordInput;
        private TextView messageText;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            EdgeToEdge.enable(this);
            setContentView(R.layout.activity_main);
            ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main), (v, insets) -> {
                Insets systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars());
                v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom);
                return insets;
            });
    
            emailInput = findViewById(R.id.emailInput);
            passwordInput = findViewById(R.id.passwordInput);
            repeatPasswordInput = findViewById(R.id.repeatPasswordInput);
            messageText = findViewById(R.id.messageText);
        }
    
        public void confirm(View view) {
            String email = emailInput.getText().toString();
            String password = passwordInput.getText().toString();
            String repeatedPassword = repeatPasswordInput.getText().toString();
            if (!email.contains("@")) {
                messageText.setText("Nieprawidłowy adres e-mail");
            } else if (!password.equals(repeatedPassword)) {
                messageText.setText("Hasła się różnią");
            }
        }
    }
    Ekran telefonu po tym kroku

    Symulacja ekranu w przeglądarce - w Android Studio / Visual Studio wygląd może się nieco różnić.

  17. Krok 17: Powitanie po poprawnym zatwierdzeniu

    Kryteria:

    R.3.10 Po wybraniu przycisku, gdy email jest poprawny i hasła są takie same, wyświetlany jest komunikat "Witaj <e-mail>”, gdzie <e-mail> oznacza aktualnie wprowadzony adres e-mail

    ok. 2 min
    Polecenie z arkusza

    Po zatwierdzeniu, gdy nie wystąpiły błędy: „Witaj <e-mail>”, gdzie <e-mail> oznacza aktualnie wprowadzony adres e-mail.

    Ostatnia gałąź else: adres ma @, hasła są równe - wypisujemy powitanie z adresem (R.3.10). Sprawdź w podglądzie wszystkie trzy przypadki: adres bez @, różne hasła i dane poprawne (obraz 1a).

    Rejestracja/app/src/main/java/com/example/rejestracja/MainActivity.java Java zmienione: 2 linie
    package com.example.rejestracja;
    
    import android.os.Bundle;
    import android.view.View;
    import android.widget.EditText;
    import android.widget.TextView;
    
    import androidx.activity.EdgeToEdge;
    import androidx.appcompat.app.AppCompatActivity;
    import androidx.core.graphics.Insets;
    import androidx.core.view.ViewCompat;
    import androidx.core.view.WindowInsetsCompat;
    
    public class MainActivity extends AppCompatActivity {
    
        private EditText emailInput;
        private EditText passwordInput;
        private EditText repeatPasswordInput;
        private TextView messageText;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            EdgeToEdge.enable(this);
            setContentView(R.layout.activity_main);
            ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main), (v, insets) -> {
                Insets systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars());
                v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom);
                return insets;
            });
    
            emailInput = findViewById(R.id.emailInput);
            passwordInput = findViewById(R.id.passwordInput);
            repeatPasswordInput = findViewById(R.id.repeatPasswordInput);
            messageText = findViewById(R.id.messageText);
        }
    
        public void confirm(View view) {
            String email = emailInput.getText().toString();
            String password = passwordInput.getText().toString();
            String repeatedPassword = repeatPasswordInput.getText().toString();
            if (!email.contains("@")) {
                messageText.setText("Nieprawidłowy adres e-mail");
            } else if (!password.equals(repeatedPassword)) {
                messageText.setText("Hasła się różnią");
            } else {
                messageText.setText("Witaj " + email);
            }
        }
    }
    Ekran telefonu po tym kroku

    Symulacja ekranu w przeglądarce - w Android Studio / Visual Studio wygląd może się nieco różnić.

  18. Krok 18: Uruchomienie w emulatorze i folder mobilna

    Kryteria:

    R.3.6 Aplikacja kompiluje się i uruchamia w emulatorze, jej wygląd jest zgodny z obrazem 1 w arkuszu egzaminacyjnym. Zawiera wszystkie elementy. Przycisk i pole komunikatów są wyśrodkowane

    ok. 3 min
    Polecenie z arkusza

    Kod aplikacji (cały folder projektu) przygotuj do nagrania na płytę (skopiuj do folderu z numerem PESEL, do podfolderu mobilna).

    Uruchamiamy aplikację zielonym trójkątem Run w emulatorze, wpisujemy dane i zatwierdzamy. Cały folder projektu Rejestracja kopiujemy do folderu mobilna.

    Ekran telefonu bez zmian - taki jak po kroku 17.

  19. Etap 4: Dokumentacja

    Kroki 19-21 · po tym etapie masz 33 z 33 kryteriów (pkt)

    Krok 19: Nagłówki metod sortującej i szukającej według listingu 1

    Kryteria: , , , ,

    R.4.1 Obie metody z aplikacji konsolowej mają nagłówek utworzony w postaci komentarza zgodny z Listingiem 1 z arkusza egzaminacyjnego

    R.4.2 W komentarzu ujęto nazwę funkcji i nazwy parametru(ów) funkcji zgodne ze stanem faktycznym (brak - w przypadku braku parametrów)

    R.4.3 W komentarzu do metody wyszukującej element maksymalny opisano co przechowuje parametr wejściowy

    R.4.4 W komentarzu opisano co zwraca funkcja (brak dla metody o typie void)

    R.4.5 W komentarzu ujęto numer PESEL zdającego

    ok. 5 min
    Polecenie z arkusza

    W kodzie źródłowym aplikacji konsolowej utwórz nagłówek metody sortującej i szukającej, według wzoru umieszczonego w listingu 1. Nagłówek powinien znaleźć się w kodzie źródłowym nad metodą. W miejscu nawiasów <> należy podać nazwę funkcji, nazwy parametrów (lub słowo „brak”) oraz zwięzłe informacje (kilka słów) – zgodnie ze wzorcem. W miejscu autor należy podać swój numer PESEL.

    Dwa komentarze w formacie listingu 1, każdy nad swoją metodą (R.4.1): nazwa metody i jej parametry - przy sortowaniu słowo „brak” (R.4.2), przy szukaniu opis tego, co przechowuje parametr start (R.4.3), opis wartości zwracanej - przy metodzie void „brak” (R.4.4) - i autor (R.4.5). Na egzaminie w polu autor wpisujemy numer PESEL - tu stoi Bartosz Bryniarski.

    konsola/src/NumberSorter.java Java zmienione: 12 linii
    import java.util.Scanner;
    
    public class NumberSorter {
        private int[] numbers = new int[10];
    
        public void readNumbers() {
            Scanner scanner = new Scanner(System.in);
            for (int i = 0; i < numbers.length; i++) {
                System.out.print("Podaj liczbę nr " + (i + 1) + ": ");
                numbers[i] = scanner.nextInt();
            }
        }
    
        /********************************************************
         * nazwa funkcji:       findMaxIndex
         * parametry wejściowe: start - indeks, od którego szukamy największej liczby do końca tablicy
         * wartość zwracana:    indeks największej liczby w tablicy numbers od pozycji start
         * autor:               Bartosz Bryniarski
         * ****************************************************/
        private int findMaxIndex(int start) {
            int maxIndex = start;
            for (int i = start + 1; i < numbers.length; i++) {
                if (numbers[i] > numbers[maxIndex]) {
                    maxIndex = i;
                }
            }
            return maxIndex;
        }
    
        /********************************************************
         * nazwa funkcji:       sortDescending
         * parametry wejściowe: brak
         * wartość zwracana:    brak - sortuje malejąco tablicę numbers (pole klasy) przez wybieranie
         * autor:               Bartosz Bryniarski
         * ****************************************************/
        public void sortDescending() {
            for (int i = 0; i < numbers.length - 1; i++) {
                int maxIndex = findMaxIndex(i);
                int buffer = numbers[i];
                numbers[i] = numbers[maxIndex];
                numbers[maxIndex] = buffer;
            }
        }
    
        public void printNumbers() {
            System.out.print("Posortowana tablica: ");
            for (int number : numbers) {
                System.out.print(number + " ");
            }
            System.out.println();
        }
    }
    Wynik programu po tym kroku
    > java Main
    Podaj liczbę nr 1: 12
    Podaj liczbę nr 2: -4
    Podaj liczbę nr 3: 7
    Podaj liczbę nr 4: 33
    Podaj liczbę nr 5: 0
    Podaj liczbę nr 6: 7
    Podaj liczbę nr 7: 19
    Podaj liczbę nr 8: -15
    Podaj liczbę nr 9: 5
    Podaj liczbę nr 10: 28
    Posortowana tablica: 33 28 19 12 7 7 5 0 -4 -15
  20. Krok 20: Zrzuty konsola.jpg i mobilna.jpg

    Kryteria: , ,

    R.1.6 Podjęto próbę skompilowania kodu, co udokumentowano obrazem przedstawiającym wykonywany program lub jego kompilację

    R.4.6 Zapisano przynajmniej jeden zrzut ekranu z uruchomienia lub kompilacji aplikacji konsolowej, na zrzucie widoczne jest środowisko, w którym powstała aplikacja

    R.4.7 Zapisano przynajmniej jeden zrzut ekranu z uruchomienia lub kompilacji aplikacji mobilnej, na zrzucie widoczne jest środowisko, w którym powstała aplikacja

    ok. 3 min
    Polecenie z arkusza

    Wykonaj zrzuty ekranu dokumentujące uruchomienie aplikacji. Zrzuty powinny obejmować cały obszar ekranu z widocznym paskiem zadań. Wymagane zrzuty ekranu: z aplikacji konsolowej – konsola.jpg, z aplikacji mobilnej – mobilna.jpg.

    Dwa zrzuty całego ekranu ze środowiskiem w tle, zapisane w formacie JPG pod nazwami z arkusza: konsola.jpg (IntelliJ z wynikiem sortowania) i mobilna.jpg (Android Studio z emulatorem i komunikatem) - do folderu dokumentacja (R.1.6, R.4.6, R.4.7).

    Wynik programu bez zmian - taki jak po kroku 19.

  21. Krok 21: Dokument egzamin

    Kryteria: ,

    R.4.8 W edytorze tekstu pakietu biurowego utworzono dokumentację w pliku, pod nazwą egzamin, która zawiera wklejone zrzuty ekranu wraz z podpisami zgodnymi z prawdą

    R.4.9 Dokumentacja zawiera: nazwę systemu operacyjnego, nazwy środowisk, nazwy języków programowania, nazwę emulowanego urządzenia lub systemu, które są zgodne z tymi udokumentowanymi na zrzutach

    ok. 3 min
    Polecenie z arkusza

    W edytorze tekstu pakietu biurowego utwórz plik z dokumentacją i nazwij go egzamin. Dokument powinien zawierać podpisane zrzuty ekranu oraz zapisane informacje: nazwę systemu operacyjnego, na którym pracował zdający, nazwy środowisk programistycznych, z których zdający korzystał na egzaminie, nazwy języków programowania użytych podczas tworzenia aplikacji, nazwę emulowanego urządzenia lub systemu, na którym uruchomiono aplikację mobilną, opcjonalnie komentarz do wykonanej pracy.

    W Wordzie albo Writerze dokument egzamin w folderze dokumentacja: oba zrzuty wklejone i podpisane zgodnie z tym, co pokazują (R.4.8), a pod nimi system, środowiska, języki i nazwa emulowanego urządzenia (R.4.9).

    egzamin.txt Tekst nowy plik
    Zrzuty ekranu: konsola.jpg - posortowana tablica w IntelliJ IDEA; mobilna.jpg - aplikacja Rejestracja w emulatorze po zatwierdzeniu poprawnych danych
    System operacyjny: Windows 11
    Środowiska programistyczne: IntelliJ IDEA (aplikacja konsolowa), Android Studio (aplikacja mobilna)
    Języki programowania: Java (aplikacja konsolowa i mobilna), XML (układ aplikacji mobilnej)
    Emulowane urządzenie: Pixel 8 (Android 16, API 36)

    Wynik programu bez zmian - taki jak po kroku 19.

  22. Etap 5: Dobre praktyki (poza kluczem)

    Kroki 22-23 · po tym etapie masz 33 z 33 kryteriów (pkt)

    Krok 22: Konsola: odporność na tekst zamiast liczby

    ok. 3 min
    Polecenie z arkusza

    Tablica jest wczytywana z klawiatury po uprzednim wypisaniu odpowiedniego komunikatu.

    scanner.nextInt() na słowie „siedem” albo na liczbie z przecinkiem rzuca wyjątek InputMismatchException i kończy program. Pętla while (!scanner.hasNextInt()) sprawdza, czy następne słowo jest liczbą całkowitą; jeśli nie, pomija je i prosi ponownie o tę samą liczbę.

    Na egzaminie wystarczy wersja wcześniejsza - klucz tego nie sprawdza.

    konsola/src/NumberSorter.java Java zmienione: 4 linie
    import java.util.Scanner;
    
    public class NumberSorter {
        private int[] numbers = new int[10];
    
        public void readNumbers() {
            Scanner scanner = new Scanner(System.in);
            for (int i = 0; i < numbers.length; i++) {
                System.out.print("Podaj liczbę nr " + (i + 1) + ": ");
                while (!scanner.hasNextInt()) {
                    scanner.next();   // pomijamy słowo, które nie jest liczbą całkowitą
                    System.out.print("To nie jest liczba całkowita. Podaj liczbę nr " + (i + 1) + ": ");
                }
                numbers[i] = scanner.nextInt();
            }
        }
    
        /********************************************************
         * nazwa funkcji:       findMaxIndex
         * parametry wejściowe: start - indeks, od którego szukamy największej liczby do końca tablicy
         * wartość zwracana:    indeks największej liczby w tablicy numbers od pozycji start
         * autor:               Bartosz Bryniarski
         * ****************************************************/
        private int findMaxIndex(int start) {
            int maxIndex = start;
            for (int i = start + 1; i < numbers.length; i++) {
                if (numbers[i] > numbers[maxIndex]) {
                    maxIndex = i;
                }
            }
            return maxIndex;
        }
    
        /********************************************************
         * nazwa funkcji:       sortDescending
         * parametry wejściowe: brak
         * wartość zwracana:    brak - sortuje malejąco tablicę numbers (pole klasy) przez wybieranie
         * autor:               Bartosz Bryniarski
         * ****************************************************/
        public void sortDescending() {
            for (int i = 0; i < numbers.length - 1; i++) {
                int maxIndex = findMaxIndex(i);
                int buffer = numbers[i];
                numbers[i] = numbers[maxIndex];
                numbers[maxIndex] = buffer;
            }
        }
    
        public void printNumbers() {
            System.out.print("Posortowana tablica: ");
            for (int number : numbers) {
                System.out.print(number + " ");
            }
            System.out.println();
        }
    }
    Wynik programu po tym kroku
    > java Main
    Podaj liczbę nr 1: siedem
    To nie jest liczba całkowita. Podaj liczbę nr 1: 12
    Podaj liczbę nr 2: -4
    Podaj liczbę nr 3: 7
    Podaj liczbę nr 4: 33
    Podaj liczbę nr 5: 0
    Podaj liczbę nr 6: 7
    Podaj liczbę nr 7: 19
    Podaj liczbę nr 8: -15
    Podaj liczbę nr 9: 5
    Podaj liczbę nr 10: 28
    Posortowana tablica: 33 28 19 12 7 7 5 0 -4 -15
  23. Krok 23: Android: pełne sprawdzenie adresu, puste hasło, teksty w strings.xml

    ok. 4 min
    Polecenie z arkusza

    Aplikacja powinna być zapisana czytelnie, z zasadami czystego formatowania kodu, stosować znaczące nazwy zmiennych i funkcji.

    Wersja egzaminacyjna uznaje za adres każdy napis z @, np. @@ albo ewa@, i rejestruje konto z pustym hasłem. Poprawki:

    • Patterns.EMAIL_ADDRESS - gotowy wzorzec adresu e-mail z Androida (nazwa, @, domena z kropką); trim() usuwa przypadkowe spacje,
    • puste hasło dostaje osobny komunikat,
    • wszystkie komunikaty przenosimy do strings.xml (powitanie z miejscem %s na adres) - można je przetłumaczyć bez zmiany kodu, a Android Studio przestaje ostrzegać o tekstach na sztywno.

    Na egzaminie wystarczy wersja wcześniejsza - klucz wymaga tylko sprawdzenia znaku @.

    Rejestracja/app/src/main/java/com/example/rejestracja/MainActivity.java Java zmienione: 8 linii
    package com.example.rejestracja;
    
    import android.os.Bundle;
    import android.util.Patterns;
    import android.view.View;
    import android.widget.EditText;
    import android.widget.TextView;
    
    import androidx.activity.EdgeToEdge;
    import androidx.appcompat.app.AppCompatActivity;
    import androidx.core.graphics.Insets;
    import androidx.core.view.ViewCompat;
    import androidx.core.view.WindowInsetsCompat;
    
    public class MainActivity extends AppCompatActivity {
    
        private EditText emailInput;
        private EditText passwordInput;
        private EditText repeatPasswordInput;
        private TextView messageText;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            EdgeToEdge.enable(this);
            setContentView(R.layout.activity_main);
            ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main), (v, insets) -> {
                Insets systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars());
                v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom);
                return insets;
            });
    
            emailInput = findViewById(R.id.emailInput);
            passwordInput = findViewById(R.id.passwordInput);
            repeatPasswordInput = findViewById(R.id.repeatPasswordInput);
            messageText = findViewById(R.id.messageText);
        }
    
        public void confirm(View view) {
            String email = emailInput.getText().toString().trim();
            String password = passwordInput.getText().toString();
            String repeatedPassword = repeatPasswordInput.getText().toString();
            if (!Patterns.EMAIL_ADDRESS.matcher(email).matches()) {
                messageText.setText(R.string.invalid_email);
            } else if (password.isEmpty()) {
                messageText.setText(R.string.empty_password);
            } else if (!password.equals(repeatedPassword)) {
                messageText.setText(R.string.passwords_differ);
            } else {
                messageText.setText(getString(R.string.welcome, email));
            }
        }
    }
    Rejestracja/app/src/main/res/layout/activity_main.xml XML zmienione: 1 linia
    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:id="@+id/main"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        tools:context=".MainActivity">
    
        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:background="#008080"
            android:padding="4dp"
            android:text="Rejestruj konto"
            android:textColor="#FFFFFF"
            android:textSize="24sp" />
    
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="8dp"
            android:text="Podaj e-mail:"
            android:textColor="#000000" />
    
        <EditText
            android:id="@+id/emailInput"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:hint="email"
            android:inputType="textEmailAddress" />
    
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="8dp"
            android:text="Podaj hasło:"
            android:textColor="#000000" />
    
        <EditText
            android:id="@+id/passwordInput"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:inputType="textPassword" />
    
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="8dp"
            android:text="Powtórz hasło:"
            android:textColor="#000000" />
    
        <EditText
            android:id="@+id/repeatPasswordInput"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:inputType="textPassword" />
    
        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center_horizontal"
            android:layout_marginTop="16dp"
            android:onClick="confirm"
            android:text="ZATWIERDŹ" />
    
        <TextView
            android:id="@+id/messageText"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center_horizontal"
            android:layout_marginTop="8dp"
            android:text="@string/author" />
    
    </LinearLayout>
    Rejestracja/app/src/main/res/values/strings.xml XML nowy plik
    <resources>
        <string name="app_name">Rejestracja</string>
        <string name="author">Autor Bartosz Bryniarski</string>
        <string name="invalid_email">Nieprawidłowy adres e-mail</string>
        <string name="passwords_differ">Hasła się różnią</string>
        <string name="empty_password">Podaj hasło</string>
        <string name="welcome">Witaj %s</string>
    </resources>
    Ekran telefonu po tym kroku

    Symulacja ekranu w przeglądarce - w Android Studio / Visual Studio wygląd może się nieco różnić.

  24. Etap 6: Oddanie pracy

    Krok 24 · po tym etapie masz 33 z 33 kryteriów (pkt)

    Krok 24: Nagranie płyty

    ok. 5 min
    Polecenie z arkusza

    Nagraj płytę z rezultatami pracy. W folderze z numerem PESEL powinny się znajdować podfoldery dokumentacja, konsola, mobilna. W folderze dokumentacja powinny znaleźć się pliki: konsola.jpg, mobilna.jpg, egzamin. Po nagraniu płyty sprawdź poprawność nagrania.

    Sprawdzamy zawartość przed nagraniem:

    • dokumentacja: konsola.jpg, mobilna.jpg, egzamin,
    • konsola: cały folder projektu (z komentarzami do obu metod),
    • mobilna: cały folder projektu Rejestracja.

    Nagrywamy, sprawdzamy odczyt płyty, opisujemy ją numerem PESEL.

    Ekran telefonu bez zmian - taki jak po kroku 23.

Podgląd

To jedno z możliwych rozwiązań. Egzaminator ocenia spełnienie kryteriów z klucza odpowiedzi, a nie zgodność z tym kodem - inna, poprawna droga też daje punkty.

Autor rozwiązania: . Licencja CC BY-NC 4.0 - kopiowanie i przeróbki do celów niekomercyjnych, z podaniem autora i źródła (link do tej strony). Treść arkusza i klucza oceniania pochodzi z CKE.