1. Wprowadzenie
Telefony towarzyszą nam wszędzie, ale do tej pory aplikacje miały trudności z dostosowywaniem się do ciągle zmieniającego się otoczenia i aktywności użytkownika.
W przeszłości deweloperzy poświęcali dużo czasu na łączenie różnych sygnałów (lokalizacji, czujnika itp.), aby określić, kiedy rozpoczęła się lub zakończyła aktywność, np. chodzenie lub jazda samochodem. Co gorsza, gdy aplikacje niezależnie i ciągle sprawdzają zmiany w aktywności użytkownika, czas pracy na baterii ulega skróceniu.
Activity Recognition Transition API rozwiązuje te problemy, udostępniając prosty interfejs API, który wykonuje wszystkie obliczenia i informuje Cię tylko o tym, co Cię interesuje: kiedy zmieniła się aktywność użytkownika. Aplikacja po prostu subskrybuje przejście w aktywnościach, które Cię interesują, a interfejs API powiadamia Cię o zmianach.
Na przykład aplikacja do obsługi wiadomości może zapytać: „Powiadom mnie, gdy użytkownik wsiądzie do pojazdu lub z niego wysiądzie”, aby ustawić status użytkownika jako zajęty. Podobnie aplikacja do wykrywania parkowania może zapytać: „powiadom mnie, gdy użytkownik wysiądzie z pojazdu i zacznie iść pieszo”, aby zapisać lokalizację parkowania użytkownika.
Z tego samouczka dowiesz się, jak używać interfejsu Activity Recognition Transition API do określania, kiedy użytkownik rozpoczyna lub kończy aktywność, taką jak chodzenie lub bieganie.
Wymagania wstępne
Znajomość tworzenia aplikacji na Androida i wywołań zwrotnych.
Czego się nauczysz
- Rejestrowanie przejść aktywności
- przetwarzanie tych zdarzeń,
- wyrejestrowywanie się z przejść między aktywnościami, gdy nie są już potrzebne;
Co będzie potrzebne
- Android Studio Bumblebee
- urządzenie z Androidem lub emulator;
2. Pierwsze kroki
Sklonuj repozytorium projektu startowego
Aby ułatwić Ci szybkie rozpoczęcie pracy, przygotowaliśmy projekt startowy, na którym możesz się oprzeć. Jeśli masz zainstalowany program git, możesz po prostu uruchomić to polecenie. (Możesz to sprawdzić, wpisując git --version w terminalu lub wierszu poleceń i sprawdzając, czy polecenie zostało wykonane prawidłowo).
git clone https://github.com/android/codelab-activity_transitionapi
Jeśli nie masz Gita, możesz pobrać projekt jako plik ZIP:
Importowanie projektu
Uruchom Android Studio i na ekranie powitalnym wybierz „Open an existing Android Studio project” (Otwórz istniejący projekt Android Studio), a następnie otwórz katalog projektu.
Po wczytaniu projektu może się też pojawić alert z informacją, że Git nie śledzi wszystkich lokalnych zmian. Możesz kliknąć Zignoruj lub „X” w prawym górnym rogu. (Nie będziesz przesyłać żadnych zmian z powrotem do repozytorium Git).
W lewym górnym rogu okna projektu powinna być widoczna zawartość podobna do tej na ilustracji poniżej, jeśli jesteś w widoku Android. (Jeśli jesteś w widoku Projekt, musisz rozwinąć projekt, aby zobaczyć to samo).

Są 2 ikony folderów (base i complete). Każda z nich jest nazywana „modułem”.
Pamiętaj, że kompilacja projektu w Android Studio może potrwać kilka sekund. W tym czasie na pasku stanu u dołu Android Studio zobaczysz spinner:

