Bismillaahirrohmaanirrohiim…
Sebelumnya saya ingin membuat sebuah service android yang berjalan pada aplikasi, dimana service tersebut diharapkan akan terus jalan meskipun program di close atau berjalan di background.
Namun ternyata penggunaan service tidak maksimal karena ketika user melakukan “clear recent app” pada HP, service di aplikasi saya tersebut ikutan berhenti berjalan alias coid.
Kemudian saya mencari cara untuk masalah di atas, saya mencoba menggunakan alarmmanager.
Masalah muncul saat penggunaan setRepeating() pada alarmmanager ternyata tidak dijalankan secara konsisten.
Setelah putar sana sini, akhirnya menemukan method setExact() pada alarmmanager, namun ternyata hanya berjalan di versi android Kitkat keatas dan juga hasilnya tetap saja “not exact”.
Karena alarmmanager ketika diset pertama kali dia akan jalan sesuai waktu yang ditentukan, yang jadi masalah hanyalah repeatingnya, maka solusi sederhananya adalah:
Membuat alarmmanager yang didalamnya ada perintah lagi untuk menjalankan alarmmanager lagi dalam BroadcastReceiver.
Kita tidak menggunakan fungsi setRepeating() ataupun setExact(), cukup menggunakan set() dengan pendingIntent yang sama.
mengapa perlu pendingIntent yang sama, karena alarmmanager akan me replace pendingintent tersebut jika terjadi duplikasi alarmmanager yang masih berjalan.
Dari sini kita tahu alasan kenapa google dan android tidak konsisten saat menggunakan setRepeating() ataupun setExact(), tidak lain dan tidak bukan karena ingin menghemat baterai.
Intinya adalah terlalu banyak alarm akan berakibat buruk pada baterai.
Oke, langsung saja kita coba membuat alarmmanager yang dapat berjalan di background yang didalamnya akan manampilkan notification di HP.
Buat project baru di android studio
Isikan nama “Coba AlarmManager” lalu next.
Pilih minimum SDK API 17, Android 4.2 Jelly bean lalu next.
Pilih empty activity lalu next.
Biarkan nilai default “MainActivity” lalu finish.
Tunggu sampai selesai menyiapkan project untuk kita
Edit file MainActivity.java
package com.rasupe.cobaalarmmanager; import android.app.AlarmManager; import android.app.NotificationManager; import android.app.PendingIntent; import android.content.Context; import android.content.Intent; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.view.View; import android.widget.Toast; import java.util.Calendar; public class MainActivity extends AppCompatActivity { private PendingIntent pendingIntent; private static final int ALARM_REQUEST_CODE = 134; //set interval notifikasi 10 detik private int interval_seconds = 10; private int NOTIFICATION_ID = 1; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Intent alarmIntent = new Intent(MainActivity.this, AppReceiver.class); pendingIntent = PendingIntent.getBroadcast(MainActivity.this, ALARM_REQUEST_CODE, alarmIntent, 0); } public void startAlarmManager(View v) { //set waktu sekarang berdasarkan interval Calendar cal = Calendar.getInstance(); cal.add(Calendar.SECOND, interval_seconds); AlarmManager manager = (AlarmManager) getSystemService(Context.ALARM_SERVICE); //set alarm manager dengan memasukkan waktu yang telah dikonversi menjadi milliseconds manager.set(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), pendingIntent); Toast.makeText(this, "AlarmManager Start.", Toast.LENGTH_SHORT).show(); } //Stop/Cancel alarm manager public void stopAlarmManager(View v) { AlarmManager manager = (AlarmManager) getSystemService(Context.ALARM_SERVICE); manager.cancel(pendingIntent); //close existing/current notifications NotificationManager notificationManager = (NotificationManager) getApplicationContext().getSystemService(Context.NOTIFICATION_SERVICE); notificationManager.cancel(NOTIFICATION_ID); //jika app ini mempunyai banyak notifikasi bisa di cancelAll() //notificationManager.cancelAll(); Toast.makeText(this, "AlarmManager Stopped by User.", Toast.LENGTH_SHORT).show(); } }
Edit activity_main.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout 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:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:gravity="center" tools:context=".MainActivity"> <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:text="Coba Alarm Manager Android" android:textAlignment="center" android:textSize="24sp" /> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal" > <Button android:id="@+id/buttonStart" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_weight="1" android:onClick="startAlarmManager" android:text="Start" /> <Button android:id="@+id/buttonStop" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_weight="1" android:onClick="stopAlarmManager" android:text="Stop" /> </LinearLayout> </LinearLayout>
Buat file dengan nama AppReceiver.java
package com.rasupe.cobaalarmmanager; import android.app.AlarmManager; import android.app.NotificationChannel; import android.app.NotificationManager; import android.app.PendingIntent; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.media.RingtoneManager; import android.support.v4.app.NotificationCompat; import java.text.SimpleDateFormat; import java.util.Calendar; import java.util.Date; public class AppReceiver extends BroadcastReceiver { private PendingIntent pendingIntent; private static final int ALARM_REQUEST_CODE = 134; //set interval notifikasi 10 detik private int interval_seconds = 10; private NotificationManager alarmNotificationManager; String NOTIFICATION_CHANNEL_ID = "rasupe_channel_id"; String NOTIFICATION_CHANNEL_NAME = "rasupe channel"; private int NOTIFICATION_ID = 1; @Override public void onReceive(Context context, Intent intent) { Intent alarmIntent = new Intent(context, AppReceiver.class); pendingIntent = PendingIntent.getBroadcast(context, ALARM_REQUEST_CODE, alarmIntent, 0); //set waktu sekarang berdasarkan interval Calendar cal = Calendar.getInstance(); cal.add(Calendar.SECOND, interval_seconds); AlarmManager manager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE); //set alarm manager dengan memasukkan waktu yang telah dikonversi menjadi milliseconds if (android.os.Build.VERSION.SDK_INT >= 23) { manager.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), pendingIntent); } else if (android.os.Build.VERSION.SDK_INT >= 19) { manager.setExact(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), pendingIntent); } else { manager.set(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), pendingIntent); } //kirim notifikasi sendNotification(context, intent); } //handle notification private void sendNotification(Context context, Intent itn) { SimpleDateFormat sdf = new SimpleDateFormat("dd MM yyyy HH:mm:ss"); String datetimex = sdf.format(new Date()); String notif_title = "Coba AlarmManager Notif"; String notif_content = "Notif time "+datetimex; alarmNotificationManager = (NotificationManager) context .getSystemService(Context.NOTIFICATION_SERVICE); Intent newIntent = new Intent(context,MainActivity.class); newIntent.putExtra("notifkey", "notifvalue"); PendingIntent contentIntent = PendingIntent.getActivity(context, 0, newIntent, PendingIntent.FLAG_UPDATE_CURRENT); //cek jika OS android Oreo atau lebih baru //kalau tidak di set maka notifikasi tidak akan muncul di OS tersebut if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) { int importance = NotificationManager.IMPORTANCE_HIGH; NotificationChannel mChannel = new NotificationChannel( NOTIFICATION_CHANNEL_ID, NOTIFICATION_CHANNEL_NAME, importance); alarmNotificationManager.createNotificationChannel(mChannel); } //Buat notification NotificationCompat.Builder alamNotificationBuilder = new NotificationCompat.Builder(context, NOTIFICATION_CHANNEL_ID); alamNotificationBuilder.setContentTitle(notif_title); alamNotificationBuilder.setSmallIcon(R.mipmap.ic_launcher); alamNotificationBuilder.setSound(RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION)); alamNotificationBuilder.setContentText(notif_content); alamNotificationBuilder.setAutoCancel(true); alamNotificationBuilder.setContentIntent(contentIntent); //Tampilkan notifikasi alarmNotificationManager.notify(NOTIFICATION_ID, alamNotificationBuilder.build()); } }
Edit AndroidManifest.xml
Tambahkan permisi untuk WAKE_LOCK
<uses-permission android:name="android.permission.WAKE_LOCK" />
Tambahkan tag receiver
<receiver android:name=".AppReceiver" android:enabled="true" android:exported="true" />
Sehingga file AndroidManifest.xml akan seperti di bawah ini:
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.rasupe.cobaalarmmanager"> <uses-permission android:name="android.permission.WAKE_LOCK" /> <application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" android:theme="@style/AppTheme"> <activity android:name=".MainActivity" android:launchMode="singleTop"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <receiver android:name=".AppReceiver" android:enabled="true" android:exported="true" /> </application> </manifest>
Semua kode di atas, untuk package com.rasupe.cobaalarmmanager;
sesuaikan dengan nama paket anda.
Keterangan penjelasan kode langsung saya isikan didalam kodenya.
Oke, kalau sudah silahkan dijalankan, dan semoga tidak error heheh.
klik tombol “Start” untuk menjalankan alarmmanager, jika ingin menghentikannya tekan tombol “Stop”
Meskipun program di close ataupun di “clear recent app”, alarm manager tersebut akan tetap jalan di background.
Demikian tutorial singkat tentang menggunakan alarmmanager di android studio.
Jika ada yang ingin disampaikan, silahkan tinggalkan di kolom komentar.
Terimakasih
Kalau Mau buat multiple notif gimana mas?
Contoh Kasusnya user bisa menambahkan pengingat sendiri
untuk membuat multi notif NOTIFICATION_ID diganti dengan id yg dinamis, misalkan 1, 2, 3 dst.
Di HP sy stelah tap START hanya muncul toast ‘AlarmManager Start’.
Output lainnya berupa apa ya, pak? Tidak ada notif.
Trima kasih.
Harusnya muncul notifikasi di HP nya gan.
sy test begini :
//sendNotification(context, intent);
//test notif pakai toast
Toast.makeText(context, “Coba output lainnya berupa toast”, Toast.LENGTH_SHORT).show();
Halo gan. Mau tanya, method ini bisa dipake untuk monitoring suatu value ngga? If value > xxxx . Panggil function notif?
Coba ditaruh di AppReceiver kondisinya, if value lalu dipanggil sendNotification.
mas aku pake rest api, nah aku mau setiap kali ada penambahan data pada tabel itu muncul alarmnya, itu gimana ya mas, ada tutorial nggak? aku bingung ngodingnya..
Kalau ingin saat ada penambahan data kemudian mengirim notifikasi, pakai onesignal saja.
baca dulu di https://rasupe.com/cara-membuat-push-notifications-di-android-dengan-onesignal-mudah/
mass Kalo Mau buat alarmnya jadi berbunyi gmna ya?
ditambahin audio gan, pakai component mediaplayer
kenapa ya ka di hp vivo saya, kalau di close repeating nya berhenti ?
coba setting di app permission, app nya di ijinkan untuk berjalan di background.
Mas aku barusan ikutin alhamdulillah luar biasa berkah ilmunya, running well, saya ada pertanyaan apakah cara ini baik kalau untuk dijadikan misal cek status koneksi mas? akan jadi draining battery nggak ya? makasih, dan kalau dimasukin start pass restart hp apakah bisa?
kalau ceknya di schedule agak lama harusnya ga draining baterai, cuma cek koneksi internet saja. kecuali prosesnya banyak dan membebani ram besar.
nah, utk menjalankan program setelah boot, bisa dengan menambahkan di AndroidManifest.xml uses-permission android:name=”android.permission.RECEIVE_BOOT_COMPLETED” />
lengkapnya ada di https://stackoverflow.com/questions/6391902/how-do-i-start-my-app-on-startup