Avoid alarm firing after each reboot - android

My apps alarm fires directly after each reboot, not at the specified time and it's not repeating. The alarm I set is ignored.
InitializeAlarm:
public class InitialisiereAlarm extends Activity {
private static final String TAG = "InitialisiereAlarm";
private static AlarmManager am;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_alarm);
aktiviereAlarmDownload();
finish();
}
private void aktiviereAlarmDownload() {
Calendar calAkt = Calendar.getInstance();
calAkt.setTimeInMillis(System.currentTimeMillis());
calAkt.set(Calendar.DAY_OF_WEEK, 2);
calAkt.set(Calendar.HOUR_OF_DAY, 10);
calAkt.set(Calendar.MINUTE, 15);
Intent intent = new Intent(this, StartAlarm.class);
intent.putExtra("alarmCode", "12345");
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 12345,
intent, PendingIntent.FLAG_UPDATE_CURRENT);
AlarmManager am = (AlarmManager) getSystemService(Activity.ALARM_SERVICE);
am.setRepeating(AlarmManager.RTC_WAKEUP, calAkt.getTimeInMillis(),
AlarmManager.INTERVAL_HALF_HOUR, pendingIntent);
}
}
StartAlarm extends BroadcastReceiver, actually the same plus starting another activity:
public class StartAlarm extends BroadcastReceiver {
private static final String TAG = "StartAlarm";
private WakeLock wl;
#Override
public void onReceive(Context context, Intent intent) {
PowerManager pm = (PowerManager) context
.getSystemService(Activity.POWER_SERVICE);
wl = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "SomeTag");
wl.acquire();
Intent intent2 = new Intent();
intent2.setClassName("com.test.testApp",
"com.test.testApp.DoThings");
intent2.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(intent2);
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 12345,
intent2, PendingIntent.FLAG_UPDATE_CURRENT);
Calendar calAkt = Calendar.getInstance();
calAkt.setTimeInMillis(System.currentTimeMillis());
calAkt.set(Calendar.DAY_OF_WEEK, 2);
calAkt.set(Calendar.HOUR_OF_DAY, 10);
calAkt.set(Calendar.MINUTE, 15);
AlarmManager am = (AlarmManager) context.getSystemService(Activity.ALARM_SERVICE);
am.setRepeating(AlarmManager.RTC_WAKEUP, calAkt.getTimeInMillis(),
AlarmManager.INTERVAL_HALF_HOUR, pendingIntent);
}
StartAlarm in the Manifest:
<receiver
android:name=".timer.StartAlarm"
android:enabled="true" >
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
I don't see what I'm doing wrong. Guess there's something I didn't understand... Any help is apprechiated!
Edit:
The problem was, that the alarm layed in the past. Solved it by setting the alarm to a future date by inserting
Calendar cal = Calendar.getInstance();
if (calAkt.compareTo(cal) <= 0) {
calAkt.add(Calendar.MINUTE, 8);
}
Thanks #CommonsWare for the hint

My apps alarm fires directly after each reboot
No, it does not. However, your StartAlarm BroadcastReceiver is getting control at boot time, because that is what you put in your manifest. If you do not want StartAlarm to get control at boot time, then get rid of its <intent-filter> in the manifest.

Related

how to start B class at every specific time on android?

