8.2: Alarm Manager

Daftar Isi:

Dalam praktik sebelumnya, Anda telah mempelajari cara membuat aplikasi merespons interaksi pengguna dengan menekan tombol atau mengetuk notifikasi. Anda juga belajar cara membuat aplikasi merespons peristiwa sistem menggunakan BroadcastReceivers. Namun bagaimana jika aplikasi perlu mengambil tindakan pada waktu yang spesifik, seperti pada kasus notifikasi kalender? Dalam kasus ini, Anda perlu menggunakan AlarmManager, kelas yang mengizinkan Anda meluncurkan dan mengulangi PendingIntent pada waktu dan interval yang spesifik.

Dalam praktik ini Anda akan membuat timer yang akan mengingatkan Anda untuk berdiri jika sudah duduk terlalu lama.

Yang harus sudah Anda KETAHUI

Dari praktik sebelumnya, Anda harus sudah bisa:

  • Mengimplementasikan listener onCheckChanged untuk tombol toggle.
  • Menyiapkan intent siaran khusus.
  • Menggunakan penerima siaran.
  • Mengirimkan notifikasi.

Yang akan Anda PELAJARI

Anda akan belajar:

  • Menjadwalkan alarm berulang dengan AlarmManager.
  • Memeriksa apakah Alarm sudah disiapkan.
  • Membatalkan alarm berulang.

Yang akan Anda LAKUKAN

Dalam praktik ini Anda akan:

  • Menyetel alarm berulang untuk memberi tahu Anda setiap lima belas menit.
  • Menggunakan ToggleButton untuk menyetel dan melacak alarm.
  • Menggunakan pesan Toast untuk memberitahukan pengguna saat Alarm diaktifkan atau dinonaktifkan.

Ringkasan Aplikasi

Stand Up! adalah aplikasi yang membantu Anda tetap sehat dengan mengingatkan Anda untuk berdiri dan berjalan-jalan setiap sekitar lima belas menit. Aplikasi ini menggunakan notifikasi untuk memberi tahu Anda ketika lima belas menit sudah berlalu. Aplikasi menyertakan tombol alih yang dapat mengaktifkan dan menonaktifkan alarm.

Pratinjau Notifikasi dalam StandUp! Aplikasi Pratinjau Stand Up! Aplikasi

Tugas 1. Menyiapkan Stand Up! Proyek dan Tampilan

1.1 Membuat Stand Up! Layout proyek

  1. Membuat proyek baru bernama "Stand Up!, menerima opsi default dan menggunakan template aktivitas kosong.
  2. Hapus TextView default dan tambahkan elemen berikut:

    TextView

    Atribut

    Nilai

    android:layout_width

    "wrap_content"

    android:layout_height

    "wrap_content"

    android:layout_above

    "@+id/alarmToggle"

    android:layout_centerHorizontal

    "true"

    android:layout_margin

    "8dp"

    android:text

    "Stand Up Alarm"

    android:textAppearance

    @style/TextAppearance.AppCompat.Headline

    ToggleButton

    Atribut

    Nilai

    android:id

    "@+id/alarmToggle"

    android:layout_width

    "wrap_content"

    android:layout_height

    "wrap_content"

    android:layout_centerHorizontal

    "true"

    android:layout_centerVertical

    "true"

1.2 Menyiapkan metode setOnCheckedChangeListener()

