Android: setting new Alarm from onReceive method - android

I have a collection of reminders in my database(sort by time). When my application starts I call setAlarm. I need to add code in onReceive method in order to do these tasks:
Get first reminder from my database
Get the delay associated to the reminder
Schedule a new Alarm for getting the next reminder.
I created a simple BroadcastReceiver class:
public class AlarmReceiver extends BroadcastReceiver{
private static final String DEBUG_TAG= "AlarmReceiver";
public void onReceive(Context arg0, Intent arg1) {
// TODO Auto-generated method stub
Log.d(DEBUG_TAG,"ALARM!!!");
// --mycode--
}
}
and the Activity class:
public class AlarmActivity extends Activity {
private Context context;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main_layout);
context = getApplicationContext();
}
public void setAlarm(View v){
Intent intent = new Intent(this,AlarmReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT);
AlarmManager alarmManager = (AlarmManager)getSystemService(ALARM_SERVICE);
alarmManager.set(AlarmManager.RTC_WAKEUP, System.currentTimeMillis()+ Delay,pendingIntent);
Log.i("SETTER","Alarm started");
}
public void stopAlarm(View v){
Intent intent = new Intent(this,AlarmReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT);
pendingIntent.cancel();
}
}
Now, I would that in the --mycode-- section new Delay is taken (if exists) from database and new Alarm is setted with this new Delay.
How can I set a new AlarmManager from onReceive method?

You can get AlarmManager in the broadcast receiver by accessing it from the context
AlarmManager alarmManager = (AlarmManager)arg0.getSystemService(Context.ALARM_SERVICE);
where arg0 is your context variable

Related

AlarmManager one time alarm does not fire

I want to trigger a one-time alarm with the following, which is basically a replicate from https://developer.android.com/training/scheduling/alarms.html (second ELAPSED_REALTIME_WAKEUP example).
This is inside public static class PlaceholderFragment extends Fragment implements View.OnClickListener:
#Override
public void onClick(View v) {
Intent intent;
intent = new Intent(this.getActivity(), MuteReceiver.class);
AlarmManager alm = (AlarmManager)(this.getActivity().getSystemService(Context.ALARM_SERVICE));
PendingIntent alarmIntent = PendingIntent.getBroadcast(getActivity(), 0, intent, 0);
alm.set(AlarmManager.ELAPSED_REALTIME_WAKEUP,
SystemClock.elapsedRealtime() + 60*1000,
alarmIntent);
Log.d("MainActivity", "alarm set");
}
public class MuteReceiver extends BroadcastReceiver is like this:
public MuteReceiver() {
Log.d("MuteReceiver", "constructed");
}
#Override
public void onReceive(Context context, Intent intent) {
final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
boolean started = prefs.getBoolean(MuteService.STARTED, false);
Log.d("MuteReceiver", "Started=" + started);
}
I pressed the button in the Fragment, saw the log message "alarm set", but after one minute (and much later), still no log about MuteReceiver being constructed or MuteReceiver started (in onReceive)
You have a guaranteed list file with a registered broadcast

Broadcasting with AlarmManager to call activity

