I am writing a program that fires off an intent to start a service periodically, to do this I have decided to use alarmmanager, I was able to make this do what I wanted in an activity fairly easily but I'm getting an error when attempting to do it in a receiver that I'm unable to figure out.
AlarmManager am = (AlarmManager)getSystemService(ALARM_SERVICE);
tells me that ALARM_SERVICE can't be resolved to a variable
here is my complete code for that receiver:
package com.testapp21.second.activities;
import android.app.AlarmManager;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.SystemClock;
public class PhoneOnReceiver extends BroadcastReceiver {
private PendingIntent mAlarmSender;
#Override
public void onReceive(Context context, Intent intent) {
mAlarmSender = PendingIntent.getService(context,
0, new Intent(context, StatsCheckerService.class), 0);
// We want the alarm to go off 30 seconds from now.
long firstTime = SystemClock.elapsedRealtime();
// Schedule the alarm!
AlarmManager am = (AlarmManager)getSystemService(ALARM_SERVICE);
am.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP,
firstTime, 30*1000, mAlarmSender);
}
}
Try
AlarmManager am = (AlarmManager)context.getSystemService(Service.ALARM_SERVICE);
I found that if you are in a fragment you can do this
AlarmManager am = (AlarmManager)getActivity().getSystemService(Service.ALARM_SERVICE);
Related
In my android application i need to show notification to user every two years at 09.00. I used the following method but did not work exactly
AlarmManager.INTERVAL_DAY * 30 * 6 * 4
and the following code is my full alarm manager
import java.util.Calendar;
import android.app.Activity;
import android.app.AlarmManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
public class MainActivity extends Activity {
private AlarmManager AlarmManager;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
AlarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(this, AlarmReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
calendar.set(2018,2,9,9,0);
AlarmManager.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(),AlarmManager.INTERVAL_DAY * 30 * 6 * 4, pendingIntent);
}
}
public void schedule()
{
Long time = new GregorianCalendar().getTimeInMillis()+10*1000;
Intent intent = new Intent(getActivity(), AlarmReceiver.class);
AlarmManager alarmManager = (AlarmManager) getActivity().getSystemService(Context.ALARM_SERVICE);
alarmManager.setInexactRepeating(AlarmManager.RTC_WAKEUP, time, 10*1000, PendingIntent.getBroadcast(getActivity(), 1, intent, PendingIntent.FLAG_UPDATE_CURRENT));
}
Above this is my method in a Fragment. Also tried in Activity. Weirdly this code works on an empty test project. The problem as I've seen here is that the last part, alarmManager.setInexactRepeating() does not start the AlarmReceiver.class at all.
What am I doing wrong here?
my Manifest file:
<receiver android:name=".AlarmReceiver"/>
<uses-permission android:name="com.android.alarm.permission.SET_ALARM"/>
also my receiver:
public class AlarmReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent){
Toast.makeText(context, "Alarm Triggered and SMS Sent", Toast.LENGTH_LONG).show();
}
}
Because of setInexactRepeating. Use setRepeating and it will be processed at the right time.
Instead of:
setInexactRepeating
use
setRepeating
setInexactRepeating, is OS and battery friendly, it batches together all the work to be done on Alarm receive and works through one by one, while as setRepeating instantly fires the alarm
Also a note: Alarms are wiped off once phone is rebooted, you might have to implement a boot broadcast receiver to make it persistent. Make sure you dont do that runtime, you need to implement it in the Manifest else when your app is not in background you will not receive any broadcasts.
A small example:
This is working code. It wakes CPU every 10 minutes until the phone turns off.
Add to Manifest.xml:
...
<uses-permission android:name="android.permission.WAKE_LOCK"></uses-permission>
...
<receiver android:process=":remote" android:name="Alarm"></receiver>
...
Code:
package YourPackage;
import android.app.AlarmManager;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.PowerManager;
import android.widget.Toast;
public class Alarm extends BroadcastReceiver
{
#Override
public void onReceive(Context context, Intent intent)
{
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)
{
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 * 10, 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);
}
}
Set Alarm from Service:
package YourPackage;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.os.IBinder;
public class YourService extends Service
{
Alarm alarm = new Alarm();
public void onCreate()
{
super.onCreate();
}
public void onStart(Context context,Intent intent, int startId)
{
alarm.SetAlarm(context);
}
#Override
public IBinder onBind(Intent intent)
{
return null;
}
}
If you want set alarm repeating at phone boot time:
Add permission to Manifest.xml:
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"></uses-permission>
...
<receiver android:name=".AutoStart">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED"></action>
</intent-filter>
</receiver>
...
And create new class:
package YourPackage;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
public class AutoStart extends BroadcastReceiver
{
Alarm alarm = new Alarm();
#Override
public void onReceive(Context context, Intent intent)
{
if (intent.getAction().equals("android.intent.action.BOOT_COMPLETED"))
{
alarm.SetAlarm(context);
}
}
}
I managed everything all right to create a notification service used to fire a notification as a result of an alarm. Unfortunately, setting the alarm using AlarmManager doesn't work right. It fires several minutes later (not exactly hours, which would indicate a timezone problem). The recurring period is 1 week, so I used the constant INTERVAL_DAY and multiplied it with 7. In order to make sure that one PendingIntent doesn't replace the other, I pass the dayOfWeek as second parameter to PendingIntent.getService(). I check the correctness of the time for the alarm to fire by logging it:
Log.d(TAG, "next alarm " + df.format(cal.getTime()));
Is there really no way to list all alarms set - at least those from my own app? I believe this is the only way to track down the error.
My code:
cal.setTimeInMillis(System.currentTimeMillis());
cal.add(Calendar.DATE, 1);
cal.set(Calendar.HOUR_OF_DAY, hour);
cal.set(Calendar.MINUTE, minute);
Log.d(TAG, "next alarm " + df.format(cal.getTime()));
Intent showNotificationIntent = new Intent(context, NotificationService.class);
dayOfWeek = cal.get(Calendar.DAY_OF_WEEK);
alarmIntent = PendingIntent.getService(context, dayOfWeek, showNotificationIntent, 0);
getAlarmManager(context).setInexactRepeating(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(),
INTERVAL_WEEK, alarmIntent);
I want to offer to have an alarm every day, but at various times, which can be set by the user. So I use up to 7 alarms, which should fire on a weekly basis.
Even after reading the numerous answers to similar questions (I don't intend to create a duplicate question), I haven't managed to find the problem.
For api levels below 19 you should use AlarmManager.setRepeating() and your alarms will trigger exactly at specified time. Thou on api levels 19 and above this will no longer work. There was change in android so that all repeating alarms are inexact. So if you would like to achieve exact repeating alarm you should schedule alarm with AlarmManager.setExact() and then when alarm triggers do it again for next week and so on every week.
Because of setInexactRepeating. Use setRepeating and it will be processed at the right time.
Instead of:
setInexactRepeating
use
setRepeating
setInexactRepeating, is OS and battery friendly, it batches together all the work to be done on Alarm receive and works through one by one, while as setRepeating instantly fires the alarm
Also a note: Alarms are wiped off once phone is rebooted, you might have to implement a boot broadcast receiver to make it persistent. Make sure you dont do that runtime, you need to implement it in the Manifest else when your app is not in background you will not receive any broadcasts.
A small example:
This is working code. It wakes CPU every 10 minutes until the phone turns off.
Add to Manifest.xml:
...
<uses-permission android:name="android.permission.WAKE_LOCK"></uses-permission>
...
<receiver android:process=":remote" android:name="Alarm"></receiver>
...
Code:
package YourPackage;
import android.app.AlarmManager;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.PowerManager;
import android.widget.Toast;
public class Alarm extends BroadcastReceiver
{
#Override
public void onReceive(Context context, Intent intent)
{
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)
{
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 * 10, 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);
}
}
Set Alarm from Service:
package YourPackage;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.os.IBinder;
public class YourService extends Service
{
Alarm alarm = new Alarm();
public void onCreate()
{
super.onCreate();
}
public void onStart(Context context,Intent intent, int startId)
{
alarm.SetAlarm(context);
}
#Override
public IBinder onBind(Intent intent)
{
return null;
}
}
If you want set alarm repeating at phone boot time:
Add permission to Manifest.xml:
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"></uses-permission>
...
<receiver android:name=".AutoStart">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED"></action>
</intent-filter>
</receiver>
...
And create new class:
package YourPackage;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
public class AutoStart extends BroadcastReceiver
{
Alarm alarm = new Alarm();
#Override
public void onReceive(Context context, Intent intent)
{
if (intent.getAction().equals("android.intent.action.BOOT_COMPLETED"))
{
alarm.SetAlarm(context);
}
}
}
I have a set of alarms that I need to keep after reboot. I've tried using on an boot receiver but they won't start again. I'm not sure if I understand the boot receiver and how to then restart all the alarms. I already have one receiver for my notifications, but don't know whether I can use the same receiver or if I need a new one?
Could anyone point me to any good tutorials or help me out?
Cheers
Code :
DatabaseHandler db = new DatabaseHandler(this);
List<UAlarm> alarms = db.getAllAlarms();
AlarmManager am = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
for (UAlarm ua : alarms) {
String programme = ua.getTitle();
String startTime = ua.getStart();
String endTime = ua.getEnd();
String nowPlaying = ua.getChannel();
db.addAlarm(new UAlarm(programme, startTime, endTime, nowPlaying, ""));
final UAlarm ut = new UAlarm();
ut.setTitle(programme);
ut.setStart(startTime);
ut.setEnd(endTime);
ut.setChannel(nowPlaying);
ut.setId(db.getLastEntered());
String [] bla = startTime.split(":");
int hour = Integer.parseInt(bla[0].trim());
int minute = Integer.parseInt(bla[1].trim());
minute -= 2;
Calendar cal = Calendar.getInstance();
cal.set(Calendar.HOUR_OF_DAY, hour);
cal.set(Calendar.MINUTE, minute);
Intent intenta = new Intent(this, NotificationMenu.class);
String name = programme;
intenta.putExtra("name", name);
intenta.putExtra("id", db.getLastEntered());
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, ua.getId(),
intenta, PendingIntent.FLAG_CANCEL_CURRENT);
am.set(AlarmManager.RTC_WAKEUP,
cal.getTimeInMillis(), pendingIntent);
}
}
with NotificationMenu being the notifications, which is why I'm using the AlarmManager
I'm not sure if I understand the boot receiver and how to then restart all the alarms.
Just call your code to call setRepeating() (or whatever) on AlarmManager.
For example, in this sample project, PollReceiver is set to receive BOOT_COMPLETED. In onReceive(), it reschedules the alarms:
package com.commonsware.android.schedsvc;
import android.app.AlarmManager;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.SystemClock;
public class PollReceiver extends BroadcastReceiver {
private static final int PERIOD=5000;
#Override
public void onReceive(Context ctxt, Intent i) {
scheduleAlarms(ctxt);
}
static void scheduleAlarms(Context ctxt) {
AlarmManager mgr=
(AlarmManager)ctxt.getSystemService(Context.ALARM_SERVICE);
Intent i=new Intent(ctxt, ScheduledService.class);
PendingIntent pi=PendingIntent.getService(ctxt, 0, i, 0);
mgr.setRepeating(AlarmManager.ELAPSED_REALTIME,
SystemClock.elapsedRealtime() + PERIOD, PERIOD, pi);
}
}
I am trying to start code inside an activity at regular intervals using Alarm manager. I have looked at various examples on here but they have not really helped.
For testing purposes, all I am trying to do is pop up a toast at 10 second intervals, but nothing seems to be happening at all. Please help guys!
I have this in the manifest (also declarations for all three activities):
<receiver android:name=".receiver.AlarmReceiver"></receiver>
Code from main activity, in OnCreate:
//
// Setting up the Alarm Manager
//
Intent myIntent = new Intent(getBaseContext(), AlarmReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(getBaseContext(), 0, myIntent, 0);
AlarmManager alarmManager = (AlarmManager)getSystemService(ALARM_SERVICE);
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
calendar.add(Calendar.SECOND, 10);
long timerInterval = 10 * 1000;
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), timerInterval, pendingIntent);
//finish();
AlarmReceiver.java:
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.widget.Toast;
public class AlarmReceiver extends BroadcastReceiver
{
public void onReceive(Context context, Intent intent)
{
Toast.makeText(context," onRecieve() test" , Toast.LENGTH_LONG).show();
Intent scheduledIntent = new Intent(context, MyService.class);
scheduledIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(scheduledIntent);
}
}
MyService.java:
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.os.IBinder;
import android.widget.Toast;
public class MyService extends Service {
public void onCreate(Bundle savedInstanceState) {
super.onCreate();
Toast.makeText(getBaseContext(),"test message.",
Toast.LENGTH_SHORT).show();
}
#Override
public IBinder onBind(Intent arg0) {
// TODO Auto-generated method stub
return null;
}
}
Your activity is not showing, because you are calling startActivity() on an Intent that identifies a Service. You should see warnings related to this in LogCat.
I humbly suggest that you use LogCat yourself, via the Log class, for logging background operations, rather than attempting to use a Toast.
test this code:
private void establecerAlarmaClick(int when){
AlarmManager manager = (AlarmManager) this.getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(MainActivityAlarmita.this, MainActivityAlarmita.class);
PendingIntent pendingIntent = PendingIntent.getActivity(MainActivityAlarmita.this, 0, intent, PendingIntent.FLAG_ONE_SHOT);
((AlarmManager) getSystemService(ALARM_SERVICE)).set(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + when * 1000, pendingIntent);
}