Broadcast receiver onReceive() getting called multiple times - android

I have a boot_completed receiver which gets notified on boot.
<receiver android:name=".BootCompletedReceiver">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
But it appears to get called multiple times. I start a timer, and then a service, which leads to multiple timers, and then the service gets reset and runs again.
Creating timer like this. This is not a repeating timer, is it?:
private void setAlarm(Context context, long interval) {
try {
AlarmManager alarms = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(RespondAlarmReceiver.ACTION_RESPOND_SMS);
intent.putExtra("isChecking", true);
PendingIntent alarmIntent = PendingIntent.getBroadcast(context, 0, intent, 0);
int alarmType = AlarmManager.ELAPSED_REALTIME_WAKEUP;
long triggerAtTime = SystemClock.elapsedRealtime() + interval; //interval is 60,000
alarms.set(alarmType, triggerAtTime, alarmIntent);
}
catch (Exception e) {
Log.e(DEBUG_TAG, "Unable to set alarm");
}
As a side note, if anybody knows how to attach the Eclipse debugger to the Boot-up broadcast receiver or to a running service, that would be fantastic.

It's strange that you'd be getting multiple timers started. Try passing PendingIntent.FLAG_ONE_SHOT as the last argument inside of PendingIntent.getBroadcast

Related

How to run service in background every 10 minute?

I want to use a service that run in background indefinitely and call a method every 10 minute
and its running even app killed
How to create it?
You can do by using service as follows
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
#Override
public void run() {
//performe the deskred task
}
}, 10minutes time in milisecods);
// If we get killed, after returning from here, restart
return START_STICKY;
}
This service will get started automatically even if app get killed, and postdelayed will run
For "how to work with services", see
Services - Android
Services in Android - Vogella
Here is a clear solution that focus on "every 10 minutes" part using AlarmManager: https://stackoverflow.com/a/10222390/2591556
Assuming you have a Running Service
User AlarmManager to run Service every 10 minutes
AlarmManager am=(AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
Intent i = new Intent(context, YourService.class);
PendingIntent pi = PendingIntent.getBroadcast(context, 0, i, 0);
am.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(), 600000, pi); // Millisec * Second * Minute
}
you could write a background Service:
Running in a Background Service
and start the service every 10-11 min (cause of AlarmManager power saving behaviour), or with exact timing (needs to shedule next execution every time) with AlarmManager.setExact
Example:
private static PendingIntent createClockIntent(Context context) {
Intent intent = new Intent(context.getString(R.string.widget_broadcast_clock_update));
PendingIntent pendingIntent = PendingIntent.getBroadcast(context.getApplicationContext(), 1,
intent, PendingIntent.FLAG_UPDATE_CURRENT);
return pendingIntent;
}
public static void startClockAlarm(Context context) {
AlarmManager alarmManager = (AlarmManager) context
.getSystemService(Context.ALARM_SERVICE);
clockIntent = createClockIntent(context);
alarmManager.setRepeating(AlarmManager.RTC, 0,
600000, clockIntent);
}
You can use the Alarm manager which will be called after every 10 mins
AlarmManager alarmManager = (AlarmManager)getSystemService(Context.ALARM_SERVICE);
Random random = new Random();
int m = random.nextInt(9999 - 1000) + 1000;
Intent notificationIntent = new Intent("android.media.action.DISPLAY_NOTIFICATION");
notificationIntent.setClass(this,AlarmReceiver_.class);
notificationIntent.addCategory("android.intent.category.DEFAULT");
PendingIntent broadcast = PendingIntent.getBroadcast(YourClass.this, m, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT);
alarmManager.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP,
SystemClock.elapsedRealtime() + 300000L,
600000L, broadcast);
ManiFest receiver Code where you will get a receiver response
<receiver android:name="com.yourpackage.AlarmReceiver_"
>
<intent-filter>
<action android:name="android.media.action.DISPLAY_NOTIFICATION" />
<category android:name="android.intent.category.DEFAULT" />
<action android:name="android.intent.action.QUICKBOOT_POWERON" />
<action android:name="android.intent.action.REBOOT" />
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
You will have to create Receiver where you will receive data as an above-specified name of AlarmReceiver_.class

