Broadcast not getting called with AlarmManager - android

I'm having trouble with the broadcast message the alarm manager should send.
This is my code:
case Intent.ACTION_BOOT_COMPLETED:
long repeatInterval = 10*1000;
long triggerTime = SystemClock.elapsedRealtime() + repeatInterval;
AlarmManager manager = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
if(manager != null){
Intent in = new Intent(context, AppReceiver.class);
in.setAction("haz");
PendingIntent inte = PendingIntent.getBroadcast(context, 500, in, PendingIntent.FLAG_UPDATE_CURRENT);
manager.setInexactRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP, triggerTime, repeatInterval, inte);
}
break;
That's being triggered correctly with the action boot completed broadcast message, but that piece of code if I'm right should call the app receiver with the "haz" action, but that's not being called, ever.
I've tried to create a service but that's also not being called.
Anyone has any clue for what I have to do?

<receiver android:name=".YourReceiver">
<intent-filter android:priority="1000">
<action android:name="android.intent.action.BOOT_COMPLETED" />
<!-- check properly boot intent syntax for manifest file -->
</intent-filter>
</receiver>

I've found a solution thanks to CommonsWare reply to my question. The answer was to have another receiver separately probably because android can't handle fast repetitions. Mine wasn't going to be that short in the end, it was for testing purposes only, but having two receivers and to call the second one with the repetitions was the answer. Thank you both #CommonsWare and #Arwy Shelke for your time and responses!!

Related

Oreo: Alarm is not fired when Application is not running

I have relatively simple setup that should trigger an alarm at certain time of the day and show a notification to user. here is relative code,
Setting the alarm
long inTime = /*expirationTime*/ Calendar.getInstance().getTimeInMillis() + 10000;
Intent startIntent = new Intent("parking.event");
startIntent.setClass(getBaseContext(), ParkingExpirationWarmingBroadcast.class);
PendingIntent startPendingIntent = PendingIntent.getBroadcast(this, 99, startIntent, 0);
alarmMgr.setExact(AlarmManager.RTC_WAKEUP,
inTime,
startPendingIntent);
BroadcastReceiver registered
<receiver
android:name=".modules.parking.ParkingExpirationWarmingBroadcast"
android:enabled="true">
<intent-filter>
<action android:name="parking.event" />
</intent-filter>
</receiver>
Broadcast Receiver
class ParkingExpirationWarmingBroadcast : BroadcastReceiver() {
#SuppressLint("NewApi")
override fun onReceive(context: Context, intent: Intent) {
}
}
The receiver is only getting triggered if app is in background. as soon as i swipe the app from multitasking, the notification is cleared and no new Alarms are triggered. I checked this setup on Android 7.0 and BroadcastReceiver is triggered regardless of app running or not.
I am aware regarding restrictions over implicit broadcasts in Android Oreo but i don't believe the intent that i have mentioned above is considered implicit.
Can anyone point out what i am doing wrong?
This is a general behavior of any Android's version. If you force-quit an application, then its Alarms and PendingIntents are deleted as well.
You can find the same answer here and here.
Force closing an app destroys its components . This is what force stop does. It's not a bug, it is very much a feature. Follow the following thread , it has been discussed by android framework engineers .
https://groups.google.com/forum/?fromgroups=#!topic/android-developers/anUoem0qrxU

AlarmManager alarm disappears randomly after being set

