Codelab Activity Recognition Transition API

1. Pengantar

Kita membawa ponsel ke mana pun, tetapi hingga saat ini, aplikasi sulit menyesuaikan pengalamannya dengan lingkungan dan aktivitas pengguna yang terus berubah.

Untuk melakukannya sebelumnya, developer menghabiskan waktu engineering yang berharga untuk menggabungkan berbagai sinyal (lokasi,sensor, dll.) guna menentukan kapan aktivitas seperti berjalan atau mengemudi dimulai atau berakhir. Lebih buruk lagi, saat aplikasi secara independen dan terus-menerus memeriksa perubahan aktivitas pengguna, masa pakai baterai akan berkurang.

Activity Recognition Transition API memecahkan masalah ini dengan menyediakan API sederhana yang melakukan semua pemrosesan untuk Anda dan hanya memberi tahu Anda hal yang benar-benar Anda minati: kapan aktivitas pengguna telah berubah. Aplikasi Anda cukup berlangganan ke transisi dalam aktivitas yang Anda minati dan API akan memberi tahu Anda tentang perubahan tersebut

Misalnya, aplikasi pesan dapat bertanya, "beri tahu saya saat pengguna masuk atau keluar dari kendaraan", untuk menetapkan status pengguna sebagai sibuk. Demikian pula, aplikasi deteksi parkir dapat bertanya,"beri tahu saya saat pengguna keluar dari kendaraan dan mulai berjalan", untuk menyimpan lokasi parkir pengguna.

Dalam codelab ini, Anda akan mempelajari cara menggunakan Activity Recognition Transition API untuk menentukan kapan pengguna memulai/menghentikan aktivitas seperti berjalan atau berlari.

Prasyarat

Pemahaman tentang pengembangan Android dan beberapa pemahaman tentang callback.

Yang akan Anda pelajari

  • Mendaftar untuk transisi aktivitas
  • Memproses peristiwa tersebut
  • Membatalkan pendaftaran untuk transisi aktivitas saat tidak lagi diperlukan

Yang akan Anda butuhkan

  • Android Studio Bumblebee
  • Perangkat Android atau emulator.

2. Memulai

Meng-clone repositori project awal

Untuk memulainya secepat mungkin, kami telah menyiapkan project awal untuk Anda kembangkan. Jika sudah menginstal git, Anda cukup menjalankan perintah di bawah ini. (Anda dapat memeriksanya dengan mengetikkan git --version di baris perintah/terminal, lalu pastikan git dijalankan dengan benar.)

 git clone https://github.com/android/codelab-activity_transitionapi

Jika tidak memiliki git, Anda bisa mendapatkan project sebagai file ZIP:

Mengimpor project

Mulai Android Studio, pilih "Open an existing Android Studio project" dari layar Welcome, lalu buka direktori project.

Setelah project dimuat, Anda juga akan melihat notifikasi bahwa Git tidak melacak semua perubahan lokal. Anda dapat mengklik "Ignore" atau "X" di kanan atas. (Anda tidak akan mendorong perubahan apa pun kembali ke repositori Git.)

Di sudut kiri atas jendela project, Anda akan melihat sesuatu seperti gambar di bawah jika berada dalam tampilan Android. (Jika berada dalam tampilan Project, Anda harus memperluas project untuk melihat hal yang sama.)

d2363db913d8e5ad.png

Ada dua ikon folder (base dan complete). Masing-masing dikenal sebagai "modul".

Perlu diketahui bahwa Android Studio mungkin memerlukan waktu beberapa detik untuk mengompilasi project di latar belakang untuk pertama kalinya. Selama durasi ini, Anda akan melihat indikator lingkaran berputar di status bar di bagian bawah Android Studio:

c9f23d5336be3cfe.png

Sebaiknya Anda menunggu hingga proses ini selesai sebelum memodifikasi kode. Ini akan memungkinkan Android Studio menarik semua komponen yang diperlukan.

Selain itu, jika Anda ditanya "Reload for language changes to take effect?" atau yang serupa, pilih "Yes".

Memahami project awal

Baik, Anda sudah siap menambahkan pengenalan aktivitas. Kita akan menggunakan modul base, yang merupakan titik awal codelab ini. Dengan kata lain, Anda akan menambahkan kode dari setiap langkah ke base.

Modul complete dapat digunakan untuk memeriksa pekerjaan Anda, atau sebagai referensi jika Anda mengalami masalah apa pun.

Ringkasan komponen utama:

  • MainActivity: Berisi semua kode yang diperlukan untuk pengenalan aktivitas.

Penyiapan emulator

Jika Anda memerlukan bantuan untuk menyiapkan emulator Android, lihat artikel Menjalankan aplikasi.