How to display the notification using service?

I was trying to display the notifications using background service for which I wrote 3 classes. The service should run in background even if the appllication closed and and it should start running automatically so I used ,
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<receiver android:name="com.s2si.ucom.ui.UcomBroadcastReceiver" >
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
So in onReceive() of BroadcastReceiver class I am starting the service using,
Intent service = new Intent(context, AlarmService.class);
context.startService(service);
In service class I am using AlarmManager to set particular interval so that I can display notification for every period of time. and finally I am invoking the BroadcastReceiver class to display the notification using AlarmManager. The problem is I am not getting the output :-(...instead of that I am getting error like, Couldn't load memtrack module (No such file or directory)... I am literally new to android coding...Can any one help me how to display notifications in such manner..and let me know what I did wrong above...Thanks much :-).
code in onCreate() method of service class,
Intent intent = new Intent(context, NotificationServiceReceiver.class);
PendingIntent sender = PendingIntent
.getBroadcast(context, 0, intent, 0);
// We want the alarm to go off 5 seconds from now.
long firstTime = SystemClock.elapsedRealtime();
firstTime += 5 * 1000;// start 5 seconds after first register.
// Schedule the alarm!
AlarmManager alarmManager = (AlarmManager) context
.getSystemService(ALARM_SERVICE);
alarmManager.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP,
firstTime, 5000, sender);// 5seconds interval
in short this is how you create a broadcast
private static final String ACTION_ALARM = "your.company.here.ACTION_ALARM";
public static void createAlarm(){
Intent alarmIntent = new Intent();
alarmIntent.setAction(ACTION_ALARM);
PendingIntent pi = PendingIntent.getBroadcast(context, 0, alarmIntent, 0);
AlarmManager am = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
am.set(AlarmManager.RTC_WAKEUP, timestamp for alarm, pi);
}
public void onReceive(...){
//whatever is supposed to happen on receive
}
and you need to declare that broadcastreceiver and the actionname its supposed to receive in manifest:
<receiver
android:name="your.company.here.AlarmReciever">
<intent-filter>
<action android:name="your.company.here.ACTION_ALARM" />
</intent-filter>
</receiver>

onReceiver of BroadcastReceiver not called, AlarmManager

