How to detect when a new alarm is set in Android - android

I would like to detect when a new alarm is set in Android default alarm application (I am using a Samsung device).
I tried: filter.addAction(AlarmManager.ACTION_NEXT_ALARM_CLOCK_CHANGED);
but it didn't work.
PS: My goal is not to detect whenever an alarm is ringing, but to use a broadcast receiver to monitor when a new alarm is created.
This is the code I am using:
IntentFilter filter = new IntentFilter("android.app.action.NEXT_ALARM_CLOCK_CHANGED");
filter.addAction("com.samsung.sec.android.clockpackage.alarm.SET_ALARM");
registerReceiver(mReceiver, filter);

From API Level-21 and above you can use below solution in your AndroidManifest.xml for the registered BroadcastReceiver.
<receiver
android:name=".YourAlarmReceiverClass"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="android.app.action.NEXT_ALARM_CLOCK_CHANGED">
</action>
</intent-filter>
</receiver>
ACTION_NEXT_ALARM_CLOCK_CHANGED is sent after the value returned by getNextAlarmClock() has changed, and your BroadcastReceiver's onReceive() will be called each time when user creates a new Alarm using Alarm clock application.

The intent AlarmManager.ACTION_NEXT_ALARM_CLOCK_CHANGED will be only triggered when the next alarm to ring is changed, not when any alarm is changed. As long as you are not allowed to get a list of all active alarms in your device... probably you won't be allowed either to get an intent when one alarm is added. Ther isn't any intent which does what you ask for.

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

Android: open activity when alarm clock is done or dismmised

Every alarm clock that the user set through the phone stock clock has an option of opening another application when the alarm is dismissed or done (I'm not sure if this feature is added in Marshmallow but I have it and I run android M).
The default for each alarm is "none" but you're able to pick the mail, weather, music applications etc...
I would like to add my application to this list so it'll open directly when the alarm is done.
What settings are needed for my application to show up at this list, and how can I set it as the default app for specific alarm (What extra should be specefied)
Intent i = new Intent(AlarmClock.ACTION_SET_ALARM);
i.putExtra(AlarmClock.EXTRA_MESSAGE, "New Alarm");
i.putExtra(AlarmClock.EXTRA_HOUR, 10);
i.putExtra(AlarmClock.EXTRA_MINUTES, 30);
startActivity(i);
So it seems that there's no option to add your app to the desired list which allow the user to pick an application to open immediately after the alarm has been dismissed or done.
My other solution is to listen to that specific event of dismissing or done through broadcast receiver. This might be a bit tricky because the event has multiple names according to the device.
I have LG phone so my event is com.lge.clock.alarmalert.stop, but you'll have to figure out whats the event for each device. I've seen some similar topics as this one.
Here's my manifest declaration for the receiver:
<receiver android:name=".Receiver.AlarmBroadcastReceiver">
<intent-filter>
<action android:name="com.android.deskclock.ALARM_DISMISS" />
<action android:name="com.android.deskclock.ALARM_DONE" />
<action android:name="com.lge.clock.alarmalert.stop" />
</intent-filter>
</receiver>
The deskclock is the default stock clock running on some devices, as I mentioned, I had to find the action for the LG phones and added it aswell.
The Receiver:
#Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (action.equals("com.android.deskclock.ALARM_DISMISS") || action.equals("com.android.deskclock.ALARM_DONE") || action.equals("com.lge.clock.alarmalert.stop"))
{
////Do Something
}
}

Android: is android.intent.action.DATE_CHANGED triggered at device reboot?