Zalecamy, aby przed wprowadzeniem zmian w kodzie poczekać na zakończenie tego procesu. Dzięki temu Android Studio pobierze wszystkie niezbędne komponenty.
Jeśli pojawi się komunikat „Czy chcesz ponownie załadować stronę, aby zastosować zmiany języka?” lub podobny, kliknij „Tak”.
Informacje o projekcie startowym
Wszystko gotowe. Możesz dodać rozpoznawanie aktywności. Będziemy używać modułu base, który jest punktem początkowym w tym samouczku. Innymi słowy, dodasz kod z każdego kroku do base.
Moduł complete może służyć do sprawdzania Twojej pracy lub jako źródło informacji, jeśli napotkasz jakieś problemy.
Omówienie kluczowych komponentów:
MainActivity: zawiera cały kod potrzebny do rozpoznawania aktywności.
Konfiguracja emulatora
Jeśli potrzebujesz pomocy przy konfigurowaniu emulatora Androida, zapoznaj się z artykułem Uruchamianie aplikacji.
Uruchamianie projektu startowego
Uruchommy aplikację.
- Podłącz urządzenie z Androidem do komputera lub uruchom emulator.
- Na pasku narzędzi wybierz konfigurację
basez selektora menu i kliknij zielony trójkąt (Uruchom) obok niej:

- Powinna pojawić się aplikacja:

