Categories: Android

AlarmManager android studio berjalan di background

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

Bagikan
rasupe

View Comments

Recent Posts

CPU usage tinggi pada server

Bismillaahirrohmaanirrohiim... Untuk mendeteksi cpu usage tinggi memang perkara rumit, adakalanya karena codingan bermasalah, akses ke…

2 months ago

Membersihkan log mongodb yang besar

Bismillaahirrohmaanirrohiim... Jika tidak dirawat dan dicek berkala, log mongodb akan semakin membesar. Bahkan sampai menghabiskan…

2 months ago

Cara mengakses gps di HP dengan javascript

Bismillaahirrohmaanirrohiim... Jika kita membuat website yang digunakan untuk memantau lokasi HP client, maka kita memerlukan…

5 months ago

Menghitung jarak dua titik koordinat dengan php dan javascript

Bismillaahirrohmaanirrohiim... Kali ini kita akan mencoba menerapkan rumus trigonometeri dari formula haversine, yang digunakan untuk…

5 months ago

Kemasan cleo botol kecil sering bikin tangan terluka

Bismillaahirrohmaanirrohiim... Disini saya akan berbagi pengalaman tentang susahnya membuka tutup botol cleo kecil ukuran 220ml.…

5 months ago

Solusi InsCek pada meteran PLN

Bismillaahirrohmaanirrohiim... Kali ini saya akan berbagi pengalaman tentang mati lampu yang disebabkan oleh permasalahan arus…

5 months ago