Service is started via BroadcastReceiver "randomly" - android

I want to have an Notification on an specified Time each day.
For that I implemented an Broadcast receiver and an AlarmManager.
My doubt is that the receiver is reacting to every broadcast of the system.
Cause if I setup the alarmManager it is working fine for a while but than I got an notification nearly every hour (approximately).
And an other strange behaviour, if i go in airplane mode, the notifications doesn't show up.
public class MyReceiver extends BroadcastReceiver
{
#Override
public void onReceive(Context context, Intent intent)
{
Intent service1 = new Intent(context, MyAlarmService.class);
context.startService(service1);
}
}
in the main activity
long REPEATE_TIME_MS=86400000 /*24h*/;
/* notification handling */
String syncConnPref = this.sharedPref.getString("notificationTime", "12:00");
String[] pieces=syncConnPref.split(":");
/* setup the start time for the alarm */
Calendar calendar = Calendar.getInstance();
long nowInMillisecs = calendar.getTimeInMillis();
calendar.set(Calendar.HOUR_OF_DAY, Integer.parseInt(pieces[0], 10));
calendar.set(Calendar.MINUTE, Integer.parseInt(pieces[1], 10));
long alarmStartTimeUnMillisecs = calendar.getTimeInMillis();
if(alarmStartTimeUnMillisecs<=nowInMillisecs)
{
calendar.add(Calendar.DAY_OF_YEAR, 1);
alarmStartTimeUnMillisecs = calendar.getTimeInMillis();
}
Intent myIntent = new Intent(this.notificationContext, MyReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(this.notificationContext, 0, myIntent,PendingIntent.FLAG_UPDATE_CURRENT);
AlarmManager alarmManager = (AlarmManager)this.notificationContext.getSystemService(Service.ALARM_SERVICE);
alarmManager.cancel(pendingIntent);
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), REPEATE_TIME_MS, pendingIntent);
Log.d(TAG, "Alarm setup with :"+ calendar.get(Calendar.HOUR_OF_DAY)+":"+ calendar.get(Calendar.MINUTE));
manifest.xml
<receiver android:name="com.example.whoseturn.MyReceiver" android:enabled="true">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>

Related

Alarm manager trigger every time app running

I want to create a repeating alarm from AlarmManager which is triggered at 21:00 every day to show a notification. So i create a service and declare that in manifest, in the service class i wrote a method for schedule repeating alarms.
public static void setRecurringAlarm(Context context) {
AlarmManager am = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
Intent i = new Intent(context, NotificationService.class);
PendingIntent pi = PendingIntent.getService(context, 0, i, 0);
am.cancel(pi);
Calendar updateTime = Calendar.getInstance();
updateTime.setTimeZone(TimeZone.getDefault());
updateTime.set(Calendar.HOUR_OF_DAY, 21);
updateTime.set(Calendar.MINUTE, 00);
updateTime.set(Calendar.SECOND, 00);
am.setInexactRepeating(AlarmManager.RTC_WAKEUP,
updateTime.getTimeInMillis(),
AlarmManager.INTERVAL_FIFTEEN_MINUTES, pi);
}
(For test i set the delay INTERVAL_FIFTEEN_MINUTES).
I call this method at onResume() of my splash screen activity and in a BroadcastReceiver that is set up to receive BOOT_COMPLETED.
#Override
protected void onResume() {
super.onResume();
NotificationService.setRecurringAlarm(this);
}
this is my BroadcastReceicer :
public class NotificationBootReceiver extends BroadcastReceiver {
public void onReceive(Context context, Intent intent) {
NotificationService.setRecurringAlarm(context);
}
}
and this is my manifest :
<receiver android:name=".notification.NotificationBootReceiver">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
<service android:name=".notification.NotificationService" />
</application>
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
the problem is every time i open the app and splashscreen running the alarm triggered and notification will be shown.

Generating alarm at specific day each week at a specified time android

I am using the following code to trigger an alarm at 08:45 am on every monday.
Calendar cl1 = Calendar.getInstance();
cl1.set(Calendar.DAY_OF_WEEK, 2);
cl1.set(Calendar.HOUR, 8);
cl1.set(Calendar.MINUTE, 45);
cl1.set(Calendar.SECOND, 0);
long tme = cl1.getTimeInMillis();
Intent intent = newIntent(Mondayentry.this,Alarmreceiver.class);
PendingIntent pendingintent = PendingIntent.getBroadcast(Mondayentry.this,0,intent, PendingIntent.FLAG_UPDATE_CURRENT);
AlarmManager al = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
al.setRepeating(AlarmManager.RTC_WAKEUP, tme,7*1440*60000, pendingintent);
And I have used the following broadcast class
public class Alarmreceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent)
{
Toast.makeText(context, "Alarm generated", Toast.LENGTH_SHORT).show();
}
}
I have also added in the manifest file
<receiver android:name=".Alarmreceiver"> </receiver>
There is no error but the alarm is not triggered at all.
Please help me.

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 set method not working when called from boot receiver

I have looked everywhere for this solution most of the replies ask to set alarm in boot receiver.
i have implemented a boot receiver and started a service and set a alarm using set method.
Service is started fine but alarm is not setting.
please help i am stuck on that.
i can post some also if you want but boot receiver is working fine as i am also starting service in that
public class MyReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
SharedPreferences sharedPref = context.getSharedPreferences(
Util.SHARED_PREF_NAME, Context.MODE_PRIVATE);
long curTime = System.currentTimeMillis();
long endTime = sharedPref.getLong(Util.END_TIME, -1);
long startTime = sharedPref.getLong(Util.START_TIME, -1);
if (curTime < endTime && startTime >= curTime) {
Intent intent1 = new Intent(context, HUD.class);
PendingIntent pintent = PendingIntent.getService(context, 1987,
intent1, PendingIntent.FLAG_CANCEL_CURRENT);
AlarmManager alarm = (AlarmManager) context
.getSystemService(Context.ALARM_SERVICE);
alarm.setRepeating(AlarmManager.RTC_WAKEUP, endTime, 100, pintent);
Log.e("alaram set", endTime + " " + curTime);
}
Intent service = new Intent(context, HUD.class);
context.startService(service);
}
}
MyReceiver.java
<receiver
android:name=".MyReceiver"
android:enabled="true"
android:exported="true" >
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
Manifest.xml
Service started successfully after boot
but alarm.setRepeating(AlarmManager.RTC_WAKEUP, endTime, 100, pintent);
alarm is not working.
I think i clear my question.
Plz help
Intent intent1 = new Intent(context, HUD.class);
PendingIntent pintent = PendingIntent.getService(context, 1987,
intent1, PendingIntent.FLAG_CANCEL_CURRENT);
AlarmManager alarm = (AlarmManager) context
.getSystemService(Context.ALARM_SERVICE);
Calendar cal = Calendar.getInstance();
cal.add(Calendar.SECOND, 30);
alarm.setInexactRepeating(AlarmManager.RTC_WAKEUP,
cal.getTimeInMillis(), 100, pending);
Try your setInexactRepeating instead of setRepeating that is more performance optimized method.

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