I want to call a method in another activity with the use of Alarm manager
I use a broadcasting to call alarm manager
I want just call a activityAlarm without ui (just alarm method)
I dont want open ui,
What should I do?
public class ReciveData extends BroadcastReceiver {
#Override
public void onReceive(Context arg0, Intent arg1) {
Intent myIntent = new Intent(G.context, ActivityAlarm.class);
myIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
PendingIntent pendingIntent = PendingIntent.getActivity(G.context, 0, myIntent, PendingIntent.FLAG_UPDATE_CURRENT);
G.alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + 2000, 3000, pendingIntent);
}
}
and this :
public class ActivityAlarm extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
alarm();
}
public void alarm() {
Log.i("LOGALARM", "Hello");
}
}
To call it without UI you should use BroadcastReceiver or Service, not Activity:
Instead of this:
Intent myIntent = new Intent(G.context, ActivityAlarm.class);
myIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
PendingIntent pendingIntent = PendingIntent.getActivity(G.context, 0, myIntent, PendingIntent.FLAG_UPDATE_CURRENT);
You should call this:
Intent myIntent = new Intent(G.context, YourReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(G.context, 0, myIntent, 0);
With this there will be no UI (because it won't start the activity), and you can put the alarm method to your BroadcastReceiver
More about the BroadcastReceiver: https://developer.android.com/reference/android/content/BroadcastReceiver.html
((ActivityAlarm ) getActivity()).alarm();
This should work for you.

Cancelling an alarm that starts within a class that launches when the reboot is complete

Here is my class which launches and sets an alarm when the phone is rebooted.
public class NotifStart extends BroadcastReceiver
{
private static AlarmNotif reAlarm = new AlarmNotif();
#Override
public void onReceive(Context context, Intent intent)
{
if (intent.getAction().equals("android.intent.action.BOOT_COMPLETED"))
{
reAlarm.SetAlarm(context.getApplicationContext());
}
}
}
and here's my alarm's receiver class:
public class AlarmNotifReceiver extends BroadcastReceiver {
PendingIntent pi;
#Override
public void onReceive(Context context, Intent intent)
{
//stuff
}
public void SetAlarm(Context context)
{
AlarmManager am = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
Intent i = new Intent(context, AlarmNotifReceiver.class);
pi = PendingIntent.getBroadcast(context, 0, i, PendingIntent.FLAG_UPDATE_CURRENT);
am.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(), 10*1000, pi); // Millisec * Second
}
public void CancelAlarm(Context context)
{
AlarmManager am = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
am.cancel(pi);
}
}
Now, if I use SetAlarm() as the phone is open I am able to use CancelAlarm() and actually cancel it. But whenever I reboot the phone and set the alarm by using the above class NotifStart I am unable to cancel it. I tried to use the cancel method from within the NotifStart but since I can't really give the context of a non-activity class as onReceive it just doesn't work.
From the docs:
A BroadcastReceiver object is only valid for the duration of the call to onReceive(Context, Intent). Once your code returns from this function, the system considers the object to be finished and no longer active.
So when you call your CancelAlarm your pending intent might be null or not equal to pending intent used for setting alarm.
In CancelAlarm(Context context) your pi might be null, check and re-create it with the same requestCode before performing cancel.
public void CancelAlarm(Context context)
{
AlarmManager am = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
Intent i = new Intent(context, AlarmNotifReceiver.class);
pi = PendingIntent.getBroadcast(context, 0, i, PendingIntent.FLAG_UPDATE_CURRENT);
am.cancel(pi);
}

How to stop Alarm Manager?

I have created the start alarm as shown below
public class MyScheduleReceiver extends BroadcastReceiver {
// Restart service every 30 seconds
private static final long REPEAT_TIME = 1000 * 5;
#Override
public void onReceive(Context context, Intent intent) {
AlarmManager service = (AlarmManager) context
.getSystemService(Context.ALARM_SERVICE);
Intent i = new Intent(context, MyStartServiceReceiver.class);
PendingIntent pending = PendingIntent.getBroadcast(context, 0, i,
PendingIntent.FLAG_CANCEL_CURRENT);
Calendar cal = Calendar.getInstance();
cal.add(Calendar.SECOND, 5);
service.setInexactRepeating(AlarmManager.RTC_WAKEUP,
cal.getTimeInMillis(), REPEAT_TIME, pending);
I crate this for stop alarm and i call it from main activity.Manifest i think is ok...Work repeat but no stop!!!
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.setup);
sendBroadcast(new Intent(this,MyScheduleReceiver.class));
}
public void StopRepeat(View view) {
sendBroadcast(new Intent(this,MyStopReceiver.class));
}
public class MyStartServiceReceiver extends BroadcastReceiver {
public void onReceive(Context context, Intent intent) {
Toast.makeText(context, "Repeat service!.",
Toast.LENGTH_LONG).show();
}
public class MyStopReceiver extends BroadcastReceiver {
// Restart service every 30 seconds
private static final long REPEAT_TIME = 1000 * 5;
#Override
public void onReceive(Context context, Intent intent) {
AlarmManager service = (AlarmManager) context
.getSystemService(Context.ALARM_SERVICE);
Intent istop = new Intent(context, MyStartServiceReceiver.class);
PendingIntent pending = PendingIntent.getBroadcast(context, 0, istop,
PendingIntent.FLAG_CANCEL_CURRENT);
Calendar cal = Calendar.getInstance();
cal.add(Calendar.SECOND, 5);
service.cancel(pending);
But the service is not stopping. What might be the issue?Thanks.
The simplest option is to restart your device. (If you created a BOOT_COMPLETED listener just remove it for now.)
You can also cancel an alarm by passing the PendingIntent you used to create the alarm to AlarmManager#cancel(). You have already written the code to do this, but do you have a Button with the XML attribute android:onClick="StopRepeat" in setup.xml? Did you click it?
Solution
We eventually discovered you had a mistake in your Manifest file, so MyStopServiceReceiver was never called...

Android AlarmManager not Triggering

I'm just trying to get a simple test app working with AlarmManager.
public class TestActivity extends Activity {
private static final int PERIOD = 1000;
private AlarmManager alarmManager;
private PendingIntent pendingIntent;
#Override
public void onCreate(Bundle savedInstanceState) {
Log.v("TextActivity", "WHY NOT!");
super.onCreate(savedInstanceState);
setContentView(R.layout.test);
alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(this, TestReceiver.class);
pendingIntent = PendingIntent.getBroadcast(this, 0, intent,
PendingIntent.FLAG_CANCEL_CURRENT);
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP,
System.currentTimeMillis(), PERIOD, pendingIntent);
Log.v("TestActivity", "Whee!");
}
}
public class TestReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Log.v("TestReceiver", "Got Here");
}
}
I have tried this on both a hardware phone and the emulator and I am not seeing the messages received. Am I missing something obvious? I am relatively new to Android development.
Did you register your receiver in AndroidManifest.xml? Also period is milliseconds, so that alarm will trigger every second, is this really what you want?

Categories

Resources