- Aplikacja nie robi teraz nic poza wyświetlaniem wiadomości. Teraz dodamy rozpoznawanie aktywności.
Podsumowanie
Z tego kroku dowiesz się:
- Ogólna konfiguracja laboratorium.
- Podstawowe informacje o naszej aplikacji.
- Jak wdrożyć aplikację.
3. Sprawdź bibliotekę i dodaj uprawnienia do pliku manifestu
Aby używać w aplikacji interfejsu Transition API, musisz zadeklarować zależność od interfejsu Google Location and Activity Recognition oraz określić w manifeście aplikacji uprawnienie com.google.android.gms.permission.ACTIVITY_RECOGNITION.
- W pliku build.gradle wyszukaj TODO: Review play services library required for activity recognition (DO ZROBIENIA: sprawdź bibliotekę usług Play wymaganą do rozpoznawania aktywności). W tym kroku (krok 1) nie musisz nic robić. Wystarczy, że sprawdzisz zadeklarowaną zależność, której wymagamy. Powinien on wyglądać podobnie do tego:
// TODO: Review play services library required for activity recognition.
implementation 'com.google.android.gms:play-services-location:19.0.1'
- W module
basewyszukaj w plikuAndroidManifest.xmlciąg TODO: Add both activity recognition permissions to the manifest i dodaj poniższy kod do elementu<manifest>.
<!-- TODO: Add both activity recognition permissions to the manifest. -->
<!-- Required for 28 and below. -->
<uses-permission android:name="com.google.android.gms.permission.ACTIVITY_RECOGNITION" />
<!-- Required for 29+. -->
<uses-permission android:name="android.permission.ACTIVITY_RECOGNITION" />
Kod powinien teraz wyglądać mniej więcej tak:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.myapp">
<!-- TODO: Add both activity recognition permissions to the manifest. -->
<!-- Required for 28 and below. -->
<uses-permission android:name="com.google.android.gms.permission.ACTIVITY_RECOGNITION" />
<!-- Required for 29+. -->
<uses-permission android:name="android.permission.ACTIVITY_RECOGNITION" />
...
</manifest>
Jak widać z komentarzy, w przypadku Androida 10 musisz dodać drugie uprawnienie. Jest to wymagane w przypadku uprawnień w czasie działania, które zostały dodane w wersji interfejsu API 29.
Znakomicie. Aplikacja może teraz obsługiwać rozpoznawanie aktywności. Wystarczy dodać odpowiedni kod.
Uruchom aplikację
Uruchom aplikację z Androida Studio. Powinien wyglądać dokładnie tak samo. Nie dodaliśmy jeszcze żadnego kodu do śledzenia przejść. Zrobimy to w następnej sekcji.
4. Sprawdzanie i żądanie uprawnień czasu działania na Androidzie
W przypadku interfejsu API w wersji 28 i starszych mamy już zgodę na uprawnienia, ale w przypadku interfejsu API w wersji 29 i nowszych musimy obsługiwać uprawnienia w czasie działania:
- W
MainActivity.javasprawdzimy, czy użytkownik korzysta z Androida 10 (29) lub nowszego. Jeśli tak, sprawdzimy uprawnienia do rozpoznawania aktywności. - Jeśli użytkownik nie przyzna uprawnień, wyświetlimy ekran powitalny (
PermissionRationalActivity.java) z wyjaśnieniem, dlaczego aplikacja ich potrzebuje, i umożliwimy ich przyznanie.
Sprawdzanie kodu wersji Androida
W module base wyszukaj w pliku MainActivity.java ciąg TODO: Review check for devices with Android 10 (29+). Powinien wyświetlić się ten fragment kodu.
Uwaga: w tej sekcji nie musisz nic robić.
// TODO: Review check for devices with Android 10 (29+).
private boolean runningQOrLater =
android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.Q;
Jak wspomnieliśmy wcześniej, w Androidzie 10 i nowszych wersjach musisz uzyskać zgodę na uprawnienia w czasie działania android.permission.ACTIVITY_RECOGNITION. Za pomocą tego prostego sprawdzenia decydujemy, czy musimy sprawdzić uprawnienia w czasie działania.
W razie potrzeby sprawdź uprawnienia w czasie działania aplikacji do rozpoznawania aktywności
W base znajdź TODO: Review permission check for 29+ w MainActivity.java. Powinien wyświetlić się ten fragment kodu.
Uwaga: w tej sekcji nie musisz nic robić.
// TODO: Review permission check for 29+.
if (runningQOrLater) {
return PackageManager.PERMISSION_GRANTED == ActivityCompat.checkSelfPermission(
this,
Manifest.permission.ACTIVITY_RECOGNITION
);
} else {
return true;
}
Używamy zmiennej utworzonej w poprzednim kroku, aby sprawdzić, czy musimy sprawdzić uprawnienia w czasie działania.
W przypadku wersji Q i nowszych sprawdzamy i zwracamy wynik uprawnień w czasie działania. Jest to część większej metody o nazwie activityRecognitionPermissionApproved(), która w prosty sposób informuje dewelopera, czy musimy poprosić o uprawnienia.
Prośba o uprawnienia czasu działania oraz włączanie i wyłączanie przejść rozpoznawania aktywności
W module base wyszukaj w MainActivity.java ciąg TODO: Enable/Disable śledzenie ćwiczeń and ask for permissions if needed. Dodaj poniższy kod po komentarzu.
// TODO: Enable/Disable activity tracking and ask for permissions if needed.
if (activityRecognitionPermissionApproved()) {
if (activityTrackingEnabled) {
disableActivityTransitions();
} else {
enableActivityTransitions();
}
} else {
// Request permission and start activity for result. If the permission is approved, we
// want to make sure we start activity recognition tracking.
Intent startIntent = new Intent(this, PermissionRationalActivity.class);
startActivityForResult(startIntent, 0);
}
W tym miejscu pytamy, czy rozpoznawanie aktywności jest zatwierdzone. Jeśli tak jest, a rozpoznawanie aktywności jest już włączone, wyłączymy je. W przeciwnym razie włączymy ją.
Jeśli uprawnienie nie zostanie przyznane, przekierowujemy użytkownika do ekranu powitalnego, na którym wyjaśniamy, dlaczego potrzebujemy tego uprawnienia, i umożliwiamy jego włączenie.
Sprawdź kod prośby o uprawnienia
W module base wyszukaj TODO: Review prośba o uprawnienia for rozpoznawanie aktywności w PermissionRationalActivity.java. Powinien wyświetlić się ten fragment kodu.
Uwaga: w tej sekcji nie musisz nic robić.
// TODO: Review permission request for activity recognition.
ActivityCompat.requestPermissions(
this,
new String[]{Manifest.permission.ACTIVITY_RECOGNITION},
PERMISSION_REQUEST_ACTIVITY_RECOGNITION)
To najważniejsza część aktywności, którą należy sprawdzić. Kod wywołuje prośbę o przyznanie uprawnień, gdy użytkownik o to poprosi.
Poza tym klasa PermissionRationalActivity.java wyświetla uzasadnienie, dlaczego użytkownik powinien zatwierdzić uprawnienie do rozpoznawania aktywności (najlepsza praktyka). Użytkownik może kliknąć przycisk Nie, dziękuję lub Dalej (który uruchamia powyższy kod).
Jeśli chcesz dowiedzieć się więcej, możesz przejrzeć plik.
5. Rejestrowanie/wyrejestrowywanie odbiornika w przypadku przejść aktywności
Zanim skonfigurujemy kod rozpoznawania aktywności, musimy się upewnić, że nasza aktywność może obsługiwać działania związane ze zmianą stanu zgłaszane przez system.
Tworzenie elementu BroadcastReceiver na potrzeby przejścia
W module base wyszukaj w MainActivity.java ciąg TODO: Create a BroadcastReceiver to listen for activity transitions. Wklej poniższy fragment kodu.
// TODO: Create a BroadcastReceiver to listen for activity transitions.
// The receiver listens for the PendingIntent above that is triggered by the system when an
// activity transition occurs.
mTransitionsReceiver = new TransitionsReceiver();
Rejestrowanie elementu BroadcastReceiver na potrzeby przejścia
W module base wyszukaj w MainActivity.java ciąg TODO: Register a BroadcastReceiver to listen for activity transitions. (Znajduje się on w sekcji onStart()). Wklej poniższy fragment kodu.
// TODO: Register a BroadcastReceiver to listen for activity transitions.
registerReceiver(mTransitionsReceiver, new IntentFilter(TRANSITIONS_RECEIVER_ACTION));
Teraz możemy otrzymywać aktualizacje, gdy przejścia aktywności są zgłaszane za pomocą obiektu PendingIntent.
Wyrejestrowanie BroadcastReceiver
W module base wyszukaj Unregister activity transition receiver when user leaves the app w MainActivity.java. (Znajduje się on w sekcji onStop()).Wklej poniższy fragment kodu.
// TODO: Unregister activity transition receiver when user leaves the app.
unregisterReceiver(mTransitionsReceiver);
Sprawdzoną metodą jest wyrejestrowanie odbiornika, gdy Activity jest wyłączany.
6. Konfigurowanie przejść między aktywnościami i wysyłanie próśb o aktualizacje
Aby zacząć otrzymywać aktualizacje dotyczące przejść między aktywnościami, musisz wdrożyć:
- Obiekt ActivityTransitionRequest, który określa typ aktywności i przejścia.
- Wywołanie zwrotne PendingIntent, w którym aplikacja otrzymuje powiadomienia. Więcej informacji znajdziesz w artykule o używaniu intencji oczekującej.
Utwórz listę przejść aktywności, które chcesz śledzić
Aby utworzyć obiekt ActivityTransitionRequest, musisz utworzyć listę obiektów ActivityTransition, które reprezentują przejście, które chcesz śledzić. Obiekt ActivityTransition zawiera te dane:
- Typ aktywności reprezentowany przez klasę DetectedActivity. Interfejs Transition API obsługuje te działania:
- Typ przejścia reprezentowany przez klasę ActivityTransition. Typy przejść:
W module base wyszukaj w pliku MainActivity.java ciąg TODO: Add activity transitions to track. Dodaj poniższy kod po komentarzu.
// TODO: Add activity transitions to track.
activityTransitionList.add(new ActivityTransition.Builder()
.setActivityType(DetectedActivity.WALKING)
.setActivityTransition(ActivityTransition.ACTIVITY_TRANSITION_ENTER)
.build());
activityTransitionList.add(new ActivityTransition.Builder()
.setActivityType(DetectedActivity.WALKING)
.setActivityTransition(ActivityTransition.ACTIVITY_TRANSITION_EXIT)
.build());
activityTransitionList.add(new ActivityTransition.Builder()
.setActivityType(DetectedActivity.STILL)
.setActivityTransition(ActivityTransition.ACTIVITY_TRANSITION_ENTER)
.build());
activityTransitionList.add(new ActivityTransition.Builder()
.setActivityType(DetectedActivity.STILL)
.setActivityTransition(ActivityTransition.ACTIVITY_TRANSITION_EXIT)
.build());
Ten kod dodaje przejścia, które chcemy śledzić, do wcześniej pustej listy.
Tworzenie intencji PendingIntent
Jak wspomnieliśmy wcześniej, jeśli chcemy otrzymywać powiadomienia o zmianach w ActivityTransitionRequest, musimy mieć PendingIntent. Zanim więc skonfigurujemy ActivityTransitionRequest, musimy utworzyć PendingIntent.
W module base wyszukaj w pliku MainActivity.java ciąg TODO: Initialize PendingIntent that will be triggered when a activity transition occurs. Dodaj poniższy kod po komentarzu.
// TODO: Initialize PendingIntent that will be triggered when a activity transition occurs.
Intent intent = new Intent(TRANSITIONS_RECEIVER_ACTION);
mActivityTransitionsPendingIntent =
PendingIntent.getBroadcast(MainActivity.this, 0, intent, 0);
Teraz mamy obiekt PendingIntent, który możemy wywołać, gdy wystąpi jedna z przemian aktywności.
Utwórz obiekt ActivityTransitionRequest i poproś o aktualizacje
Obiekt ActivityTransitionRequest możesz utworzyć, przekazując listę ActivityTransition do klasy ActivityTransitionRequest.
W module base wyszukaj Utwórz prośbę i nasłuchuj zmian aktywności w MainActivity.java. Dodaj poniższy kod po komentarzu.
// TODO: Create request and listen for activity changes.
ActivityTransitionRequest request = new ActivityTransitionRequest(activityTransitionList);
// Register for Transitions Updates.
Task<Void> task =
ActivityRecognition.getClient(this)
.requestActivityTransitionUpdates(request, mActivityTransitionsPendingIntent);
task.addOnSuccessListener(
new OnSuccessListener<Void>() {
@Override
public void onSuccess(Void result) {
activityTrackingEnabled = true;
printToScreen("Transitions Api was successfully registered.");
}
});
task.addOnFailureListener(
new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception e) {
printToScreen("Transitions Api could NOT be registered: " + e);
Log.e(TAG, "Transitions Api could NOT be registered: " + e);
}
});
Przyjrzyjmy się kodowi. Najpierw tworzymy obiekt ActivityTransitionRequest na podstawie listy przejść aktywności.
ActivityTransitionRequest request = new ActivityTransitionRequest(activityTransitionList);
Następnie rejestrujemy aktualizacje przejść aktywności, przekazując instancję ActivityTransitionRequest i obiekt PendingIntent utworzony w ostatnim kroku do metody requestActivityTransitionUpdates(). Metoda requestActivityTransitionUpdates() zwraca obiekt Task, który możesz sprawdzić pod kątem powodzenia lub niepowodzenia, jak pokazano w następnym bloku kodu:
// Register for Transitions Updates.
Task<Void> task =
ActivityRecognition.getClient(this)
.requestActivityTransitionUpdates(request, mActivityTransitionsPendingIntent);
task.addOnSuccessListener(
new OnSuccessListener<Void>() {
@Override
public void onSuccess(Void result) {
activityTrackingEnabled = true;
printToScreen("Transitions Api was successfully registered.");
}
});
task.addOnFailureListener(
new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception e) {
printToScreen("Transitions Api could NOT be registered: " + e);
Log.e(TAG, "Transitions Api could NOT be registered: " + e);
}
});
Po zarejestrowaniu się w celu otrzymywania aktualizacji dotyczących przejść między aktywnościami aplikacja będzie otrzymywać powiadomienia w zarejestrowanym obiekcie PendingIntent. Ustawiamy też zmienną, która informuje, że śledzenie ćwiczeń jest włączone. Dzięki temu wiemy, czy wyłączyć lub włączyć śledzenie, gdy użytkownik ponownie kliknie przycisk.
Usuwanie aktualizacji po zamknięciu aplikacji
Ważne jest, abyśmy usuwali aktualizacje przejść, gdy aplikacja jest zamykana.
W module base wyszukaj Stop listening for activity changes w MainActivity.java. Dodaj poniższy kod po komentarzu.
// TODO: Stop listening for activity changes.
ActivityRecognition.getClient(this).removeActivityTransitionUpdates(mActivityTransitionsPendingIntent)
.addOnSuccessListener(new OnSuccessListener<Void>() {
@Override
public void onSuccess(Void aVoid) {
activityTrackingEnabled = false;
printToScreen("Transitions successfully unregistered.");
}
})
.addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception e) {
printToScreen("Transitions could not be unregistered: " + e);
Log.e(TAG,"Transitions could not be unregistered: " + e);
}
});
Teraz musimy wywołać metodę zawierającą powyższy kod, gdy aplikacja jest zamykana.
W module base wyszukaj TODO: Disable activity transitions when user leaves the app w MainActivity.java w onPause(). Dodaj poniższy kod po komentarzu.
// TODO: Disable activity transitions when user leaves the app.
if (activityTrackingEnabled) {
disableActivityTransitions();
}
To wszystko, co musisz wiedzieć o śledzeniu zmian w przejściach między aktywnościami. Teraz musimy tylko przetworzyć aktualizacje.
7. Przetwarzanie zdarzeń
Gdy nastąpi żądane przejście aktywności, aplikacja otrzyma wywołanie zwrotne Intent. Z obiektu Intent można wyodrębnić obiekt ActivityTransitionResult, który zawiera listę obiektów ActivityTransitionEvent. Wydarzenia są uporządkowane chronologicznie. Jeśli na przykład aplikacja poprosi o typ aktywności IN_VEHICLE w przypadku przejść ACTIVITY_TRANSITION_ENTER i ACTIVITY_TRANSITION_EXIT, otrzyma obiekt ActivityTransitionEvent, gdy użytkownik zacznie prowadzić pojazd, a następnie kolejny, gdy przejdzie do innej aktywności.
Dodajmy kod do obsługi tych zdarzeń.
W module base wyszukaj TODO: Extract activity transition information from listener w MainActivity.java w onReceive()utworzonego wcześniej elementu BroadcastReceiver. Dodaj poniższy kod po komentarzu.
// TODO: Extract activity transition information from listener.
if (ActivityTransitionResult.hasResult(intent)) {
ActivityTransitionResult result = ActivityTransitionResult.extractResult(intent);
for (ActivityTransitionEvent event : result.getTransitionEvents()) {
String info = "Transition: " + toActivityString(event.getActivityType()) +
" (" + toTransitionType(event.getTransitionType()) + ")" + " " +
new SimpleDateFormat("HH:mm:ss", Locale.US).format(new Date());
printToScreen(info);
}
}
Spowoduje to przekonwertowanie informacji na znak String i wyświetlenie go na ekranie.
To wszystko. Gotowe! Spróbuj uruchomić aplikację.
WAŻNA UWAGA: trudno jest odtworzyć zmiany aktywności na emulatorze, dlatego zalecamy używanie urządzenia fizycznego.
Powinno być możliwe śledzenie zmian aktywności.
Aby uzyskać najlepsze wyniki, zainstaluj aplikację na urządzeniu fizycznym i przejdź się. :)
8. Sprawdzanie kodu
Masz prostą aplikację, która śledzi przejścia aktywności i wyświetla je na ekranie.
Możesz przeczytać cały kod, aby sprawdzić, co zostało zrobione, i lepiej zrozumieć, jak wszystko ze sobą współpracuje.