To quickly summarize the issue the alarm that is set disappears between when I set it and sometime the next day. My code all seems to work properly, alarms are set and go off at proper times. After the initial alarm fires and completes, it is automatically set for the next day. I can check and see it with adb shell's dumpsys alarm.
update: I have added some more log information just below here
[14/01/2017 20:57:41] Registering start alarm 1 with Alarm Manager event time: 14/01/2017 21:00:00
[14/01/2017 20:57:41] Registering stop alarm 1001 with Alarm Manager event time: 14/01/2017 21:01:00
[14/01/2017 21:00:00] Receiver has received INTENT_ACTION_ALARM_START and is launching the music player for task #1.
[14/01/2017 21:01:00] Receiver has received INTENT_ACTION_ALARM_STOP and is stopping the music player, and sending a restart request to the MusicService.
[14/01/2017 21:01:00] Restart requested on alarm 1, attempting to add new alarms for tomorrow.
[14/01/2017 21:01:00] Registering start alarm 1 with Alarm Manager event time: 15/01/2017 21:00:00
[14/01/2017 21:01:00] Registering stop alarm 1001 with Alarm Manager event time: 15/01/2017 21:01:00
Batch{43d23730 num=1 start=86684689 end=86684689}:
RTC_WAKEUP #0: Alarm{438c1740 type 0 org.hudsoft.music}
type=0 whenElapsed=86684689 when=+23h55m1s357ms window=0 repeatInterval=0 count=0
operation=PendingIntent{43af9370: PendingIntentRecord{43ddd9a8 org.hudsoft.music broadcastIntent}}
Batch{43d1e348 num=1 start=86744688 end=86744688}:
RTC_WAKEUP #0: Alarm{438c10d8 type 0 org.hudsoft.music}
type=0 whenElapsed=86744688 when=+23h56m1s357ms window=0 repeatInterval=0 count=0
operation=PendingIntent{438ea450: PendingIntentRecord{4393a970 org.hudsoft.music broadcastIntent}}
When I go to bed though and wake up and check the next day the Alarm is curiously missing from the adb shell dumpsys output, it also never executes.
My question is where does the alarm go to without any user interaction? How can I set an alarm that will persist? The documentation claims that "The Alarm Manager is intended for cases where you want to have your application code run at a specific time, even if your application is not currently running"
My current design is that when the app opens or when BOOT event is received by receiver I run an IntentService that sets all my alarms and goes away, assuming Alarm Manager will handle
the rest. My receiver should wait for the response, problem is each night I go to sleep I wake up and my alarm manager rtc wakeup's have mysteriously disappeared.
If you need any other information to help diagnose the issue please let me know this is my first post I have been struggling with and searching for a solution for about a week!
in my receiver this fires to stop the music playing service and also restart a new alarm for the next day:
if (intent.getAction().equals("INTENT_ACTION_ALARM_END")) {
Intent stopIntent = new Intent(context, MusicPlayer.class);
Task thisTask = (Task) intent.getSerializableExtra("thisTask");
stopIntent.putExtra("thisTask", thisTask);
context.stopService(stopIntent);
Intent restartAlarmIntent = new Intent(context, MusicService.class);
restartAlarmIntent.setAction("INTENT_ACTION_ALARM_RESTART");
restartAlarmIntent.putExtra("thisTask", thisTask);
context.startService(restartAlarmIntent);
}
Here is the code I use to build and start the alarms
Intent myIntent = new Intent(this, MusicReceiver.class);
myIntent.setAction("INTENT_ACTION_ALARM_START");
myIntent.putExtra("thisTask", task);
Log.d("Intent", "Sending start intent now");
PendingIntent pendingStartIntent = buildAlarmIntent(task, "INTENT_ACTION_ALARM_START");
setSingleExactAlarm(endTime, pendingStartIntent);
myIntent = new Intent(this, MusicReceiver.class);
myIntent.setAction("INTENT_ACTION_ALARM_END");
myIntent.putExtra("thisTask", task);
Log.d("Intent", "Sending end intent now");
PendingIntent pendingStopIntent = buildAlarmIntent(task, "INTENT_ACTION_ALARM_END");
setSingleExactAlarm(endTime, pendingStopIntent);
public PendingIntent buildAlarmIntent (Task task, String action) {
PendingIntent pendingIntent;
Intent myIntent = new Intent(this, MusicReceiver.class);
myIntent.setAction(action);
myIntent.putExtra("thisTask", task);
Integer idNum = task.getId();
if (action.equals("INTENT_ACTION_ALARM_END")) {
idNum += 1000;
pendingIntent = PendingIntent.getBroadcast(this, idNum, myIntent, PendingIntent.FLAG_UPDATE_CURRENT);
} else {
pendingIntent = PendingIntent.getBroadcast(this, idNum, myIntent, PendingIntent.FLAG_UPDATE_CURRENT);
}
return pendingIntent;
}
private void setSingleExactAlarm(long time, PendingIntent pIntent) {
AlarmManager mAlarmManager;
mAlarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
if (android.os.Build.VERSION.SDK_INT >= 19) {
mAlarmManager.setExact(AlarmManager.RTC_WAKEUP, time, pIntent);
} else {
mAlarmManager.set(AlarmManager.RTC_WAKEUP, time, pIntent);
}
}
Here is the receiver section of my AndroidManifest
<receiver
android:name=".MusicReceiver"
android:enabled="true"
android:exported="true"
android:process=":remote">
<intent-filter>
<action android:name="INTENT_ACTION_ALARM_START" />
<action android:name="INTENT_ACTION_ALARM_END" />
<action android:name="android.intent.action.BOOT_COMPLETED" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</receiver>
Thanks in advance for taking the time to look into my issue!
I have found my issue and I thought I would post it in case anyone else runs into a similar issue. My alarms were restarting themselves with the previous times I had set before. Since the time had already passed they would resolve immediately and disappear. This also caused a loop where it would try to restart it again and again but I believe the alarm manager realizes this is happening after events and stops queuing them up to prevent an infinite loop of resetting alarms that have a start time in the past. Hope this helps someone!
I do not have enough reputation to leave a comment, as I do not have a definite answer. However, Is there possibility that your phone is powering off? According to the Android documentation:
https://developer.android.com/reference/android/app/AlarmManager.html
"Registered alarms are retained while the device is asleep (and can optionally wake the device up if they go off during that time), but will be cleared if it is turned off and rebooted."
It is difficult to diagnose further without the code behind receiving BOOT_COMPLETED.
In the past I have used the following to set an alarm, and I do not have the issue you have described:
AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(context, MyBroadcastReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT);
alarmManager.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, alarmStartTime.getTimeInMillis(), pendingIntent);
I hope this helps, and good luck.