Menjalankan project awal

Mari kita jalankan aplikasi.

  • Hubungkan perangkat Android ke komputer atau mulai emulator.
  • Di toolbar, pilih konfigurasi base dari pemilih drop-down, lalu klik tombol segitiga hijau (Run) di sampingnya:

a640a291ffaf62ad.png

  • Anda akan melihat aplikasi di bawah ini:

f58d4bb92ee77f41.png

  • Aplikasi tidak melakukan apa pun sekarang selain mencetak pesan. Sekarang kita akan menambahkan pengenalan aktivitas.

Ringkasan

Di langkah ini, Anda telah mempelajari tentang:

  • Penyiapan umum untuk codelab.
  • Dasar-dasar aplikasi kita.
  • Cara men-deploy aplikasi.

3. Meninjau library dan menambahkan izin ke manifes

Untuk menggunakan Transition API di aplikasi, Anda harus mendeklarasikan dependensi ke Google Location and Activity Recognition API dan menentukan izin com.google.android.gms.permission.ACTIVITY_RECOGNITION di manifes aplikasi.

  1. Telusuri TODO: Tinjau library layanan play yang diperlukan untuk pengenalan aktivitas dalam file build.gradle. Tidak ada tindakan untuk langkah ini (langkah 1), cukup tinjau dependensi yang dideklarasikan yang kita butuhkan. Tampilannya akan terlihat seperti ini:
    // TODO: Review play services library required for activity recognition.
    implementation 'com.google.android.gms:play-services-location:19.0.1'
  1. Dalam modul base, telusuri TODO: Tambahkan kedua izin pengenalan aktivitas ke manifes dalam AndroidManifest.xml, lalu tambahkan kode di bawah ke elemen <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" />

Kode Anda kini akan terlihat mirip seperti ini:

<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>

Seperti yang dapat dilihat dari komentar, Anda harus menambahkan izin kedua untuk Android 10. Hal ini diperlukan untuk izin runtime yang ditambahkan di API versi 29.

Selesai. Aplikasi Anda kini dapat mendukung pengenalan aktivitas, kita hanya perlu menambahkan kode untuk mendapatkannya.

Menjalankan aplikasi

Jalankan aplikasi Anda dari Android Studio. Tampilannya akan terlihat sama persis. Kita belum menambahkan kode apa pun untuk melacak transisi. Kode tersebut akan muncul di bagian berikutnya.

4. Memeriksa/Meminta izin runtime di Android

Meskipun kami tercakup dalam izin pada API versi 28 dan yang lebih lama, kami perlu mendukung izin runtime di API versi 29 dan yang lebih baru:

  • Di MainActivity.java, kita akan memeriksa apakah pengguna menggunakan Android 10 (29) atau yang lebih baru, dan jika ya, kita akan memeriksa izin pengenalan aktivitas.
  • Jika izin tidak diberikan, kita akan mengarahkan pengguna ke layar pembuka (PermissionRationalActivity.java) yang menjelaskan alasan aplikasi memerlukan izin tersebut dan memungkinkan mereka menyetujuinya.

Meninjau kode yang memeriksa versi Android

Dalam modul base, telusuri TODO: Tinjau pemeriksaan untuk perangkat dengan Android 10 (29+) di MainActivity.java. Anda akan melihat cuplikan kode ini.

Perlu diketahui bahwa tidak ada tindakan untuk bagian ini.

// TODO: Review check for devices with Android 10 (29+).
private boolean runningQOrLater =
    android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.Q;

Seperti yang dinyatakan sebelumnya, Anda memerlukan persetujuan untuk izin runtime android.permission.ACTIVITY_RECOGNITION di Android 10 dan yang lebih baru. Kita menggunakan pemeriksaan sederhana ini untuk memutuskan apakah kita perlu memeriksa izin runtime atau tidak.

Meninjau pemeriksaan izin runtime untuk pengenalan aktivitas jika diperlukan

Dalam modul base, telusuri TODO: Tinjau pemeriksaan izin untuk 29+ dalam MainActivity.java. Anda akan melihat cuplikan kode ini.

Perlu diketahui bahwa tidak ada tindakan untuk bagian ini.

// TODO: Review permission check for 29+.
if (runningQOrLater) {

   return PackageManager.PERMISSION_GRANTED == ActivityCompat.checkSelfPermission(
           this,
           Manifest.permission.ACTIVITY_RECOGNITION
   );
} else {
   return true;
}

Kita menggunakan variabel yang dibuat pada langkah sebelumnya untuk melihat apakah kita perlu memeriksa izin runtime.

