Well in my app I am trying the following functionality. I want depending on the date and the time, the user to receiver some notifications.
For example:
September 9, 19.13 receive notification with message1
September 10, 07.30, with message 2,
same day, but 11.50, with message 3 and so on...
I used an alarm and a push bar notification but it worked only for the first one. So I serached for that and is is stated that I must use a repeating alarm manager.
Before I post my code I want to clarify some things:
1) I am thinking it that it should work like that:
i must check every 1-2 min, what time is it, fetch my next "time" from an array that events are stored, and set ana alarm for that, right? Then given that this bynch of code will run every 1-2 minutes, i will check again, fetch the next event,set alarm for that time and so on.
Am I correct?
So to begin with, i am trying to implement a repeating alarm manager which every 1 min will display me a Toast message (If I do this and replacing the toast message with get_next_event() and set_next_notification() will do the job I think. - These function are working fine in my project with only one alarm being set).
But problem is that when I am starting my service I see nothing.
here is my code:
Alarm.java
public class Alarm extends BroadcastReceiver
{
#Override
public void onReceive(Context context, Intent intent)
{
Toast.makeText(context, "Starting Alarm Manager", Toast.LENGTH_LONG).show(); // For example
PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
PowerManager.WakeLock wl = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "");
wl.acquire();
// Put here YOUR code.
Toast.makeText(context, "Alarm !!!!!!!!!!", Toast.LENGTH_LONG).show(); // For example
wl.release();
}
public void SetAlarm(Context context)
{
Toast.makeText(context, "Setting Alarm Manager", Toast.LENGTH_LONG).show(); // For example
AlarmManager am=(AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
Intent i = new Intent(context, Alarm.class);
PendingIntent pi = PendingIntent.getBroadcast(context, 0, i, 0);
am.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(), 1000 * 60 , pi); // Millisec * Second * Minute
}
public void CancelAlarm(Context context)
{
Intent intent = new Intent(context, Alarm.class);
PendingIntent sender = PendingIntent.getBroadcast(context, 0, intent, 0);
AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
alarmManager.cancel(sender);
}
YourService.java
public class YourService extends Service
{
Alarm alarm = new Alarm();
public void onCreate()
{
super.onCreate();
Toast.makeText(YourService.this, "Service Created", Toast.LENGTH_LONG).show(); // For example
}
public void onStart(Context context,Intent intent, int startId)
{
Toast.makeText(YourService.this, "Setting from Service", Toast.LENGTH_LONG).show(); // For example
alarm.SetAlarm(context);
}
#Override
public IBinder onBind(Intent intent)
{
return null;
}
}
DemoActivity.java
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
buttonStart = (Button) findViewById(R.id.buttonStart);
buttonStop = (Button) findViewById(R.id.buttonStop);
buttonStart.setOnClickListener(this);
buttonStop.setOnClickListener(this);
}
public void onClick(View src) {
switch (src.getId()) {
case R.id.buttonStart:
Toast.makeText(ServicesDemo.this, "Button Pressed", Toast.LENGTH_LONG).show(); // For example
Log.d(TAG, "onClick: starting srvice");
startService(new Intent(this, YourService.class));
break;
case R.id.buttonStop:
Log.d(TAG, "onClick: stopping srvice");
stopService(new Intent(this, YourService.class));
break;
}
}
So i press the button, I see that "button is pressed" , i see that "service created" but then none of the toasts that alarm started are being shown. And of course, I see nothing every 1 min.
here is my manifest.
<application android:icon="#drawable/ic_launcher" android:label="#string/app_name">
<activity android:name=".ServicesDemo" android:label="#string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service android:enabled="true" android:name=".YourService" />
<receiver android:process=":remote" android:name="Alarm"></receiver>
</application>
<uses-sdk android:minSdkVersion="8" />
<uses-permission android:name="android.permission.WAKE_LOCK"></uses-permission>
</manifest>
So what do I need to change in my code or in the manifest?
I suggest you to use AlarmManager for this: http://developer.android.com/reference/android/app/AlarmManager.html .
Related
I am writing my first app and I'm trying to fire a notification at a specific time every day that reports some information.
For starter, I created the following class that I use to restart the alarms after a reboot and to start the alarms from the main app (this to have just one piece of code to reuse).
public class SetAlarmReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
startReminderService(context);
}
public void checkServiceRunning(Context context) {
Intent reminderIntent = new Intent(context, AlarmReceiver.class);
reminderIntent.setAction("MyReminder");
// I check if a reminder is already active
boolean reminderActive = (PendingIntent.getBroadcast(context, REMINDER_SERVICE,
reminderIntent,
PendingIntent.FLAG_NO_CREATE) != null);
Log.d("test", "The reminder is active?" + reminderActive);
if (!reminderActive) {
startReminderService(context);
}
}
public void startReminderService(Context context) {
Calendar serviceNotificationTime = Calendar.getInstance();
serviceNotificationTime.set(Calendar.HOUR_OF_DAY, 9);
serviceNotificationTime.set(Calendar.MINUTE, 0);
serviceNotificationTime.set(Calendar.SECOND, 0);
Intent reminderIntent = new Intent(context, AlarmReceiver.class);
reminderIntent.setAction("MyReminder");
PendingIntent pendingIntent = PendingIntent.getBroadcast(
context,
REMINDER_SERVICE,
reminderIntent,
PendingIntent.FLAG_CANCEL_CURRENT);
AlarmManager serviceAlarmManager = (AlarmManager) context.getSystemService(ALARM_SERVICE);
serviceAlarmManager.setRepeating(
AlarmManager.RTC_WAKEUP,
serviceNotificationTime.getTimeInMillis(),
AlarmManager.INTERVAL_DAY,
pendingIntent);
if (pendingIntent != null) {
Log.d("test", "Background service set up and running.");
} else {
Log.d("test", "Failed to set up background service!");
}
}
}
After that I updated the manifest with the following lines:
<receiver
android:name="com.mycompany.myapp.services.SetAlarmReceiver"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
<receiver
android:name="com.mycompany.myapp.services.AlarmReceiver"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="MyReminder" />
</intent-filter>
</receiver>
So far, everything goes right. When the phone reboots, the reminder is correctly restarted and (if the reminder time is in the past) it fires immediately.
The AlarmReceiver class is the following:
public class AlarmReceiver extends BroadcastReceiver {
private Context ctx;
#Override
public void onReceive(Context context, Intent intent) {
this.ctx = context;
remindStuff();
}
private void remindStuff() {
....
some code
....
// I check if the alarm is still on (probably awful, since it just fired)
SetAlarmReceiver setAlarmReceiver = new SetAlarmReceiver();
setAlarmReceiver.checkServiceRunning(ctx);
}
}
I use the same approach to check if the alarm is on from the main activity:
private void checkServicesRunning() {
SetAlarmReceiver setAlarmReceiver = new SetAlarmReceiver();
setAlarmReceiver.checkServiceRunning(getApplicationContext());
}
Everything looks correct to me, I've tried any solution I found, reading tons of questions like mine on StackOverflow but I still can't understand what I'm doing wrong.
The alarm fires correctly right after BOOT_COMPLETED is triggered by the system and it fires correctly when I just enabled the alarm (only if the notification time is in the past - f.e. when it's 10pm and the alarm must fire at 9am).
When the checkServiceRunning method runs, it tells me that the alarm is already enabled (returning true in the Logcat) but when I close the app and I re-run it after a while, the alarm looks like it's been canceled and it's being recreated by the app.
Any hint?
Thanks.
EDIT: I tried the command 'adb shell dumpsys alarm' and it actually shows my alarm running correctly so, at this point, I think the issue is something else but I cannot understand what...
I'm building an alarm application which will have an exact repeating alarm.
Seeing how for Repeating Android provides only Inexact alarm with possible delay of 75% of chosen interval, I've tried making Exact alarm which upon triggering sets itself once again. This type of alarm works perfectly as long as my screen is kept on. But as soon as it goes to sleep, the alarm works fine the first time, but second alarm which is set programmaticaly fires with delay as if I was using Inexact method.
As an alternative solution I'm thinking of making an InexactRepeating alarm which will fire up every minute to check whether it's "the time". This way my alarm will be with 2 minute imprecision interval, which is acceptable. But I'm not sure how much it will strain phone's battery.
Any ideas guys?
Here's my attemp at Exact alarm:
AlarmManager.java
public static void setAlarm(Context context){
AlarmManager alarmManager = (AlarmManager) context.getSystemService(context.ALARM_SERVICE);
//SET BROADCAST RECEIVER WHICH WILL BE THE ONE TO LISTEN FOR THE ALARM SIGNAL
Intent intent = new Intent(context, AlarmTriggerBroadcastReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 22222, intent, PendingIntent.FLAG_CANCEL_CURRENT);
//SETING THE ALARM
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
alarmManager.setExact(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + 300000, pendingIntent);
} else {
alarmManager.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + 300000, pendingIntent);
}
}
AlarmTriggerBroadcastReceiver.java
public class AlarmTriggerBroadcastReceiver extends BroadcastReceiver {
private final static String TAG_ALARM_TRIGGER_BROADCAST = "ALARM_TRIGGER_BROADCAST";
#Override
public void onReceive(Context context, Intent intent) {
//WAKE UP DEVICE
WakeLocker.acquire(context);
//LAUNCH PAGE
Intent intent1 = new Intent();
intent1.setClassName(context.getPackageName(), SomeActivity.class.getName());
intent1.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(intent1);
Toast.makeText(context, "TOAST ALARM", Toast.LENGTH_LONG).show();
};
//SET NEW ALARM
AlarmManagerActivity.setAlarm(context);
WakeLocker.release();
}
}
WakeLocker.java
//WAKES UP DEVICE IF PHONE'S SCREEN LOCKED
public abstract class WakeLocker {
private static PowerManager.WakeLock wakeLock;
public static void acquire(Context ctx) {
//if (wakeLock != null) wakeLock.release();
PowerManager pm = (PowerManager) ctx.getSystemService(Context.POWER_SERVICE);
wakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK |
PowerManager.ACQUIRE_CAUSES_WAKEUP |
PowerManager.ON_AFTER_RELEASE, "myapp:WAKE_LOCK_TAG");
wakeLock.acquire();
}
public static void release() {
if (wakeLock != null) wakeLock.release(); wakeLock = null;
}
}
Manifest
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="com.android.alarm.permission.SET_ALARM"/>
<uses-permission android:name="android.permission.SET_ALARM"/>
<receiver
android:name=".Alarm.AlarmTriggerBroadcastReceiver"
android:process=":remote">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED"></action>
</intent-filter>
<intent-filter android:priority="1">
<action android:name="my.app.here.ALARM_RECIEVED" />
</intent-filter>
</receiver>
What do, fellow coders?
have you tried using a WorkManager instead of having to use the Broadcast Receivers? See details here. And an app demo here.
I am trying to create a service and set an alarm through it. I need to run the service in background to keep the broadcaster reciever running even if the app is closed. I tried using START_STICKY, running service in a separate child process as well as a global process, all in vain. What should I do ?
Alarm.java
package com.simpleapps.simpleweather;
import ...
public class Alarm extends BroadcastReceiver
{
#Override
public void onReceive(Context context, Intent intent)
{
ToneGenerator toneGen1 = new ToneGenerator(AudioManager.STREAM_MUSIC, 100);
toneGen1.startTone(ToneGenerator.TONE_CDMA_PIP,150);
Toast.makeText(context, "Alarm !!!!!!!!!!", Toast.LENGTH_LONG).show();
}
public void setAlarm(Context context)
{
Log.d("Alarm","Started");
AlarmManager am =( AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
Intent i = new Intent(context, Alarm.class);
PendingIntent pi = PendingIntent.getBroadcast(context, 0, i, 0);
am.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(), 1000 * 60, pi); // Millisec * Second * Minute
}
public void cancelAlarm(Context context)
{
Intent intent = new Intent(context, Alarm.class);
PendingIntent sender = PendingIntent.getBroadcast(context, 0, intent, 0);
AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
alarmManager.cancel(sender);
}
}
HelloService.java
package com.simpleapps.simpleweather;
import ...
public class HelloService extends Service
{
Alarm alarm = new Alarm();
public void onCreate()
{
super.onCreate();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId)
{
Log.d("Alarm","New Service");
alarm.setAlarm(this);
return START_STICKY;
}
#Override
public void onStart(Intent intent, int startId)
{
alarm.setAlarm(this);
}
#Override
public IBinder onBind(Intent intent)
{
return null;
}
}
Manifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.simpleapps.simpleweather">
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WAKE_LOCK"/>
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".today_details" />
<activity android:name=".forecast_details"/>
<receiver android:process=":remote" android:name=".Alarm" android:exported="true">
</receiver>
<service
android:name=".HelloService"
android:enabled="true">
</service>
</application>
</manifest>
Starting Service -
Intent intent = new Intent(this, HelloService.class);
startService(intent);
Update : It is working on every device except my Lollipop 5.0 device AsusZenfone2
I've tried your code and it's working ok on the emulator. One thing I've notice is that:
* setRepeating
* <b>Note:</b> Beginning in API 19, the trigger time passed to this method
* is treated as inexact: the alarm will not be delivered before this time, but
* may be deferred and delivered some time later. The OS will use
* this policy in order to "batch" alarms together across the entire system,
* minimizing the number of times the device needs to "wake up" and minimizing
* battery use. In general, alarms scheduled in the near future will not
* be deferred as long as alarms scheduled far in the future.
So I've change the Alarm to look like so (It's just illustration, you could do it without static fields):
public class Alarm extends BroadcastReceiver
{
private static boolean sAlarmCanceled = false;
#Override
public void onReceive(Context context, Intent intent)
{
if (sAlarmCanceled)
return;
ToneGenerator toneGen1 = new ToneGenerator(AudioManager.STREAM_MUSIC, 100);
toneGen1.startTone(ToneGenerator.TONE_CDMA_PIP,150);
Toast.makeText(context, "Alarm !!!!!!!!!!", Toast.LENGTH_SHORT).show();
scheduleNextAlarm(context);
}
public static void enableAlarm(Context context) {
sAlarmCanceled = false;
scheduleNextAlarm(context);
}
public static void disableAlarm() {
sAlarmCanceled = true;
}
private static void scheduleNextAlarm(Context context)
{
AlarmManager am =( AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
Intent i = new Intent(context, Alarm.class);
PendingIntent pi = PendingIntent.getBroadcast(context, 0, i, PendingIntent.FLAG_ONE_SHOT);
am.set(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + 10000, pi);
}
}
And now it get executed precisely every 10 sec. Service runs normal and I was able to remove Application task and see the alarm anyway.
I've an alarm which opens an activity at a time chosen by the user. If the user hits the start button, the alarm goes fine but it gets cancelled after reboot. I've looked everywhere and it says that I should use a service. Is it possible to keep the alarms on after the reboot without using service? I'm new to coding so can you please breakdown what I need to do. Thank you
public class MainActivity extends AppCompatActivity {
Button disable;
Button start;
TimePicker timePicker;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
timePicker = (TimePicker) findViewById(R.id.timePicker);
disable = (Button) findViewById(R.id.disable_alarm);
start = (Button) findViewById(R.id.button);
start.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.HOUR_OF_DAY, timePicker.getHour());
calendar.set(Calendar.MINUTE, timePicker.getMinute());
Intent intent = new Intent(getApplicationContext(),notification.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(getApplicationContext(), 100, intent, PendingIntent.FLAG_UPDATE_CURRENT);
AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), 120*1000, pendingIntent);
}
});
disable.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent intent = new Intent(getApplicationContext(),notification.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(getApplicationContext(), 100, intent, PendingIntent.FLAG_UPDATE_CURRENT);
AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
alarmManager.cancel(pendingIntent);
}
});
and Broadcast Receiver is
public class notification extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Intent scheduledIntent = new Intent(context, pop_up2.class);
scheduledIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(scheduledIntent);}}
Thanks
All of the active alarms are cancelled after phone is shutdown. In order to reset the alarms you need to use a separate broadcast receiver that will receive only boot completed action. The receiver then starts service that will reset all your alarms in background. Best one for you is IntentService, because it ends itself when the work is done. Of course you need to store the information about alarms somewhere in order to remember which ones to reset. You can use, for example, SQLite to store them.
In your manifest:
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
and
<receiver android:name="developer.marat.apps.days.Alarms.BootCompletedReceiver"
android:enabled="true">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
<service android:name="developer.marat.apps.days.Alarms.RestartAlarmsService"/>
Special receiver:
public class BootCompletedReceiver extends BroadcastReceiver{
#Override
public void onReceive(Context context, Intent intent) {
if ("android.intent.action.BOOT_COMPLETED".equals(intent.getAction())) {
Intent i = new Intent(context, RestartAlarmsService.class);
ComponentName service = context.startService(i);
}
}
}
RestartAlarms:
public class RestartAlarmsService extends IntentService{
public RestartAlarmsService() {
super("RestartAlarmsService");
}
#Override
protected void onHandleIntent(Intent intent) {
// Restart your alarms here.
// open database, iterate through every alarm and set them again
}
}
I still cannot get my AlarmReceiver class' onReceive method to fire. Does anything stick out as wrong with this implementation?
All this is supposed to do is wait a certain period of time (preferably 6 days) and then pop up a notification. (Can you believe there isn't a built in system for this? crontab anyone!?)
MyActivity and BootReceiver both set up an alarm under the necessary conditions. AlarmService kicks out a notification. And AlarmReceiver is supposed to catch the alarm and kick off AlarmService, but it has never caught that broadcast, and won't no matter what I do.
Oh, and I've been testing on my Droid X, 2.3.4. Project being built against API 8.
P.S. Most of this has been adapted from http://android-in-practice.googlecode.com/svn/trunk/ch02/DealDroidWithService/
------------ MyActivity.java ------------
public class MyActivity extends Activity implements SensorEventListener {
private void setupAlarm() {
Log.i(TAG, "Setting up alarm...");
AlarmManager alarmMgr = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 1, new Intent(context, AlarmReceiver.class), 0);
// Get alarm trigger time from prefs
Log.i(TAG, "Getting alarm trigger time from prefs...");
SharedPreferences mPrefs2 = PreferenceManager.getDefaultSharedPreferences(context);
long trigger = SocUtil.getLongFromPrefs(mPrefs2, AlarmConst.PREFS_TRIGGER);
Log.i(TAG, "Trigger from prefs: " + trigger + " (" + new Date(trigger).toString() + ").");
// If alarm trigger is not set
if(trigger == new Long(-1).longValue()) {
// Set it
trigger = new Date().getTime() + NOTIFY_DELAY_MILLIS;
SocUtil.saveLongToPrefs(mPrefs2, AlarmConst.PREFS_TRIGGER, trigger);
Log.i(TAG, "Trigger changed to: " + trigger + " (" + new Date(trigger).toString() + ").");
// And schedule the alarm
alarmMgr.set(AlarmManager.RTC, trigger, pendingIntent);
Log.i(TAG, "Alarm scheduled.");
}
// If it is already set
else {
// Nothing to schedule. BootReceiver takes care of rescheduling it after a reboot
}
}
}
------------ AlarmService.java ------------
public class AlarmService extends IntentService {
public AlarmService() {
super("AlarmService");
}
#Override
public void onHandleIntent(Intent intent) {
Log.i(AlarmConst.TAG, "AlarmService invoked.");
this.sendNotification(this);
}
private void sendNotification(Context context) {
Log.i(AlarmConst.TAG, "Sending notification...");
Intent notificationIntent = new Intent(context, Splash.class);
PendingIntent contentIntent = PendingIntent.getActivity(context, 0, notificationIntent, 0);
NotificationManager notificationMgr = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
Notification notification = new Notification(R.drawable.icon, "Test1", System.currentTimeMillis());
notification.setLatestEventInfo(context, "Test2", "Test3", contentIntent);
notificationMgr.notify(0, notification);
}
}
------------ AlarmReceiver.java ------------
public class AlarmReceiver extends BroadcastReceiver {
// onReceive must be very quick and not block, so it just fires up a Service
#Override
public void onReceive(Context context, Intent intent) {
Log.i(AlarmConst.TAG, "AlarmReceiver invoked, starting AlarmService in background.");
context.startService(new Intent(context, AlarmService.class));
}
}
------------ BootReceiver.java ------------
(to restore wiped alarms, because stuff I schedule with the OS isn't important enough to stick around through a reboot -_-)
public class BootReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Log.i(AlarmConst.TAG, "BootReceiver invoked, configuring AlarmManager...");
Log.i(AlarmConst.TAG, "Setting up alarm...");
AlarmManager alarmMgr = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 1, new Intent(context, AlarmReceiver.class), 0);
// Get alarm trigger time from prefs
Log.i(AlarmConst.TAG, "Getting alarm trigger time from prefs...");
SharedPreferences mPrefs2 = PreferenceManager.getDefaultSharedPreferences(context);
long trigger = SocUtil.getLongFromPrefs(mPrefs2, AlarmConst.PREFS_TRIGGER);
Log.i(AlarmConst.TAG, "Trigger from prefs: " + trigger + " (" + new Date(trigger).toString() + ").");
// If trigger exists in prefs
if(trigger != new Long(-1).longValue()) {
alarmMgr.set(AlarmManager.RTC, trigger, pendingIntent);
Log.i(AlarmConst.TAG, "Alarm scheduled.");
}
}
}
------------ Manifest ------------
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<activity
android:name=".MyActivity"
android:label="#string/app_name" >
</activity>
<receiver android:name="com.domain.app.BootReceiver">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
<receiver android:name="com.domain.app.AlarmReceiver"></receiver>
<service android:name="com.domain.app.AlarmService"></service>
Here is some code I recently used to make a notification every hour (This is in my MainActivity):
AlarmManager am = (AlarmManager) getSystemService(ALARM_SERVICE);
Intent Notifyintent = new Intent(context, Notify.class);
PendingIntent Notifysender = PendingIntent.getBroadcast(this, 0, Notifyintent, PendingIntent.FLAG_UPDATE_CURRENT);
am.setInexactRepeating(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), 3600000, Notifysender);
Then in Notify.java
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
public class Notify extends BroadcastReceiver{
#SuppressWarnings("deprecation")
#Override
public void onReceive(Context context, Intent intent) {
NotificationManager myNotificationManager = (NotificationManager) context.getSystemService(context.NOTIFICATION_SERVICE);
Notification notification = new Notification(R.drawable.ic_launcher, "Update Device", 0);
Intent notificationIntent = new Intent(context, MainActivity.class);
PendingIntent contentIntent = PendingIntent.getActivity(context, 0, notificationIntent, 0);
notification.setLatestEventInfo(context, "Device CheckIn", "Please run Device CheckIn", contentIntent);
notification.flags |= Notification.FLAG_HIGH_PRIORITY;
myNotificationManager.notify(0, notification);
}
}
Then lastly in the AndroidManifest.xml I have this in between the tags:
<receiver android:name=".Notify" android:exported="true">
<intent-filter>
<action android:name="android.intent.action.NOTIFY" />
</intent-filter>
</receiver>
I have the main code that I know works at the office, feel free to email me for more help as I faced the same issues.
email: sbrichards at mit.edu
You must register your AlarmReceiver with an intent Action. like below. and the action string must be same to what action you are broadcasting by sendBroadcast() method..
like sendBroadcast(new Intent(""com.intent.action.SOMEACTION.XYZ""));
<receiver android:name="com.domain.app.AlarmReceiver">
<intent-filter>
<action android:name="com.intent.action.SOMEACTION.XYZ" />
</intent-filter>
</receiver>
I solved this by not even using a BroadcastReceiver. Every single one of the tutorials and posts I read about how to do notification alarms (and that was A LOT) said to use a BroadcastReceiver, but apparently I don't understand something, or that's a load of crap.
Now I just have the AlarmManager set an alarm with an Intent that goes directly to a new Activity I created. I still use the BootReceiver to reset that alarm after a reboot.
This lets the notification work in-app, out-of-app, with the app process killed, and after a reboot.
Thanks to the other commenters for your time.