zehata
zehata

Reputation: 3674

Android Class in MainActivity does not receive Broadcast from Alarm Manager

I am trying to use Alarm Manager to send and receive a broadcast that will call a method to create a notification. I want the notification to be created even when app is closed. I created a class with this method that creates the alarm in Alarm Manager:

@android.webkit.JavascriptInterface
public void qotd(String toast, int hour, int minute) {
            // for testing purposes
            Toast.makeText(mContext, (String.valueOf(hour) + " " + String.valueOf(minute)), Toast.LENGTH_SHORT).show();

            // cancel other alarms first
            Intent alarmtocancel = new Intent(mContext, loadqotd.class);
            PendingIntent cancelIntent = PendingIntent.getBroadcast(mContext, 1001, alarmtocancel, PendingIntent.FLAG_CANCEL_CURRENT);
            AlarmManager am = (AlarmManager) getSystemService(mContext.ALARM_SERVICE);
            am.cancel(cancelIntent);
            cancelIntent.cancel();

            // create new alarm
            Intent alarmintent = new Intent(mContext, loadqotd.class);
            AlarmManager setam = (AlarmManager) getSystemService(mContext.ALARM_SERVICE);
            PendingIntent pendingIntent = PendingIntent.getService(mContext, 0, alarmintent, 0);
            Calendar calendar = Calendar.getInstance();
            calendar.setTimeInMillis(System.currentTimeMillis());
            calendar.set(Calendar.HOUR_OF_DAY, hour);
            calendar.set(Calendar.MINUTE, minute);
            setam.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), 24 * 60 * 60 * 1000, pendingIntent);            
}

This is the receiver, I placed it inside Main Activity:

public class loadqotd extends BroadcastReceiver{

    @Override
    public void onReceive(Context context, Intent intent) {
        // testing purposes
        Toast.makeText(context, "received", Toast.LENGTH_SHORT).show();
        Intent resultIntent = new Intent(context, QuestionOfTheDay.class);

        NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(context);

        mBuilder.setSmallIcon(R.drawable.notification_icon)
                        .setContentTitle("Your Question of the Day is ready!")
                        .setContentText("Check out the question of today")
                        .setContentIntent(PendingIntent.getActivity(context, 0, resultIntent, PendingIntent.FLAG_UPDATE_CURRENT));

        int notid = 001;
        NotificationManager notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
        notificationManager.notify(notid, mBuilder.build());
    }
}

This is the manifest:

...
<application>
    <receiver android:name=".MainActivity$loadqotd"></receiver>
</application>
...

I have done an Alarm Manager dump and found the broadcast inside. However, when alarm manager fires, loadqotd is never called, whether when the app is in the background or when in the app. Also, it is neither due to build error or runtime exception.

Upvotes: 1

Views: 408

Answers (1)

Mike M.
Mike M.

Reputation: 39201

When you use a nested class as an app component - like the loadqotd class in your question - it must be public static. Alternatively, you could move that to a separate class file, and update the name in the manifest accordingly.

Either way you choose, you'll need to change a couple of things in the Receiver class. You'll need to call getSystemService() on the Context passed into the onReceive() method, since it was previously being called on the current MainActivity instance, which it will no longer have access to. Also, you'll need to qualify the NOTIFICATION_SERVICE constant.

NotificationManager notificationManager =
    (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);

And, lastly, the PendingIntent for your alarm needs to be a broadcast PendingIntent, since you're broadcasting to a Receiver, not starting a Service. Change getService() to getBroadcast().

PendingIntent pendingIntent = PendingIntent.getBroadcast(mContext, 0, alarmintent, 0);

Upvotes: 1

Related Questions