Aplikasi Stand Up! memiliki tombol alih yang digunakan untuk menyetel dan membatalkan alarm, sekaligus tampak mewakili status alarm saat ini. Untuk menyetel alarm saat tombol alih diaktifkan, Anda perlu menggunakan metode onCheckedChangeListener():

  1. Dalam metode MainActivity onCreate(), temukan Alarm Toggle menurut id.
  2. Panggil setOnCheckedChangeListener() pada instance tombol alih, dan mulai mengetik "new OnCheckedChangeListener". Android Studio akan menyelesaikan metode untuk Anda secara otomatis, termasuk metode penggantian onCheckedChanged() yang diperlukan. Metode ini memiliki dua parameter: CompoundButton yang diklik (dalam kasus ini tombol Toggle Alarm), dan boolean yang mewakili status Tombol Toggle saat ini (yakni, apakah tombol alih saat ini diaktifkan atau dinonaktifkan).

    alarmToggle.setOnCheckedChangeListener(
       new CompoundButton.OnCheckedChangeListener() {
    
       @Override
       public void onCheckedChanged(CompoundButton compoundButton,
            boolean isChecked) {
       }
    });
    
  3. Akan sangat berguna jika pengguna menerima masukan selain tombol alih yang diaktifkan dan dinonaktifkan untuk menujukkan bahwa alarm memang disetel (Anda belum mengimplementasikan alarm, ini akan dilakukan pada bagian berikutnya). Setel blok if/else menggunakan parameter boolean dalam metode onCheckedChanged() yang mengirimkan pesan toast untuk memberi tahu pengguna apakah alarm diaktifkan atau dinonaktifkan. Jangan lupa untuk mengekstrak sumber daya string.

    String toastMessage;
    if(isChecked){
       //Set the toast message for the "on" case
       toastMessage = getString(R.string.alarm_on_toast);
    } else {
       //Set the toast message for the "off" case
       toastMessage = getString(R.string.alarm_off_toast);
    }
    
    //Show a toast to say the alarm is turned on or off
    Toast.makeText(MainActivity.this, toastMessage, Toast.LENGTH_SHORT)
           .show();
    

Tugas 2. Menyiapkan Notifikasi

Langkah berikutnya adalah membuat notifikasi yang akan mengingatkan pengguna untuk berdiri setiap lima belas menit. Untuk sekarang, notifikasi akan dikirimkan segera setelah tombol alih disetel.

2.1 Membuat notifikasi

Pada langkah ini Anda akan membuat metode deliverNotification() yang akan mengeposkan pengingat untuk berdiri dan berjalan-jalan.

  1. Buat variabel anggota dalam MainActivity bernama mNotificationManager dari tipe NotificationManager.
  2. Inisialisasikan dalam onCreate() dengan memanggil getSystemService():
    mNotificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
    
  3. Buat metode MainActivity bernama deliverNotification() yang mengambil Context sebagai argumen dan tidak mengembalikan apa pun.
    private void deliverNotification(Context context) {}
    
  4. Buat konstanta anggota dalam MainActivity bernama NOTIFICATION_ID dan setel ke 0. Aplikasi hanya akan mendapatkan satu notifikasi pada satu waktu, jadi Anda akan menggunakan id notifikasi yang sama untuk semua notifikasi.
    Catatan: ID Notifikasi digunakan untuk membedakan notifikasi dalam aplikasi. Pengelola Notifikasi hanya bisa membatalkan notifikasi yang dikirimkan dari aplikasi agar Anda bisa menggunakan ID yang sama dalam aplikasi yang berbeda.

Intent Konten Notifikasi

  1. Buat Intent dalam onCreate() yang akan Anda gunakan untuk Intent Konten notifikasi:
    Intent contentIntent = new Intent(context, MainActivity.class);
    
  2. Buat PendingIntent dari Intent konten tepat di bawah definisi contentIntent menggunakan metode getActivity(), meneruskan ID notifikasi dan menggunakan FLAG_UPDATE_CURRENT flag:
    PendingIntent contentPendingIntent = PendingIntent.getActivity
       (context, NOTIFICATION_ID, contentIntent, PendingIntent.FLAG_UPDATE_CURRENT);
    
    Catatan: bendera PendingIntent memberi tahu sistem cara menangani situasi saat banyak instance PendingIntent yang sama dibuat (maksudnya berisi intent yang sama). Bendera FLAG_UPDATE_CURRENT memerintahkan sistem untuk menggunakan Intent lama tetapi mengganti data ekstra. Karena Anda tidak memiliki ekstra dalam intent ini, Anda akan menggunakan kembali PendingIntent yang sama berulang-ulang.

Judul dan Teks Notifikasi

  1. Buat sumber daya string dalam file strings.xml bernama notification_title. Setel agar setara dengan "Stand Up Alert".
  2. Buat sumber daya string dalam file strings.xml bernama notification_text. Setel agar setara dengan "You should stand up and walk around now!".