AlarmManager is discarded when application is cleared from background

This is how I am creating an alarm.
When the app is still running in background the alarm is fired.
but when it is cleared from the recent apps, the alarm is getting discarded. I am registering a new receiver and providing a unique action for differentiation between two alarms. Is there any mistake in my code.
String filter_action = "myPackageName" + request_code_value +"_time";
IntentFilter filter = new IntentFilter(filter_action);
registerReceiver(new AlarmReciever(), filter);
Intent intent = new Intent(filter_action);
intent.putExtra(getString(R.string.get_current_intent_value), request_code_value);
intent.putExtra(getString(R.string.alarmtext), alarm_title);
intent.putExtra(getString(R.string.alarm_time), newAlarm_Choose_Alarm_Value.getText().toString());
Calendar calNow = Calendar.getInstance();
Calendar calSet = (Calendar) calNow.clone();
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, request_code_value, intent, 0);
calSet.setTimeInMillis(timeInMillis);
if (calSet.compareTo(calNow) <= 0) {
// Today Set time passed, count to tomorrow
calSet.add(Calendar.DATE, 1);
}
alarmManager.set(AlarmManager.RTC_WAKEUP, calSet.getTimeInMillis(), pendingIntent);
Manifest file.
<receiver android:name="com.bigbangpartners.YoWakeUp.activities.AlarmReciever" >
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
<action android:name="AlarmManager_Start" />
</intent-filter>
</receiver>
Please help me.
Thanks in advance.
If you are registering and de-registering the BroadcastReceiver programmatically in your Activitys, then a BroadcastReceiver created in this way will remain in existence only as long as the app process is alive. So when you remove your app from the list of recent apps, this BroadcastReceiver is also, in effect, destroyed.
On the other hand, a BroadcastReceiver registered in the manifest is a global, permanent component of an Android app that remains in existence forever, whether the app process is alive or not.
If you want your alarms to be activated even when the app is not in the foreground, then you need to register the BroadcastReceiver in the app manifest and specify the alarm action as well. You are not doing that, and this, I believe, is the root of your problem.
What you should do:
1. Define your BroadcastReceiver in manifest like this:
<receiver android:name="com.bigbangpartners.YoWakeUp.activities.AlarmReciever" >
</receiver>
2. Remove all calls to registerReceiver() and unRegisterReceiver() in your app code as that is not needed.
3. Define your alarm Intent like this:
Intent intent = new Intent(this, AlarmReceiver.class);
Rest of code remains same. First try this and see if it works.