Untuk Q dan yang lebih baru, kami memeriksa dan menampilkan hasil untuk izin runtime. Ini adalah bagian dari metode yang lebih besar yang disebut activityRecognitionPermissionApproved() yang memberi tahu developer dalam satu panggilan sederhana apakah kita perlu meminta izin atau tidak.

Meminta izin runtime dan mengaktifkan/menonaktifkan transisi pengenalan aktivitas

Dalam modul base, telusuri TODO: Aktifkan/Nonaktifkan pelacakan aktivitas, lalu minta izin jika diperlukan dalam MainActivity.java. Tambahkan kode di bawah setelah komentar.

// 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);

}

Di sini, kita menanyakan apakah pengenalan aktivitas disetujui. Jika demikian dan pengenalan aktivitas sudah diaktifkan, kami akan menonaktifkannya. Jika tidak, kami akan mengaktifkannya.

Jika izin tidak disetujui, kita mengarahkan pengguna ke aktivitas layar pembuka yang menjelaskan alasan kita memerlukan izin tersebut dan memungkinkan mereka mengaktifkannya.

Tinjau kode permintaan izin

Dalam modul base, telusuri TODO: Tinjau permintaan izin untuk pengenalan aktivitas dalam PermissionRationalActivity.java. Anda akan melihat cuplikan kode ini.

Perlu diketahui bahwa tidak ada tindakan untuk bagian ini.

// TODO: Review permission request for activity recognition.
ActivityCompat.requestPermissions(
             this,
             new String[]{Manifest.permission.ACTIVITY_RECOGNITION},
             PERMISSION_REQUEST_ACTIVITY_RECOGNITION)

Ini adalah bagian terpenting dari Aktivitas dan bagian yang akan ditinjau. Kode memicu permintaan izin saat pengguna memintanya.

Selain itu, class PermissionRationalActivity.java menampilkan alasan mengapa pengguna harus menyetujui izin pengenalan aktivitas (praktik terbaik). Pengguna dapat mengklik tombol No Thanks atau tombol Continue (yang memicu kode di atas).

Anda dapat meninjau file tersebut jika ingin mempelajari lebih lanjut.

5. Mendaftarkan/Membatalkan pendaftaran penerima untuk transisi aktivitas

Sebelum menyiapkan kode pengenalan aktivitas, kita ingin memastikan Aktivitas dapat menangani tindakan transisi yang diajukan oleh sistem.

Membuat BroadcastReceiver untuk transisi

Dalam modul base, telusuri TODO: Buat BroadcastReceiver untuk memproses transisi aktivitas dalam MainActivity.java. Tempelkan cuplikan di bawah.

// 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();

Mendaftarkan BroadcastReceiver untuk transisi

Dalam modul base, telusuri TODO: Daftarkan BroadcastReceiver untuk memproses transisi aktivitas di MainActivity.java. (Terletak di onStart()). Tempelkan cuplikan di bawah.

// TODO: Register a BroadcastReceiver to listen for activity transitions.
registerReceiver(mTransitionsReceiver, new IntentFilter(TRANSITIONS_RECEIVER_ACTION));

Sekarang kita memiliki cara untuk mendapatkan pembaruan saat transisi aktivitas dinaikkan melalui PendingIntent.

Membatalkan pendaftaran BroadcastReceiver

Dalam modul base, telusuri Membatalkan pendaftaran penerima transisi aktivitas saat pengguna keluar dari aplikasi di MainActivity.java. (Terdapat di onStop()).Tempelkan cuplikan di bawah.

// TODO: Unregister activity transition receiver when user leaves the app.
unregisterReceiver(mTransitionsReceiver);

Praktik terbaiknya adalah membatalkan pendaftaran penerima saat Activity dinonaktifkan.

6. Menyiapkan transisi aktivitas dan meminta pembaruan

Untuk mulai menerima update transisi aktivitas, Anda harus mengimplementasikan:

Membuat daftar ActivitiyTransitions yang akan diikuti

Untuk membuat objek ActivityTransitionRequest, Anda harus membuat daftar objek ActivityTransition, yang mewakili transisi yang ingin Anda lacak. Objek ActivityTransition mencakup data berikut:

  1. Jenis aktivitas, diwakili oleh class DetectedActivity. Transition API mendukung aktivitas berikut:
  1. Jenis transisi, diwakili oleh class ActivityTransition. Jenis transisi adalah:

Dalam modul base, telusuri TODO: Tambahkan transisi aktivitas untuk dilacak dalam MainActivity.java. Tambahkan kode di bawah setelah komentar.

// 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());

Kode ini menambahkan transisi yang ingin kita lacak ke daftar yang sebelumnya kosong.

Membuat PendingIntent