Ikon Notifikasi

  1. Tambahkan aset gambar untuk digunakan sebagai ikon notifikasi (gunakan Image Asset Studio). Pilih ikon apa pun yang Anda rasa cocok untuk alarm ini: Ikon Stand Up

Buat notifikasi

  1. Gunakan NotificationCompat.Builder untuk membuat notifikasi dalam metode deliverNotification()menggunakan judul, teks, ikon, dan intent konten notifikasi di atas.
    NotificationCompat.Builder builder = new NotificationCompat.Builder(context)
       .setSmallIcon(R.drawable.ic_stand_up)
       .setContentTitle(context.getString(R.string.notification_title))
       .setContentText(context.getString(R.string.notification_text))
       .setContentIntent(contentPendingIntent)
    
  2. Setel prioritas Notifikasi ke PRIORITY_HIGH:
    .setPriority(NotificationCompat.PRIORITY_HIGH)
    
  3. Tambahkan opsi ke builder untuk menyetel AutoCancel ke true, dan opsi lainnya untuk menggunakan lampu, suara dan pola getar default:
    .setAutoCancel(true)
    .setDefaults(NotificationCompat.DEFAULT_ALL);
    

Kirim notifikasi

  1. Gunakan NotificationManager untuk mengirimkan notifikasi:
    mNotificationManager.notify(NOTIFICATION_ID, builder.build());
    
  2. Panggil deliverNotification() saat tombol alih alarm diaktifkan, meneruskan konteks aktivitas:
  3. Panggil cancelAll() pada NotificationManager jika tombol alih dinonaktifkan untuk menghapus notifikasi.

    if(isChecked){
       deliverNotification(MainActivity.this);
       //Set the toast message for the "on" case
       toastMessage = getString(R.string.alarm_on_toast);
    } else {
       //Cancel notification if the alarm is turned off
       mNotificationManager.cancelAll();
    
       //Set the toast message for the "off" case
       toastMessage = getString(R.string.alarm_off_toast);
    }
    
  4. Jalankan aplikasi dan periksa apakah notifikasi dikirimkan dengan semua opsi yang diinginkan.

Pada tahap ini tidak ada alarm sama sekali: notifikasi segera dikirimkan saat tombol alih alarm diaktifkan. Dalam bagian ini, Anda akan mengimplementasikan AlarmManager untuk menjadwalkan dan mengirimkan notifikasi setiap 15 menit sekali.

Tugas 3. Membuat Alarm Berulang

Sekarang karena aplikasi sudah dapat mengirimkan notifikasi, waktunya untuk mengimplementasikan komponen utama aplikasi: AlarmManager. Ini adalah kelas yang akan bertanggung jawab untuk mengirimkan pegingat secara berkala agar Anda berdiri. AlarmManager memiliki banyak jenis alarm bawaan, baik alarm satu waktu maupun alarm periodik, alarm eksak atau tidak eksak. Untuk mengetahui selengkapnya tentang jenis-jenis alarm, lihat panduan ini.

AlarmManager, seperti notifikasi, menggunakan PendingIntent sehingga dikirim dengan opsi yang spesifik. Karena hal ini, AlarmManager dapat mengirimkan Intent saat aplikasi tidak berjalan lagi. Dalam aplikasi ini, PendingIntent akan mengirimkan siaran Intent dengan tindakan "Notify".

Intent siaran akan diterima oleh penerima siaran yang mengambil tindakan yang tepat (mengirimkan notifikasi). Diagram proses alarm Stand Up!

AlarmManager dapat memicu peristiwa sekali waktu atau berulang yang terjadi saat perangkat tertidur atau aplikasi tidak berjalan. Peristiwa dapat dijadwalkan dengan pilihan currentTimeMillis() saat menggunakan versi real time (RTC) atau elapsedRealtime() saat menggunakan versi waktu yang sudah berlalu (ELAPSED_REALTIME), dan mengirimkan PendingIntent saat terjadi. Untuk informasi selengkapnya tentang jam berbeda yang tersedia dan informasi tentang cara mengontrol waktu peristiwa, lihat Referensi Developer SystemClock.

3.1 Menyiapkan intent tertunda siaran