I want use String start = "16:00"; in specific time, start another activity.
I must use String start = "16:00"
MainActivity.class
String start = "16:00";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
setAlarmTime(this);
}
private void setAlarmTime(Context context) {
String[] strStart = start.split(":") // delete ":"
Calendar cal_start = Calendar.getInstance();
cal_start.set(Calendar.HOUR_OF_DAY, Integer.parseInt(strStart[0])); // hour
cal_start.set(Calendar.MINUTE, Integer.parseInt(strStart[1])); //minute
AlarmManager alarm = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(this, AlarmActivity.class);
PendingIntent pIntent = PendingIntent.getActivity(context, 0, intent, 0);
alarm.set(AlarmManager.RTC, cal_start.getTimeInMillis(), pIntent);
}
I want while the app is running, current time 4 o'clock , start AlarmActivity.class .
But it does not work.
How to every specific time start another activity on android?
#update
private void setAlarmTime(Context context) {
String[] strStart = start.split(":");
Calendar cal_start = Calendar.getInstance();
cal_start.set(Calendar.HOUR_OF_DAY, Integer.parseInt(strStart[0]));
cal_start.set(Calendar.MINUTE, Integer.parseInt(strStart[1]));
AlarmManager alarm = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(this, AlarmReceiver.class);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, 0);
alarm.set(AlarmManager.RTC_WAKEUP, cal_start.getTimeInMillis(), pendingIntent);
this source not work.
not work alarmManager.
Please consider to use AlarmManager.RTC_WAKEUP if you need to wake up the device even if it goes off.
alarm.set(AlarmManager.RTC_WAKEUP, cal_start.getTimeInMillis(), pIntent);
AlarmManager.RTC will NOT wake the device up.
Reference: https://developer.android.com/reference/android/app/AlarmManager.html#RTC
Btw, you do not need to pass the context reference to method:
PendingIntent pIntent = PendingIntent.getActivity(this /*can use this as it is a context already */ , 0, intent, 0);
Update:
Please also set the second and millisecond of the cal_start; otherwise it will be the values that you get the calendar instance.
cal_start.set(Calendar.SECOND, 0);
cal_start.set(Calendar.MILLISECOND, 0);
Update 2:
It works in my side, you may try to add
<uses-permission android:name="android.permission.WAKE_LOCK" />
in Manifests.
Btw, if you want this alarm repeat every day
AlarmManager alarm = (AlarmManager) getSystemService(ALARM_SERVICE);
alarm.setRepeating(AlarmManager.RTC_WAKEUP, cal_start.getTimeInMillis(), AlarmManager.INTERVAL_DAY, pIntent);
Add this permission in your manifest
<uses-permission android:name="android.permission.WAKE_LOCK" />
register your receiver class in the application tag in the manifest file
<receiver android:name=".AlarmActivity" />
Resister your alarm that will trigger AlarmActivity at a specific time in your case its 16:00
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.HOUR_OF_DAY, 16);
calendar.set(Calendar.MINUTE, 0);
calendar.set(Calendar.SECOND, 0);
Intent intent = new Intent(getApplicationContext(), AlarmActivity.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(), AlarmManager.INTERVAL_DAY, pendingIntent);
Make sure your register class extend BroadcastReceiver like this
class AlarmActivity extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
// Do whatever you want
// you can generate notifications here
// or can start your application activity you want
}
}

Alarm Manager not firing on screen is off

I set alarm manager for time control.My purpose continue to time controlling on screen off. While screen is on everything is ok but when i locked to device(screen of) my broadcast receiver not receiver anything
i tried lots of different solution (in Manifest export:false or process:":remote") about similar problem but problem not solved. I need to help. I hope someone solved that problem before.
For set alarm manager
AlarmManager alarmManager = (AlarmManager)
context.getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(context, TimeService.class);
intent.setAction(SETUP_TIMER_FOR_NOTIFICATION);
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 112, intent, PendingIntent.FLAG_UPDATE_CURRENT);
long now = System.currentTimeMillis();
long minute = 1000 * 60;
alarmManager.cancel(pendingIntent);
alarmManager.setInexactRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime() , minute, pendingIntent);
My Receiver
public class TimeService extends WakefulBroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Log.i("TimeService", "onReceive");
Intent timeIntent = new Intent(context, NotificationService.class);
timeIntent.setAction(SETUP_TIMER_FOR_NOTIFICATION);
startWakefulService(context, timeIntent);
}
}
Manifest.xml
<receiver
android:name="service.TimeService"
android:enabled="true"
android:exported="false"
>
<intent-filter>
<action android:name="alarm_timer_for_notification" />
</intent-filter>
</receiver>
setAndAllowWhileIdle this is worked when screen is off and phone in idle mode
In marshmallow introduce the doze mode for battery saving. So the alarm not fired correctly in repeat mode.
So we use
https://developer.android.com/reference/android/app/AlarmManager.html#setAndAllowWhileIdle(int,%20long,%20android.app.PendingIntent)
From marshmallow and up, alarm waked up only 10 min interval,setAndAllowWhileIdle also fire service or notification 10 minutes once when phone is idle (screen is off).
In normal mode time interval working fine (I have checked 3 min's interval)
public class TimeService extends WakefulBroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Log.i("TimeService", "onReceive");
Intent timeIntent = new Intent(context, NotificationService.class);
timeIntent.setAction(SETUP_TIMER_FOR_NOTIFICATION);
startWakefulService(context, timeIntent);
setAlarm(context);
}
public void setAlarm(Context context)
{
Timber.v(TAG +"set Alarm");
PreferencesHelper preferencesHelper =new PreferencesHelper(context);
AlarmManager alarmManager = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(context, TimeService.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, intent, 0);
int intervalInMinutes = preferencesHelper.getInt(context.getResources().getString(R.string.sha_loc_intervals), 1)* 60000;
if (android.os.Build.VERSION.SDK_INT >= 23) {
alarmManager.setAndAllowWhileIdle(AlarmManager.ELAPSED_REALTIME_WAKEUP,
SystemClock.elapsedRealtime()+intervalInMinutes , pendingIntent);
} else if (android.os.Build.VERSION.SDK_INT >= 19
&& android.os.Build.VERSION.SDK_INT < 23) {
alarmManager.setExact(AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime()+intervalInMinutes , pendingIntent);
} else {
alarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime()+intervalInMinutes , pendingIntent);
}
}
public void cancelAlarm(Context context)
{
Timber.v(TAG +"cancel Alarm");
Intent intent = new Intent(context, TimeService.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, intent, 0);
AlarmManager alarmManager = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
alarmManager.cancel(pendingIntent);
}}
<receiver android:name=".TimeService"
android:enabled="true"
android:exported="true"
android:process=":remote">
</receiver>
In MainActivity.class
TimeService timeService =new TimeService();
timeService.setAlarm(MainActivity.this);
You want to take a permission in manifest file.
uses-permission android:name="android.permission.WAKE_LOCK"
WakeLock is a mechanism to keep the device on

