Does anybody know why this event doesn't trigger?

I'm building an AlarmManager that triggers an event, here's the code:


package com.damiano.alarm;

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.os.Build;
import android.util.Log;
import android.widget.Toast;

import androidx.core.app.NotificationCompat;
import androidx.core.app.NotificationManagerCompat;

import com.google.appinventor.components.annotations.SimpleEvent;
import com.google.appinventor.components.annotations.SimpleFunction;
import com.google.appinventor.components.runtime.AndroidNonvisibleComponent;
import com.google.appinventor.components.runtime.ComponentContainer;
import com.google.appinventor.components.runtime.EventDispatcher;

import java.util.Calendar;

public class Alarm extends AndroidNonvisibleComponent {
    private AlarmManager alarmManager;
    private PendingIntent pendingIntent;
    private Context context;
    private static Alarm instance;

    public Alarm(ComponentContainer container) {
        super(container.$form());
        context = container.$context();
        alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
        instance = this;

        // Crea un canale di notifica se non esiste
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            NotificationChannel channel = new NotificationChannel(
                "ALARM_CHANNEL",
                "Alarm Notifications",
                NotificationManager.IMPORTANCE_HIGH
            );
            NotificationManager manager = context.getSystemService(NotificationManager.class);
            manager.createNotificationChannel(channel);
        }
    }

    @SimpleFunction(description = "Set a repeating alarm at the specified hour and minute, repeating every day.")
    public void setRepeatingAlarm(int hour, int minute) {
        // Ottieni l'istanza del Calendar e imposta l'orario per l'allarme
        Calendar calendar = Calendar.getInstance();
        calendar.setTimeInMillis(System.currentTimeMillis());
        calendar.set(Calendar.HOUR_OF_DAY, hour);
        calendar.set(Calendar.MINUTE, minute);
        calendar.set(Calendar.SECOND, 0);

        // Crea un PendingIntent per il BroadcastReceiver
        Intent intent = new Intent(context, AlarmReceiver.class);
        pendingIntent = PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_IMMUTABLE);

        // Imposta l'allarme per ripetersi ogni giorno
        alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), AlarmManager.INTERVAL_DAY, pendingIntent);

        // Log e notifica dell'allarme impostato
        String formattedTime = String.format("%02d:%02d", hour, minute);
        Log.d("Alarm", "Repeating alarm set for " + formattedTime);
        Toast.makeText(context, "Repeating alarm set for " + formattedTime, Toast.LENGTH_SHORT).show();
    }

    @SimpleEvent(description = "Event triggered when the alarm goes off.")
    public void AlarmTriggered() {
        Log.d("Alarm", "AlarmTriggered event fired!");
        EventDispatcher.dispatchEvent(this, "AlarmTriggered");
    }

    @SimpleFunction(description = "Cancel the currently set alarm.")
    public void cancelAlarm() {
        if (alarmManager != null) {
            alarmManager.cancel(pendingIntent);
            Toast.makeText(context, "Alarm cancelled", Toast.LENGTH_SHORT).show();
        }
    }

    public static class AlarmReceiver extends BroadcastReceiver {
        @Override
        public void onReceive(Context context, Intent intent) {
            Log.d("AlarmReceiver", "Alarm received!");

            // Mostra una notifica quando l'allarme viene attivato
            NotificationCompat.Builder builder = new NotificationCompat.Builder(context, "ALARM_CHANNEL")
                .setSmallIcon(android.R.drawable.ic_dialog_info)
                .setContentTitle("Alarm")
                .setContentText("Your alarm is triggered!")
                .setPriority(NotificationCompat.PRIORITY_HIGH)
                .setAutoCancel(true);

            NotificationManagerCompat notificationManager = NotificationManagerCompat.from(context);
            notificationManager.notify(1, builder.build());

            // Mostra un Toast per confermare l'attivazione dell'allarme
            Toast.makeText(context, "Alarm triggered!", Toast.LENGTH_SHORT).show();

            // Attiva l'evento in MIT App Inventor
            if (instance != null) {
                instance.AlarmTriggered();
            }
        }
    }
}

Here's the AndroidManifest.xml:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.damiano.alarm">

    <!-- Permessi necessari -->
    <uses-permission android:name="android.permission.WAKE_LOCK"/>
    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
    <uses-permission android:name="android.permission.SCHEDULE_EXACT_ALARM"/>
    <uses-permission android:name="android.permission.USE_EXACT_ALARM"/>

    <application>
        <!-- Dichiarazione del BroadcastReceiver -->
        <receiver android:name=".Alarm$AlarmReceiver" android:exported="true"/>
    </application>
</manifest>

What version of Android are you on? For newer versions I believe you have to request permission from the user to use exact alarms. It might be that not having this permission silently prevents your alarm from being scheduled.

1 Like

Thank you for your answer, but this is old code, i continued working on this project and I believe i fixed this issue. This topic can be closed.

1 Like