Cannot start Widget Update With Alarm Manager and PendingIntent

I am trying for couple of days to solve this problem , hope someone can help me.
I am using Alarm Manager to make my widget update nay time i want (if to sue XML its only once in 30 min) so i made a pending intent and wrote it like in the examples that i found but , its updates only once when i compile the program.
Here is mu code:
#Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds)
{
android.util.Log.w("FullTankWidget.UpdateService", "onUpdate()");
Intent updateIntent = new Intent("android.appwidget.action.APPWIDGET_UPDATE");
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, updateIntent, PendingIntent.FLAG_CANCEL_CURRENT);
AlarmManager alarmManager = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
// alarmManager.setRepeating(AlarmManager.RTC, nextMinute.getTimeInMillis(),60000,pendingIntent);
long firstTime = SystemClock.elapsedRealtime();
alarmManager.set(AlarmManager.RTC, firstTime + (60 * 1000), pendingIntent);
android.util.Log.w("FullTankWidget.UpdateService", String.valueOf(firstTime));
// To prevent any ANR timeouts, we perform the update in a service
context.startService(new Intent(context,WidgetUpdateService.class));
the intent filter is writen in the manifest - defoult widget reciever
<receiver android:name=".FullTankWidget" >
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
</intent-filter>
<meta-data android:name="android.appwidget.provider" android:resource="#xml/fulltank_widget_config" />
</receiver>
But your alarmManager.setRepeating() line is commented out...
First of all you should also specify your class in the Intent.
updateIntent.setClass(context, YourProviderClassName.class);
Then it is subject of the PendingIntent. There is a PendingIntent filter working on the background that does not allow two similar Intents to be set as pending. So when it is called, it will be ignored if there is a similar intent to it.
If in your appwidget provider info you have a value set for updatePeriodMillis other than zero, then the system has already set a PendingIntent for updating. This is why your new PendingIntent won't work.
The solution is to disable updatePeriodMillis and use AlarmManager instead. The AlarmManager class has methods that help you set PendingIntents the way you want. But remember you will still have only one PendingIntent at a time.

C2DM registration retry

I\m using C2DM and it's working fine if the registration was successfull. But sometimes registration fails and then it tries to register later:
Intent retryIntent = new Intent(C2DM_RETRY);
PendingIntent retryPIntent = PendingIntent.getBroadcast(context,
0 /*requestCode*/, retryIntent, 0 /*flags*/);
AlarmManager am = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
am.set(AlarmManager.ELAPSED_REALTIME,
backoffTimeMs, retryPIntent);
But what to do if the alarm manager fires this intent? will i have to catch it? Because somehow the program never retrys to register.
First of all. The retry code supplied is WRONG! Yes, even folks from google can publish wrong code!
The am.set method (in C2DMBaseReceiver.handleRegistration) takes in the time since bootup in milliseconds that the the intent should fire at. We are passing in 30000, 60000, 120000 etc. All these values will be WELL in the past. What we should pass in is:
am.set(AlarmManager.ELAPSED_REALTIME, SystemClock.elapsedRealtime() + backoffTimeMs,
retryPIntent);
This means we are saying the next intent should be fired at now + backOffTimeMs. This is the first bug in the published code.
The second bug is that there is no BroadcastReceiver that is wired up to receive the
com.google.android.c2dm.intent.RETRY
intent!
So, we include the following addition in the manifest file:
<receiver android:name="com.google.android.c2dm.C2DMBroadcastReceiver">
<intent-filter>
<action android:name="com.google.android.c2dm.intent.RETRY"/>
<category android:name="com.google.android.apps.chrometophone" />
</intent-filter>
</receiver>
(this is an additional block, leave all other things as is)
And there you go! It will start working!

Categories

Resources