Alarmmanager going off on reboot...but its set for 7 days ahead?

I'm failing to see why this alarm is going off on a reboot...I am setting it 7 days ahead here -
Intent intent = new Intent(MainActivity.this, Reminder.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(
MainActivity.this, 1, intent, 1);
AlarmManager am = (AlarmManager) getSystemService(ALARM_SERVICE);
try {
am.cancel(pendingIntent);
} catch (Exception e) {
System.out.println("Derp");
}
Calendar calendar = Calendar.getInstance();
calendar.add(Calendar.DATE, 7);
long time = calendar.getTimeInMillis();
am.set(AlarmManager.RTC_WAKEUP, time,
pendingIntent);
Here is my manifest that I have set for alarm to stick around on a reboot - Reminder is the class receiving the alarm-
<receiver android:name="com.practicum.notifications.Reminder" >
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
By default, all alarms are canceled when a device shuts down. To prevent this from happening, you can design your application to automatically restart a repeating alarm if the user reboots the device. This ensures that the AlarmManager will continue doing its task without the user needing to manually restart the alarm.
You have to manually reset the alarm once again in Bootup Receiver
public class SampleBootReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals("android.intent.action.BOOT_COMPLETED")) {
// Set the alarm here.
}
}
All alarms are shut off when you power off the Android device.
You need to call setRepeating method
public class AlarmReceiver extends BroadcastReceiver {
private static final int PERIOD=5000;
#Override
public void onReceive(Context ctxt, Intent i) {
scheduleAlarms(ctxt);
}
static void scheduleAlarms(Context ctxt) {
AlarmManager am = (AlarmManager) ctxt.getSystemService(Context.ALARM_SERVICE);
Intent i = new Intent(ctxt, YourService.class);
PendingIntent pi = PendingIntent.getService(ctxt, 0, i, 0);
mgr.setRepeating(AlarmManager.ELAPSED_REALTIME,
SystemClock.elapsedRealtime() + PERIOD, PERIOD, pi);
}
}
Check this answer from CommonsWare.
For future reference, I misunderstood how receving the boot complete action worked. I had the intent filter in both of my receiver classes so they were both running, when instead I needed an intent filter on a new broadcastreceiver class to RESET my alarmmanagers.

alarm manager stop when change system clock