I am building a cab booking app, I need current location of the cab every 20 seconds.
I have defined a AlarmManager and need it to repeat itself every 20 seconds. But its not repeating itself regularly. Instead it repeated itself after 233 seconds, and just once. What am I doing wrong here ?
My HomeScreen has a inner class OnAlarmReceiver, in the onCreate of my HomeScreen I am calling AlarmManager
AlarmManager mgr = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
Intent i = new Intent(this, OnAlarmReceiver.class);
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
PendingIntent pi = PendingIntent.getBroadcast(this, 0, i, PendingIntent.FLAG_CANCEL_CURRENT);
Calendar cal = Calendar.getInstance();
cal.add(Calendar.SECOND, 20);
mgr.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP,
cal.getTimeInMillis(), God.UPDATE_PENDING_INTERVAL, pi);
Inner class in HomeScreen
public class OnAlarmReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
// PullPendingRequests.acquireStaticLock(context);
Toast.makeText(context, "Don't panik but your time is up!!!!.", Toast.LENGTH_LONG)
.show();
Log.d("Taxeeta:PullPendingRequets", "CallService Location");
context.startService(new Intent(context, PullPendingRequests.class));
}
}
My AndroidManifest file has
<service
android:name="com.taxeeta.support.PullPendingRequests"
android:enabled="true"
android:label="#string/app_name"
android:screenOrientation="portrait"
android:theme="#android:style/Theme.Light.NoTitleBar" />
<receiver android:name=".com.taxeeta.HomeScreen.OnAlarmReceiver" />
</application>
Output of adb shell dumpsys alarm
com.taxeeta
51471ms running, 5248 wakeups
5248 alarms: flg=0x4 cmp=com.taxeeta/.HomeScreen$OnAlarmReceiver
Output of adb shell dumpsys alarm | grep taxeeta
ELAPSED_WAKEUP #7: Alarm{409303b0 type 2 com.taxeeta}
operation=PendingIntent{408ba2d8: PendingIntentRecord{40887be8 com.taxeeta broadcastIntent}}
com.taxeeta
5248 alarms: flg=0x4 cmp=com.taxeeta/.HomeScreen$OnAlarmReceiver
To fix it, I removed the inner class OnAlarmReceiver and fixed the androidmanifest.xml file.
<receiver
android:name="com.taxeeta.support.OnAlarmReceiver"
android:exported="true" >
<intent-filter>
<action android:name="android.intent.action.NOTIFY" />
</intent-filter>
</receiver>
If the answer above doesn't work for you then there is another way to not receive any callbacks when AlarmManager fires an expired alarm. You simply need to check this one out: by sending the wrong Intent on instantiation of PendingIntent. For example you wanted to receive a call onReceive on one of your receivers but you instantiated a PendingIntent via getActivity or getService, but what you actually meant is getReceiver.
When creating instance of PendingIntent, there are many ways to create it (getService, getActivity,getReceiver, getForegroundService:
if you want Activity the receiver of the intent then you:
PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_*);
if you want BroadcastReceiver the receiver of the intent:
PendingIntent.getReceiver(this, 0, intent, PendingIntent.FLAG_*);
if you want a foreground Service the receiver of the intent:
PendingIntent.getForegroundService(this, 0, intent, PendingIntent.FLAG_*);
if you want a Service the receiver of the intent:
PendingIntent.getService(this, 0, intent, PendingIntent.FLAG_*);
Also, make sure you intents are pointing to the correct class. (e.g. creating intents for Activity, Service etc.). You will not receive any call if you pass wrongfully like this:
Intent intent = new Intent(this, MyReceiver.class); // You wanted receiver
// PendingIntent was created in such a way
// you wanted this to be received by an activity.
// you will not receive any call if you set it up like this.
PendingIntent = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_*);
I also posted similar answer here.
HTH
This piece of code worked for me and make sure you have added reciever in android manifest file.
AlarmManager service = (AlarmManager) context
.getSystemService(Context.ALARM_SERVICE);
Intent i = new Intent(context, OnAlarmReceiver.class);
PendingIntent pending = PendingIntent.getBroadcast(context, 0, i,
PendingIntent.FLAG_CANCEL_CURRENT);
Calendar cal = Calendar.getInstance();
// Start 20 seconds after boot completed
cal.add(Calendar.SECOND, 20);
//
// Fetch every 20 seconds
// InexactRepeating allows Android to optimize the energy consumption
service.setInexactRepeating(AlarmManager.RTC_WAKEUP,
cal.getTimeInMillis(), 1000*20, pending);
The above solutions didn't work for me.
Additionally, registering dynamically via code did the trick:
Intent intent = new Intent();
intent.setAction("android.intent.action.NOTIFY");
//Register the receiver
context.registerReceiver(new OnAlarmReceiver(),new IntentFilter());
For anyone still stuck - make sure your broadcast receiver is not crashing in the background. Make sure to check your LogCat!

Broadcast receiver not called

