|
|
Kierunek
Informatyka
|
|||
|
|
||||
Instrukcja
do ćwiczeń laboratoryjnych nr:
|
4
|
Nazwa przedmiotu:
|
||
Temat: intencje jawienie zdefiniowane
|
Tryb studiów:
stacjonarne |
|||
|
Czas
trwanie ćw. 2x45
min |
||||
|
Autor materiałów:
dr Marcin Skuba |
||||
1.
Treści programowe:
Tworzenie
nowych aktywności. Intencje. Przekazywanie wartości przez intencje. Intencje
wywołujące aktywności w sposób jawny i niejawny.
2. Cel
zajęć:
Celem
zajęć jest opanowanie umiejętności uruchamiania nowych aktywności poprzez
Intencje oraz przekazywanie danych pomiędzy aktywnościami również przez
Intencje.
3.
Materiały dydaktyczne
Intencje są jednym
z podstawowych komponentów aplikacji w systemie Android. Intencje odpowiadają
przede wszystkim za obsługę rozkazów wydawanych przez użytkownika np.: „zrób
zdjęcie”, zadzwoń do …”, „uruchom okno”. Najważniejszym zadaniem Intencji jest
uruchamianie odpowiednich Aktywności.
Intencje
możemy używać do uruchamiania innych aktywności w sposób jawny oraz niejawny.
W
tej instrukcji opisany zostanie jawny sposób wywoływania aktywności. Aktywności
wywoływane niejawnie opisane zostaną w następnej instrukcji.
ü Jawne definiowanie Aktywności
Jawne definiowanie aktywności to
takie gdzie tworząc nową Intencje podajemy dokładny typ (Klasę) uruchamianej Aktywności.
Klasa ta musi znajdować się w tym samym projekcie co aktywność wywołująca.
Np.:
Intent intent = new
Intent(MainActivity.this, SecondActivity.class);
startActivity(intent);
Przekazywanie
danych między aktywnościami
Możesz
przekazywać dane dodając je do intencjci za pomocą metody
putExtra():
Wysyłanie
danych:
Intent intent =
new Intent(MainActivity.this,
MainActivity2.class);
// Przekazywanie danych różnych typów
intent.putExtra("KEY_STRING", "Przykładowy
tekst");
intent.putExtra("KEY_INT", 123);
intent.putExtra("KEY_BOOLEAN", true);
intent.putExtra("KEY_FLOAT", 3.14f);
intent.putExtra("KEY_LONG", 9876543210L);
// Jeśli masz własny obiekt implementujący Serializable
MyObject myObject =
new MyObject("Jan", 25);
intent.putExtra("KEY_OBJECT", myObject);
// Jeśli masz obiekt implementujący Parcelable (np. klasy Androidowe)
MyParcelableObject parcelableObject
= new MyParcelableObject("Dane");
intent.putExtra("KEY_PARCELABLE", parcelableObject);
// Uruchomienie drugiej aktywności
startActivity(intent);
Odbieranie
danych w drugiej aktywności:
String user = getIntent().getStringExtra("username");
//onCreate
Intent intent = getIntent();
String stringValue = intent.getStringExtra("KEY_STRING");
int intValue = intent.getIntExtra("KEY_INT", 0);
boolean boolValue = intent.getBooleanExtra("KEY_BOOLEAN", false);
float floatValue = intent.getFloatExtra("KEY_FLOAT", 0f);
long longValue = intent.getLongExtra("KEY_LONG", 0L);
// Dla Serializable
MyObject
myObject = (MyObject) intent.getSerializableExtra("KEY_OBJECT");
// Dla Parcelable (opisane poniżej)
MyParcelableObject
parcelableObject = intent.getParcelableExtra("KEY_PARCELABLE");
-----------------------------------------------------------------------------------------------------------------------
Przykład
1
Aplikacja
przekazująca wartość z aktywności pierwszej do drugiej bez odpowiedzi
aktywności drugiej.
Aktywność pierwsza

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:id="@+id/main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@android:color/holo_orange_light"
tools:context=".MainActivity">
<Button
android:id="@+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Prześlij
dane do drugiej aktywności"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.498"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.623"
/>
<TextView
android:id="@+id/textView"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="Aktywnosc pierwsza "
android:textAlignment="center"
android:textSize="34sp"
app:layout_constraintBottom_toTopOf="@+id/editTextText"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.66"
/>
<EditText
android:id="@+id/editTextText"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginEnd="16dp"
android:layout_marginBottom="112dp"
android:ems="10"
android:hint="Wprowadz tekst do wysłania"
android:inputType="text"
app:layout_constraintBottom_toTopOf="@+id/button"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
MainActivity.java
package com.example.dwie_aktywnosci;
import
android.content.Intent;
import
android.os.Bundle;
import
android.view.View;
import
android.widget.Toast;
import
androidx.appcompat.app.AppCompatActivity;
import
com.example.dwie_aktywnosci.databinding.ActivityMainBinding;
public
class MainActivity
extends AppCompatActivity
{
private ActivityMainBinding
binding;
@Override
protected
void onCreate(Bundle
savedInstanceState) {
super.onCreate(savedInstanceState);
binding
=
ActivityMainBinding.inflate(getLayoutInflater());
setContentView(binding.getRoot());
binding.button.setOnClickListener(new View.OnClickListener()
{
@Override
public
void onClick(View view) {
String wiadomosc = binding.editTextText.getText().toString().trim();
if (!wiadomosc.isEmpty()) {
Intent
intent = new
Intent(MainActivity.this, MainActivity2.class);
intent.putExtra("KEY_WIADOMOSC",
wiadomosc);
startActivity(intent);
} else {
Toast.makeText(MainActivity.this, "Wpisz
wiadomość!", Toast.LENGTH_SHORT).show();
}
}
});
}
}
Aktywność druga
Aktywność druga

activity_main2.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:id="@+id/main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/design_default_color_secondary"
tools:context=".MainActivity2">
<Button
android:id="@+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Zwróć
dane do pierszej aktywności"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.498"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.623"
/>
<TextView
android:id="@+id/textView"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="Aktywnosc druga"
android:textAlignment="center"
android:textSize="34sp"
app:layout_constraintBottom_toTopOf="@+id/editTextText"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.66"
/>
<EditText
android:id="@+id/editTextText"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginEnd="16dp"
android:layout_marginBottom="112dp"
android:ems="10"
android:hint="Wprowadz tekst do wysłania"
android:inputType="text"
app:layout_constraintBottom_toTopOf="@+id/button"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
MainActivity2.java
package com.example.dwie_aktywnosci;
import
android.content.Intent;
import
android.os.Bundle;
import
android.view.View;
import
androidx.appcompat.app.AppCompatActivity;
import
com.example.dwie_aktywnosci.databinding.ActivityMain2Binding;
public
class MainActivity2 extends
AppCompatActivity
{
private
ActivityMain2Binding
binding;
@Override
protected
void onCreate(Bundle
savedInstanceState) {
super.onCreate(savedInstanceState);
binding=
ActivityMain2Binding.inflate(getLayoutInflater());
setContentView(binding.getRoot());
//odbieranie danych
z pierwszej aktywności
Intent
intent = getIntent();
// Sprawdzenie, czy intent nie jest null i czy
zawiera dane
if
(intent != null
&&
intent.hasExtra("KEY_WIADOMOSC"))
{
String wiadomosc
= intent.getStringExtra("KEY_WIADOMOSC");
//
Dodatkowe sprawdzenie na null
if
(wiadomosc != null)
{
binding.editTextText.setText(wiadomosc);
} else
{
binding.editTextText.setText(""); // lub inny tekst domyślny
}
}
binding.button.setOnClickListener(new View.OnClickListener()
{
@Override
public
void onClick(View view) {
finish();
}
});
}
}
-----------------------------------------------------------------------------------------------------------------------
Przykład
2
Aplikacja
przekazująca wartość z aktywności pierwszej do drugiej oraz zwracanie wartości
z drugiej do pierwszej przy pomocy intencji
MainActivity.java
package com.example.dwie_aktywnosci;
import
android.app.Activity;
import
android.content.Intent;
import
android.os.Bundle;
import
androidx.activity.EdgeToEdge;
import
androidx.activity.result.ActivityResult;
import
androidx.activity.result.ActivityResultCallback;
import
androidx.activity.result.ActivityResultLauncher;
import
androidx.activity.result.contract.ActivityResultContracts;
import
androidx.appcompat.app.AppCompatActivity;
import
com.example.dwie_aktywnosci.databinding.ActivityMainBinding;
public
class MainActivity
extends AppCompatActivity
{
private ActivityMainBinding
binding;
// Rejestrujemy launcher
do odbioru wyniku z innej aktywności
private
final ActivityResultLauncher<Intent> getResult
=
registerForActivityResult(
new ActivityResultContracts.StartActivityForResult(),
new ActivityResultCallback<ActivityResult>() {
@Override
public
void onActivityResult(ActivityResult result) {
if (result.getResultCode() ==
Activity.RESULT_OK)
{
Intent data = result.getData();
if (data != null)
{
String returnedText = data.getStringExtra("RESULT_KEY");
binding.editTextText.setText(returnedText);
}
}
}
});
@Override
protected
void onCreate(Bundle
savedInstanceState) {
super.onCreate(savedInstanceState);
binding
=
ActivityMainBinding.inflate(getLayoutInflater());
setContentView(binding.getRoot());
binding.button.setOnClickListener(v
-> {
String text
= binding.editTextText.getText().toString();
Intent
intent = new
Intent(MainActivity.this, MainActivity2.class);
intent.putExtra("KEY_DANE",
text);
getResult.launch(intent);
//
Jawne uruchomienie drugiej aktywności
});
}
}
MainActivity2.java
package com.example.dwie_aktywnosci;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import androidx.appcompat.app.AppCompatActivity;
import com.example.dwie_aktywnosci.databinding.ActivityMain2Binding;
public class MainActivity2 extends AppCompatActivity {
private ActivityMain2Binding binding;
@Override
protected void
onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
binding=
ActivityMain2Binding.inflate(getLayoutInflater());
setContentView(binding.getRoot());
//odbieranie
danych z pierwszej aktywności
Intent intent=
getIntent();
String dane = intent.getStringExtra("KEY_DANE");
binding.editTextText.setText(dane);
binding.button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View
view) {
String odpowiedz = binding.editTextText.getText().toString();
Intent
resultIntent = new Intent();
//Wstawianie wartości do intencji wyniku
resultIntent.putExtra("RESULT_KEY", odpowiedz);
// Ustaw wynik i zakończ aktywność
setResult(Activity.RESULT_OK,
resultIntent);
finish();
}
});
}
}
-----------------------------------------------------------------------------------------------------------------------
ü Interfejs Parcelable
W
Androidzie Parcelable to interfejs, który pozwala
na szybkie i efektywne przesyłanie obiektów między komponentami aplikacji
(np. między Activity lub Fragment) za
pomocą Intentów lub Bundle.
· Obiekt
implementujący Parcelable może być „spakowany” w
Intencję i wysłany do innej aktywności.
· Android
zamienia obiekt na specjalny strumień bajtów i odtwarza go w miejscu docelowym.
· Jest
szybszy niż Serializable,
dlatego jest rekomendowany w Androidzie.
Przykład
wykorzystania
interfejsu Parcelable do przesyłania danych w
aktywnościach.
package com.example.dwie_aktywnosci;
import
android.os.Parcel;
import
android.os.Parcelable;
//
Klasa Osoba implementująca Parcelable – pozwala
przesyłać obiekty między Activity lub Fragment
public
class Osoba implements
Parcelable {
private
String
imie; //
Pole przechowujące imię osoby
private
int wiek; //
Pole przechowujące wiek osoby
// Konstruktor główny – używany do
tworzenia nowego obiektu klasy Osoba
public Osoba(String imie, int wiek) {
this.imie
=
imie;
this.wiek
=
wiek;
}
// Konstruktor odczytujący dane z Parcel
// Android używa go przy odtwarzaniu
obiektu z Intencji lub Bundle
protected
Osoba(Parcel
in) {
// Kolejność odczytu
musi odpowiadać kolejności zapisu w writeToParcel()
imie
=
in.readString();
wiek =
in.readInt();
}
// Metoda writeToParcel –
pakowanie danych obiektu do Parcel
// Parcel to strumień bajtów używany
do przesyłania danych między komponentami
@Override
public void writeToParcel(Parcel dest, int flags)
{
dest.writeString(imie); // zapis imienia
dest.writeInt(wiek); // zapis wieku
}
// Metoda describeContents
// Zwykle zwraca 0, chyba że obiekt
zawiera FileDescriptor (rzadko używane)
@Override
public int describeContents() {
return 0;
}
// CREATOR – wymagany przez Androida do odtworzenia
obiektu z Parcel
// Tworzy nowy obiekt Osoba z Parcel
oraz tablice obiektów
public static final Creator<Osoba>
CREATOR = new
Creator<Osoba>() {
@Override
public Osoba
createFromParcel(Parcel in) {
//
Wywołuje konstruktor odczytujący z Parcel
return new Osoba(in);
}
@Override
public
Osoba[] newArray(int size) {
//
Tworzy tablicę obiektów Osoba
return new Osoba[size];
}
};
// Gettery – umożliwiają odczyt danych z obiektu
public String getImie()
{ return imie; }
public int getWiek() { return wiek; }
}
Wysyłanie
danych w pierwszej aktywności:
Osoba osoba = new Osoba("Jan", 25);
Intent intent = new Intent(MainActivity.this,
MainActivity2.class);
intent.putExtra("KEY_OSOBA",
osoba);
startActivity(intent);
Odbieranie
obiektu klasy Osoba w drugiej aktywności:
//odbieranie danych z pierwszej
aktywności
Intent intent = getIntent();
Osoba osoba = intent.getParcelableExtra("KEY_OSOBA");
String imie = osoba.getImie();
int wiek = osoba.getWiek();
Wysyłanie dużej ilości
obiektów
// Tworzymy dużą listę obiektów Osoba
ArrayList<Osoba> listaOsob
= new ArrayList<>();
for (int i = 1; i <= 100;
i++) {
listaOsob.add(new Osoba("Osoba
" + i, 20 + i));
}
// Tworzymy Intent do
drugiej aktywności
Intent intent = new Intent(MainActivity.this,
MainActivity2.class);
// Przekazujemy listę Osób jako ParcelableArrayList
intent.putParcelableArrayListExtra("KEY_LISTA_OSOB", listaOsob);
startActivity(intent);
Odbieranie dużej ilości
obiektów:
Intent intent
= getIntent();
ArrayList<Osoba> listaOsob
= intent.getParcelableArrayListExtra("KEY_LISTA_OSOB");
if (listaOsob != null && !listaOsob.isEmpty())
{
StringBuilder
builder = new StringBuilder();
for (Osoba
o : listaOsob) {
builder.append(o.getImie()).append(" - ").append(o.getWiek()).append("\n");
}
binding.textView.setText(builder.toString());
} else {
binding.textView.setText("Brak danych do wyświetlenia");
}
putParcelableArrayListExtra jest specjalnie
przystosowane do przesyłania list Parcelable.
Dla
bardzo dużych danych (setki lub tysiące obiektów) lepiej rozważyć:
Dzięki
Parcelable przesyłanie 100-200 obiektów działa
płynnie, jest znacznie szybsze niż Serializable.
ü
StringBuilder
StringBuilder w Javie to klasa służąca do
efektywnego tworzenia i modyfikowania łańcuchów tekstowych.
· Pozwala
dodawać (append), wstawiać (insert), usuwać (delete) lub zamieniać (replace)
tekst w jednym obiekcie.
· Szybszy
niż konkatenacja Stringów (+) w pętli, bo String w Javie jest niezmienny (immutable).
· Po
zakończeniu modyfikacji można zamienić na zwykły String:
String wynik = stringBuilder.toString();
Przykład użycia:
StringBuilder builder =
new StringBuilder();
builder.append("Jan");
builder.append(" ");
builder.append("Kowalski");
builder.append(" ma ");
builder.append(25);
builder.append(" lat.");
String wynik
= builder.toString();
System.out.println(wynik); // Jan
Kowalski ma 25 lat.
4. Zadania
Zadanie
1.
Napisz aplikację wg własnego pomysłu składającą
się z trzech aktywności.
·
Pierwsza powinna umożliwić uruchomienie drugiej
przekazując jej cztery wartości różnego typu pobrane z komponentów takich jak EditText, CheckBox oraz RadioButton.
·
W pierwszej aktywności
powinna znaleźć się również metoda uruchamiająca aktywność trzecią.
Aplikacja
powinna umożliwić przesyłanie co najmniej jednej wartości z pierwszej
aktywności do trzeciej oraz kilka z trzeciej do pierwszej.
Przekazane wartości przedstaw w
kontrolkach aktualnych aktywności.
Zadanie
2.
Napisz aplikację przekazująca dane z
pierwszej aktywności do drugiej. Dane powinny być reprezentowane przez klasę Punkt,
w której występują takie składowe jak zmienna x, y (int)
oraz kolor (int), metodę zwracającą
ciąg znaków w postaci np. „x=100 y=200 kolor=112233”. Utwórz 100 obiektów w
aktywności pierwszej oraz prześlij ją do aktywności drugiej. Wynik wyświetl w
polu tekstowych TextView.