I have a service that runs in background. I am using alarm manager to start this service. It works fine but when i change the system clock in my device or in the simulator the alarm manager stops.
public void startAzanService() {
Calendar cal = Calendar.getInstance();
Intent intent = new Intent(this, CheckAzan.class);
PendingIntent pintent = PendingIntent.getService(this, 0, intent, 0);
AlarmManager alarm = (AlarmManager)getSystemService(Context.ALARM_SERVICE);
//repeat the action every 5 secionde
alarm.setRepeating(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), 5000, pintent);
}
You can overcome this problem by Listening to the time changing Broadcast. Do the following:-
1)Create BroadcastReceiver in you Manifest file:-
<receiver android:name=".TimeChangeReceiver">
<intent-filter >
<action android:name="android.intent.action.TIME_SET"/>
</intent-filter>
</receiver>
2)Create the receiver class:-
public class TimeChangeReceiver extends BroadcastReceiver{
#Override
public void onReceive(final Context arg0, Intent arg1) {
//Call your Alarm setting code
Calendar cal = Calendar.getInstance();
Intent intent = new Intent(this, CheckAzan.class);
PendingIntent pintent = PendingIntent.getService(this, 0, intent, 0);
AlarmManager alarm = (AlarmManager)getSystemService(Context.ALARM_SERVICE);
//repeat the action every 5 secionde
alarm.setRepeating(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), 5000, pintent);
}
}
*Assuming that your don`t have any problem with your code :)
This link is also a good Tutorial of the BroadcastReceiver

AlarmManager inside BroadcastReceiver when BOOT_COMPLETED

I have a Service "GroupsTaskAlarmChecker" that is called every 20 seconds by AlarmManager in onCreate of Groups.class activity this way:
int seconds = 20;
Intent myIntent = new Intent(Groups.this, GroupsTaskAlarmChecker.class);
pendingIntent = PendingIntent.getService(Groups.this, 0, myIntent, 0);
AlarmManager alarmManager = (AlarmManager)getSystemService(ALARM_SERVICE);
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
calendar.add(Calendar.SECOND, 10);
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), seconds * 1000, pendingIntent);
This works perfectly. But I need to do that when device boot.
Then I know I have to make AndroidManifest like this:
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<receiver android:name=".ReceiverBoot">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED">
<category android:name="android.intent.category.HOME">
</category></action></intent-filter>
</receiver>
and then mi broadcastReceiver like this:
public class ReceiverBoot extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
int seconds = 20;
Intent myIntent = new Intent(context, GroupsTaskAlarmChecker.class);
pendingIntent = PendingIntent.getService(context, 0, myIntent, 0);
AlarmManager alarmManager = (AlarmManager)getSystemService(ALARM_SERVICE);
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
calendar.add(Calendar.SECOND, 10);
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), seconds * 1000, pendingIntent);
}
}
but inside this onReceive I dont know how can I do the same that I did before (with intent and alarmManager to start the service each 20 seconds).
Error in this line:
AlarmManager alarmManager = (AlarmManager)getSystemService(ALARM_SERVICE);
Is possible that I can't make an AlarmManager inside BroadcastReceiver?
I thank you all, I am an Android begginer and I need your help. Sorry for my english ;)
To summarize the answers and comments above: the onReceive handler receives a context which can be used to access getSystemService and ALARM_SERVICE. Sample code:
public class MyReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
// Start periodic service.
Calendar cal = Calendar.getInstance();
Intent srvIntent = new Intent(context, MyService.class);
PendingIntent pIntent = PendingIntent.getService(context, 0, srvIntent, 0);
// Use context argument to access service
AlarmManager alarm =
(AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
// Repeat every 5 seconds
alarm.setInexactRepeating(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(),
5000, pIntent);
}
}
}
Create a new class with this code and of course change MyReceiver and MyService to the names in your implementation.
ALARM_SERVICE is neither defined in the class ReceiverBoot nor in BroadcastReceiver.
You should reference Context.ALARM_SERVICE as the argument for getSystemService(String).
Here is a little contribution, which I believe that can add a more complete vision about achieving the goal of this question.
First: configure a "receiver" inside of the AndroidManifest from your app.
<receiver
android:name=".AlarmBroadcastReceiver"
android:enabled="true">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED"/>
</intent-filter>
</receiver>
Second: with a Class that EXTENDS the Abstract Class BroadcastReceiver, you should determine if the Intent Action was "BOOT_COMPLETED". If the condition is satisfied, you can call a method from your class which has all the construction to your Alarm.
See the following snippet bellow.
public class AlarmBroadcastReceiver extends BroadcastReceiver {
String TAG = "ALARMS";
String CLASS = this.getClass().getSimpleName() + ": ";
Context alarmContext;
#Override
public void onReceive(final Context context, Intent intent) {
Log.d(TAG, CLASS + "[START] onReceive()... ");
alarmContext = context;
if (Intent.ACTION_BOOT_COMPLETED.equals(intent.getAction())) {
Log.d(TAG, CLASS + "BOOT_COMPLETED action has been received.");
setAlarmOnBoot();
}
Log.d(TAG, CLASS + "[END] onReceive()... ");
}
public void setAlarmOnBoot() {
Log.d(TAG, CLASS + "[START] - setAlarmOnBoot()");
final long beginAt = SystemClock.elapsedRealtime() + 60 * 1000;
final long interval = 300000; // 5 minutes
try {
AlarmManager alarm = (AlarmManager) alarmContext.getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(alarmContext, AlarmBroadcastReceiver.class);
PendingIntent pIntent = PendingIntent.getService(alarmContext, 0, intent, 0);
alarm.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP, beginAt, interval, pIntent);
Log.d(TAG, CLASS + "the Alarm has been configured successfully (5 minutes) of interval.");
} catch (Exception e) {
Log.d(TAG, CLASS + "an exception has ocurred while setting the Alarm...");
e.printStackTrace();
}
Log.d(TAG, CLASS + "[END] - setAlarmOnBoot()");
}
}
in your onReceive:
if ("android.intent.action.BOOT_COMPLETED".equals (intent.getAction())){
//start it again here
}

Categories

Resources