Seperti yang disebutkan sebelumnya, kita memerlukan PendingIntent jika ingin mendapatkan pemberitahuan tentang perubahan apa pun di ActivityTransitionRequest. Jadi, sebelum menyiapkan ActivityTransitionRequest, kita perlu membuat PendingIntent.

Dalam modul base, telusuri TODO: Lakukan inisialisasi PendingIntent yang akan dipicu saat transisi aktivitas terjadi dalam MainActivity.java. Tambahkan kode di bawah setelah komentar.

// 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);

Sekarang kita memiliki PendingIntent yang dapat dipicu saat salah satu ActivityTransition terjadi.

Membuat ActivityTransitionRequest dan meminta update

Anda dapat membuat objek ActivityTransitionRequest dengan meneruskan daftar ActivityTransitions ke class ActivityTransitionRequest.

Dalam modul base, telusuri Buat permintaan dan dengarkan perubahan aktivitas di MainActivity.java. Tambahkan kode di bawah setelah komentar.

// 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);

            }
        });

Mari kita tinjau kodenya. Pertama, kita membuat ActivityTransitionRequest dari daftar transisi aktivitas.

ActivityTransitionRequest request = new ActivityTransitionRequest(activityTransitionList);

Selanjutnya, kita mendaftar untuk pembaruan transisi aktivitas dengan meneruskan instance ActivityTransitionRequest dan objek PendingIntent yang kita buat pada langkah terakhir ke metode requestActivityTransitionUpdates(). Metode requestActivityTransitionUpdates() menampilkan objek Task yang dapat Anda periksa kesuksesan atau kegagalannya, seperti yang ditunjukkan dalam blok kode berikutnya:

// 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);

            }
        });

Setelah berhasil mendaftar untuk pembaruan transisi aktivitas, aplikasi Anda akan menerima notifikasi di PendingIntent yang terdaftar. Kita juga menetapkan variabel bahwa pelacakan aktivitas diaktifkan agar kita dapat mengetahui apakah akan menonaktifkan/mengaktifkan jika pengguna mengklik tombol lagi.

Menghapus update saat aplikasi ditutup

Kita harus menghapus update transisi saat aplikasi ditutup.

Dalam modul base, telusuri Berhenti memproses perubahan aktivitas di MainActivity.java. Tambahkan kode di bawah setelah komentar.

// 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);
            }
        });

Sekarang kita perlu memanggil metode yang berisi kode di atas saat aplikasi dimatikan

Dalam modul base, telusuri TODO: Nonaktifkan transisi aktivitas saat pengguna keluar dari aplikasi di MainActivity.java di onPause(). Tambahkan kode di bawah setelah komentar.

// TODO: Disable activity transitions when user leaves the app.
if (activityTrackingEnabled) {
    disableActivityTransitions();
}

Itulah cara melacak perubahan pada transisi aktivitas. Sekarang kita hanya perlu memproses update.

7. Memproses Peristiwa

Saat transisi aktivitas yang diminta terjadi, aplikasi Anda akan menerima callback Intent. Objek ActivityTransitionResult dapat diekstrak dari Intent, yang mencakup daftar objek ActivityTransitionEvent. Peristiwa diurutkan secara kronologis, misalnya, jika aplikasi meminta jenis aktivitas IN_VEHICLE pada transisi ACTIVITY_TRANSITION_ENTER dan ACTIVITY_TRANSITION_EXIT, maka aplikasi akan menerima objek ActivityTransitionEvent saat pengguna mulai mengemudi, dan menerima objek lain lagi saat pengguna bertransisi ke aktivitas lainnya.

Mari kita tambahkan kode untuk menangani peristiwa tersebut.

Dalam modul base, telusuri TODO: Ekstrak informasi transisi aktivitas dari pemroses di MainActivity.java di onReceive()dari BroadcastReceiver yang kita buat sebelumnya. Tambahkan kode di bawah setelah komentar.

// 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);
    }
}

Tindakan ini akan mengonversi informasi menjadi String dan mencetaknya ke layar.

Selesai. Coba jalankan aplikasi.

CATATAN PENTING: Sulit untuk mereproduksi perubahan aktivitas di emulator, jadi sebaiknya gunakan perangkat fisik.

Anda seharusnya dapat melacak perubahan aktivitas.

Untuk hasil terbaik, instal aplikasi di perangkat fisik dan berjalan-jalan. :)

8. Meninjau Kode

Anda telah mem-build aplikasi sederhana yang melacak transisi Aktivitas dan mencantumkannya di layar.

Jangan ragu untuk membaca seluruh kode guna meninjau apa saja yang telah Anda lakukan dan dapatkan ide yang lebih baik tentang cara kerja kode tersebut.