AlarmManager bertanggung jawab untuk mengirimkan PendingIntent pada interval waktu yang telah ditentukan. PendingIntent ini akan mengirimkan intent siaran yang memberi tahu aplikasi kapan waktunya untuk memperbarui waktu yang tersisa dalam notifikasi.

  1. Buat konstanta string sebagai variabel anggota dalam MainActivity untuk digunakan sebagai tindakan intent siaran yang akan mengirimkan notifikasi:

    private static final String ACTION_NOTIFY =
        "com.example.android.standup.ACTION_NOTIFY";
    
    Catatan: gunakan nama paket yang berkualitas untuk string Intent, untuk memastikan Siaran unik, dan tidak dapat digunakan secara tidak sengaja oleh aplikasi lain dengan tindakan yang serupa.
  2. Buat Intent bernama notifyIntent dalam onCreate() dengan string khusus sebagai tindakannya:

    Intent notifyIntent = new Intent(ACTION_NOTIFY);
    
  3. Buat PendingIntent notifikasi menggunakan konteks, variabel NOTIFICATION_ID, intent notifikasi baru, dan bendera PendingIntent UPDATE_CURRENT:
    PendingIntent notifyPendingIntent = PendingIntent.getBroadcast
       (this, NOTIFICATION_ID, notifyIntent, PendingIntent.FLAG_UPDATE_CURRENT);
    

3.2 Menyetel alarm berulang

Anda sekarang akan menggunakan AlarmManager untuk mengirimkan Intent siaran setiap 15 menit. Untuk tugas ini, jenis alarm yang tepat adalah alarm tidak eksak berulang yang menggunakan waktu yang sudah lewat dan akan mengaktifkan perangkat jika tertidur. Jam real time tidak relevan di sini, karena kita ingin mengirimkan notifikasi setiap lima belas menit.

  1. Inisialisasi AlarmManager dalam onCreate() dengan memanggil getSystemService():
    AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
    
  2. Dalam metode onCheckedChanged(), panggil setInexactRepeating() pada instance alarm manager saat pengguna mengeklik "ON" pada Alarm (Parameter keduanya adalah true). Anda akan menggunakan alarm setInexactRepeating() karena lebih efisien sumber daya untuk menggunakan penentuan waktu yang tidak tepat (sistem dapat membundel alarm dari beberapa aplikasi yang berbeda) dan alarm tidak perlu pas berulang setiap 15 menit. Metode setInexactRepeating() mengambil 4 argumen:
  3. Jenis alarm. Pada kasus ini Anda menggunakan tipe waktu yang sudah lewat sejak boot, karena hanya waktu relatif yang penting. Anda juga akan mengaktifkan perangkat jika tertidur, sehingga jenis alarmnya adalah ELAPSED_REALTIME_WAKEUP.
  4. Waktu pemicu dalam milidetik. Untuk ini, gunakan waktu yang sudah lewat, plus 15 menit. Untuk mendapatkan waktu yang sudah lewat, Anda bisa memanggil SystemClock.elapsedRealtime(). Lalu Anda bisa menggunakan konstanta AlarmManager untuk menambahkan 15 menit ke waktu yang sudah lewat: AlarmManager.INTERVAL_FIFTEEN_MINUTES.
  5. Interval waktu dalam milidetik. Anda ingin agar notifikasi diposting setiap 15 menit. Anda bisa menggunakan konstanta AlarmManager.INTERVAL_FIFTEEN_MINUTES lagi.
  6. PendingIntent yang akan dikirim. Anda membuat PendingIntent pada tugas sebelumnya.

    long triggerTime = SystemClock.elapsedRealtime()
           + AlarmManager.INTERVAL_FIFTEEN_MINUTES;
    
    long repeatInterval = AlarmManager.INTERVAL_FIFTEEN_MINUTES;
    
    //If the Toggle is turned on, set the repeating alarm with a 15 minute interval
    alarmManager.setInexactRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP,
           triggerTime, repeatInterval, notifyPendingIntent);
    
    Catatan: Karena Anda mengakses instance AlarmManager dan notifyPendingIntent dari kelas bagian dalam yang anonim, Android Studio dapat menjadikan instance ini final. Jika tidak, Anda harus menjadikannya final sendiri.
  7. Hapus panggilan ke deliverNotification() dalam metode onCheckedChanged().

  8. Jika tombol alih alarm dinonaktifkan (dengan mengeklik toggle dalam status ON), batalkan alarm dengan memanggil cancel() pada AlarmManager, yang meneruskan intent tertunda yang digunakan untuk membuat alarm.
    alarmManager.cancel(notifyPendingIntent);
    
    Pertahankan panggilan ke cancelAll() di NotificationManager, karena menonaktifkan tombol alih seharusnya tetap menghapus notifikasi yang ada.

