Reputation: 3674
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
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