I know this a basic problem but it is still driving me crazy. I am setting a repeating alarm but the receiver is never called.
Intent intent = new Intent(NewSchedule.this, RepeatingAlarm.class);
PendingIntent sender = PendingIntent.getBroadcast(NewSchedule.this, 0, intent, 0);
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
calendar.add(Calendar.SECOND, 10);
AlarmManager am = (AlarmManager) getSystemService(ALARM_SERVICE);
am.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP, calendar.getTimeInMillis(), 5 * 1000, sender);
Log.i("calendar",calendar.getTimeInMillis() + "");
Toast.makeText(NewSchedule.this, "repeating_scheduled", Toast.LENGTH_SHORT).show();
public class RepeatingAlarm extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(context, "repeating_received", Toast.LENGTH_LONG).show();
}
}
<receiver android:name=".RepeatingAlarm" android:process=":remote" />
I am testing on my phone. The calendar log shows the exact time. I never get the Toast in the receiver class.
Reference : Android Alarm Manager with broadcast receiver
Intent sender = new Intent("WhatEverYouWant");
PendingIntent senderPIntent = PendingIntent.getBroadcast(context, 0, sender, 0);
AlarmManager alarm = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
alarm.set(AlarmManager.RTC_WAKEUP, triggerTime, senderPIntent);
// In Manifest.xml file
<receiver android:name="com.package.YourOnReceiver">
<intent-filter>
<action android:name="WhatEverYouWant" />
</intent-filter>
</receiver>
Actually it turned out my code was good. Somehow the alarm was up and running and thus for some unknown reason (at least to me) the recevier could not be called. I figured it out when I created a new project and tested that that receiver was working fine. I also had to stop that alarm. Then I went back to my original project and started the same alarm without changing any lines and it was working fine. Has anyone experienced this?

AlarmManager occasionally doesn't fire alarm

I'm developing a live wallpaper for Android. To refresh the wallpaper at set times I use AlarmManager. Most of the times this works great, but occasionally my alarm isn't received. On top of that I can't replicate this behaviour, it just randomly happens. I've run into this using at least 3 ROMs.
Now for the code.
I use this PendingIntent:
mRefreshIntent = new Intent()
.setComponent(new ComponentName(mContext, RefreshBroadcastReceiver.class))
.setAction("my.package.name.REFRESH_WALLPAPER");
mPendingRefreshIntent = PendingIntent.getBroadcast(
mContext,
0,
mRefreshIntent,
PendingIntent.FLAG_CANCEL_CURRENT);
This is my code to set the alarm:
mAlarmManager.set(AlarmManager.RTC_WAKEUP, time, mPendingRefreshIntent);
where time is the UTC time in milliseconds. I often verified if the alarm is set as intended using adb shell dumpsys alarm, which it is.
The receiving side:
public class RefreshBroadcastReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Log.d("DayNight", "onReceive ; " + System.currentTimeMillis());
DayNightService.refresher.refresh();
Log.d("DayNight", "onReceive done; " + System.currentTimeMillis());
}
}
Associated manifest lines:
<application>
...
<receiver
android:name="RefreshBroadcastReceiver">
<intent-filter>
<action android:name="my.package.name.REFRESH_WALLPAPER" />
</intent-filter>
</receiver>
...
</application>
Alarms which are not fired always exist in the queue (dumpsys alarms) beforehand, and are not in the alarm log afterwards. Seems like they get 'lost' at T minus zero.
I will be very happy if one of you can solve this problem for me.
I use following code:
Intent intent = new Intent(ACTION);
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_NO_CREATE);
Log.d(LOG_TAG, "pending intent: " + pendingIntent);
// if no intent there, schedule it ASAP
if (pendingIntent == null) {
pendingIntent = PendingIntent.getBroadcast(context, 0, intent, 0);
// schedule new alarm in 15 minutes
alarmService.setInexactRepeating(AlarmManager.RTC, System.currentTimeMillis(),300000, pendingIntent);
Log.d(LOG_TAG, "scheduled intent: " + pendingIntent);
}
Note, that I request inexact repeating alarm and RTC ( not RTC_WAKEUP ) - if phone is sleeping deep inside jeans pocket, user is not interested on changes of your live wallpaper - no need to waste battery juice and wake phone up
You may also need to register boot complete broadcast receiver to start update scheduling
on reboot.

Categories

Resources