AlarmManager sekarang akan mulai mengirimkan Intent Siaran mulai dari lima belas menit sejak Alarm disetel, dan setiap lima belas menit setelahnya. Aplikasi harus bisa merespons intent ini dengan mengirimkan notifikasi. Pada langkah selanjutnya Anda akan membuat subkelas Penerima Siaran untuk menerima intent siaran dan mengirimkan notifikasi.

3.3 Membuat Penerima Siaran

Penerima Siaran bertanggung jawab untuk menerima intent siaran dari AlarmManager dan bereaksi dengan tepat.

  1. Dalam Android Studio, klik File > New > Other > Broadcast Receiver.
  2. Masukkan AlarmReceiver sebagai namanya, pastikan kotak centang Exported sudah tidak dicentang (untuk memastikan aplikasi lain tidak dapat memanggil Penerima Siaran ini). Anda juga bisa mengubah setelan ini dalam AndroidManifest dengan menyetel atribut android:exported ke false. Android Studio akan membuat subkelas BroadcastReceiver dengan metode yang diperlukan (onReceive()), dan menambahkan penerima ke AndroidManifest. Anda mungkin perlu menambahkan Filter Intent ke tag <receiver> dalam AndroidManifest untuk memilih Intent Siaran masuk yang tepat.
  3. Dalam Manifes Android, buat <intent-filter> tag pembuka dan penutup di antara tag <receiver> buat sebuah item <action> dalam filter maksud dengan android:name disetel ke string tindakan ACTION_NOTIFY khusus yang Anda buat:
    <intent-filter>
        <action android:name="com.example.android.standup.ACTION_NOTIFY" />
    </intent-filter>
    
  4. Salin dan tempel metode deliverNotification() ke metode onReceive() dalam BroadcastReceiver dan panggil dari onReceive(). Pengelola notifikasi dan id notifikasi belum diinisialisasi dalam kelas BroadcastReceiver jadi akan disorot dengan warna merah.
  5. Salin variabel NOTIFICATION_ID dari MainActivity ke dalam kelas BroadcastReceiver.
  6. Inisialisasi NotificationManager di awal metode onReceive(). Anda harus memanggil getSystemService() dari yang diteruskan dalam Konteks:
    NotificationManager notificationManager = (NotificationManager)
       context.getSystemService(Context.NOTIFICATION_SERVICE);
    
  7. Hapus baris yang memunculkan UnsupportedOperationException.
  8. Jalankan aplikasi Anda. Jika tidak ingin menunggu lima belas menit untuk melihat notifikasi, Anda bisa mengubah waktu pemicu ke SystemClock.elapsedRealtime() untuk segera melihat notifikasi. Anda juga bisa mengubah interval ke waktu yang lebih singkat untuk memastikan bahwa alarm berulang berfungsi.

Sekarang Anda memiliki aplikasi yang dapat menjadwalkan dan melakukan operasi berulang, bahkan jika aplikasi tidak lagi berjalan. Lanjutkan, keluar dari aplikasi, notifikasi akan tetap dikirimkan. Ada satu komponen terakhir yang akan memastikan pengalaman pengguna yang layak: jika aplikasi ditutup, tombol alih akan disetel ulang ke status nonaktif, bahkan jika alarm sudah disetel. Untuk memperbaikinya, Anda perlu memeriksa status alarm setiap kali aplikasi diluncurkan.

3.5 Memeriksa Status Alarm