I made this broadcast receiver
public class DateReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Log.i("DATE RECEIVER", "OK");
}
}
registered in manifest
<receiver
android:name=".DateReceiver"
android:enabled="true"
android:exported="false" >
<intent-filter>
<action android:name="android.intent.action.DATE_CHANGED" />
</intent-filter>
</receiver>
It works when device is on but if I turn it off and wait for midnight to pass, then I don't get any intent at reboot. How should I get it?
You won't get this broadcast because date has NOT changed (unless i.e. there's time update after the boot). It is different but has not changed in the way that justifies this broadcast. This may be confusing but in fact it does not matter what time stamp is when device starts. As device was started it does not know if that was because of restart or it was off for 5 weeks. Broadcast will be send if time is artificially changed i.e. due to network time sync, manual time change via preferences, timezone change. Normal ticking does not count. Initial time stamp does not matter.
If you need to know date on boot, you should listen to BOOT_COMPLETED.
You also need to remove android:exported="false" or set it to true as otherwise it is not reachable.

Resetting alarms on reboot

User can create different alarms. So it's up to user when to keep alarm and he can keep multiple alarms and I maintain all the scheduled alarms in a database and show to the user for further reference. Below is my code.
if("CREATEONCE".equals(strparam1))
{
am.set(AlarmManager.RTC_WAKEUP, l2, pi);// l2 is time in millis
}else if("CREATEREPEAT".equals(strparam1))
{
am.setRepeating(AlarmManager.RTC_WAKEUP, l2, 86400000 , pi); //l2 is time in millis
}
So this is the code which sets the alarms. User can set multiple alarms. For example he keeps an alarm for 7.00 am for once, 8.00 am for once and 9.00 am dialy. So, for once alarms the code goes to if block and for repeat daily, the code goes to else if block in the code.
If the above 3 alarms are set by user at 6.00 am. If he reboots his device immediately after setting the alarms, the entire alarms don't trigger.
So I have read many posts regarding this like post1, post2. They all just gave to use broadcast receiver to know that device is rebooted. After the broadcast receiver receives a hint that device is rebooted, do I need to repeat above code again by getting the info from sqlite database to make all the alarms work? If so, can someone help me the way to do that from the broadcast receiver? Code snippets are appreciated
Suppose if the user sets 50 alarms, wouldn't it be a long process to get the info of all the 50 alarms and set them again?
I don't know how you are storing your alarms. But I suggest it would suffice to set up a system level alarm for the earliest coming alarm. Then once that is triggered, set up the alarm again for the next soonest triggering alarm.
I suggest putting your AlarmSetting call in a service and then call it from a broadcast receiver.
public class AlarmResetReceiver extends BroadcastReceiver {
public void onReceive(Context context, Intent intent) {
//your code to set up alarms
}
}
There are also other conditions upon which you want to set your alarms up again in your manifest
<receiver android:name=".receivers.AlarmResetReceiver">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
<action android:name="android.intent.action.TIME_SET" />
<action android:name="android.intent.action.TIMEZONE_CHANGED" />
<action android:name="android.intent.action.LOCALE_CHANGED" />
</intent-filter>
</receiver>

Android receivers being ignored when activity is not active

I have a background service which has a receiver for connectivity change which only seems to be received if the activity is active.
#Override
public void onCreate() {
mContext = this;
IntentFilter connectivityChangeFilter = new IntentFilter("android.net.conn.CONNECTIVITY_CHANGE");
registerReceiver(receiver, connectivityChangeFilter);
I've set it up in the manifest as follows:
<service
android:name="com.myservice.TimeService"
android:label="com.myservice.TimeService" >
<intent-filter>
<action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
</intent-filter>
</service>
I have another receiver for boot completed which works ok, which is registered as a receiver in the manifest (unlike this one).
Is the intent filter not enough to run a broadcast? I would want the receiver to call a method on the service so it needs to be able to access methods of the service but I don't think receivers can bind to services.
-- Update
In a nutshell, I want to know if I can statically declare a receiver that interacts with a service. Dynamic declaration works only if the app is active.
Use android sticky intent
A normal broadcast Intent is not available anymore after is was send and processed by the system. If you use the sendStickyBroadcast(Intent) method, the Intent is sticky, meaning the Intent you are sending stays around after the broadcast is complete.
example code here:

Categories

Resources