Untuk melacak status alarm, Anda memerlukan variabel boolean yang true jika alarm sudah ada, dan false jika belum. Untuk menyetel boolean ini, Anda bisa memanggil PendingIntent.getBroadcast() dengan bendera PendingIntent FLAG_NO_CREATE. Dalam hal ini, PendingIntent dikembalikan jika sudah ada, atau kelas mengembalikan null. Memeriksa apakah alarm sudah disetel sangatlah berguna.

Catatan: Saat Anda membuat PendingIntent, sistem menggunakan metode Intent.filterEquals() untuk menentukan apakah PendingIntent dengan Intent yang sama sudah ada. Ini artinya untuk memiliki PendingIntent yang berbeda, Intent berisi harus berbeda dalam salah satu tindakan, data, tipe, kelas, atau kategori. Ekstra intent tidak termasuk dalam perbandingan. Bendera PendingIntent menentukan apa yang terjadi saat PendingIntent yang Intent-nya cocok dengan yang Anda coba sudah ada. Dalam kasus bendera NO_CREATE, ini akan mengembalikan null kecuali PendingIntent dengan Intent yang cocok sudah ada.
  1. Buat boolean yang benar jika PendingIntent tidak null, dan sebaliknya salah, menggunakan strategi ini. Gunakan boolean untuk menyetel status ToggleButton dengan benar saat aplikasi dimulai. Kode ini harus datang sebelum PendingIntent dibuat, atau kode akan selalu mengembalikan benar:
    boolean alarmUp = (PendingIntent.getBroadcast(this, NOTIFICATION_ID, notifyIntent,
       PendingIntent.FLAG_NO_CREATE) != null);
    
  2. Setel keadaan tombol alih segera setelah Anda mendefinisikan boolean alarmUp:
    alarmToggle.setChecked(alarmUp);
    
    Ini akan memastikan tombol alih selalu diaktifkan jika alarm disetel, dan dinonaktifkan jika tidak. Itu saja. Sekarang Anda memiliki alarm terjadwal yang akan mengingatkan Anda untuk berdiri setiap lima belas menit.
  3. Jalankan aplikasi Anda. Aktifkan alarm. Keluar dari aplikasi. Buka aplikasi lagi. Tombol alarm akan menunjukkan bahwa alarm aktif.

Kode solusi

**Proyek Android Studio: StandUp

Tantangan penyusunan kode

Catatan:Semua tantangan penyusunan kode opsional dan bukan prasyarat untuk pelajaran berikutnya.

Kelas AlarmManager juga menangani jam alarm untuk fungsi yang biasa, misalnya yang membangunkan Anda di pagi hari. Pada perangkat yang menjalankan API 21+, Anda bisa mendapatkan informasi tentang jam alarm jenis ini berikutnya dengan memanggil getNextAlarmClock() pada pengelola alarm.

Tambahkan tombol ke aplikasi yang menampilkan waktu jam alarm berikutnya, yang telah disetel pengguna dalam pesan Toast.

Rangkuman

  • AlarmManager mengizinkan Anda untuk menjadwalkan tugas berdasarkan jam real time atau waktu yang sudah lewat sejak booting.
  • AlarmManager menyediakan berbagai jenis alarm, yang periodik dan sekali waktu, dengan opsi untuk mengaktifkan perangkat jika tertidur.
  • AlarmManager ditujukan untuk situasi saat penentuan waktu yang tepat sangatlah penting (seperti acara kalender). Jika tidak, pertimbangkan framework Penjadwalan Pekerjaan untuk penentuan waktu dan penjadwalan yang lebih efisien sumber daya.
  • Gunakan versi penentuan waktu yang tidak tepat dari AlarmManager kapan pun memungkinkan untuk meminimalkan beban yang disebabkan oleh banyaknya perangkat pengguna atau aplikasi yang melakukan tugas pada waktu yang bersamaan.
  • AlarmManager menggunakan PendingIntent untuk melakukan operasi, jadi Anda bisa menjadwalkan siaran, layanan, dan aktivitas menggunakan PendingIntent yang tepat.

Konsep terkait

Dokumentasi konsep terkait ada di Dasar-Dasar Developer Android: Konsep.

Ketahui selengkapnya

Dokumentasi Developer Android

Panduan

Referensi

Sumber daya web lainnya

results matching ""

    No results matching ""