Do I still need database in setting multiple alarms or reminders? - java

So I'm developing this Android application which has many features, and one of them is the workout reminder. We used firebase database in setting up login authentication, and the user's information.
Now for the last feature, I made a workout reminder which consists of Task Name and Time which also has a notification and. It only sets one alarm and I assume that if I applied and displayed it in a Recycler View, it will set multiple alarms. Unfortunately, it doesn't. When the reminder is displayed in the Recycler View, and when I restart the application, the reminder is gone.
I just want to humbly ask if I need to store it in a database and then retrieve it?
Thank you in advance!
Here is my code below:
public class AlertReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
NotificationHelper notificationHelper = new NotificationHelper(context);
NotificationCompat.Builder nb = notificationHelper.getChannel1Notification(reminderAddFragment.getTitle(), reminderAddFragment.getMessage());
notificationHelper.getManager().notify(1, nb.build());
}
}
private void startAlarm(Calendar cal) {
AlarmManager alarmManager = (AlarmManager) getActivity().getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(getActivity(), AlertReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(getActivity(), 1, intent, 0);
alarmManager.setExact(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), pendingIntent);
}

Solved it by setting different requestCode everytime I set an alarm.
private void startAlarm(Calendar cal) {
AlarmManager alarmManager = (AlarmManager) getActivity().getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(getActivity(), AlertReceiver.class);
final int id = (int) System.currentTimeMillis();
PendingIntent pendingIntent = PendingIntent.getBroadcast(getActivity(), id, intent, PendingIntent.FLAG_MUTABLE);
alarmManager.setExact(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), pendingIntent);
}

Yes, you need to persist the state of alarms set by your app and display the same to the user. Once set we cannot retrieve the alarms set by the system at the app level. All we can do is dump them using adb shell using:
adb shell dumpsys alarm > alarms_dump.txt

Related

BroadcastReceiver received more than once

I am getting a problem with my reminder APP.
When I add first reminder broadcast is received once for second time broadcast is received twice for third time it is received thrice.
I tried many different solutions on StackOverfolow but none of them are working
Kindly help me out with detailed answer.
Link to Project
. code is given below:
Function to set Reminder:
public void startAlarm(Calendar c) {
AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(context, AlertReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, number, intent, PendingIntent.FLAG_ONE_SHOT);
alarmManager.setExact(AlarmManager.RTC_WAKEUP, c.getTimeInMillis(), pendingIntent);
}
Class receiving Broadcast:
public class AlertReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(context, intent.getAction(), Toast.LENGTH_LONG).show();
MediaPlayer mediaPlayer = MediaPlayer.create(context, Settings.System.DEFAULT_NOTIFICATION_URI);
mediaPlayer.start();
}
}
I see that you are setting the alarm inside Adapters onBindViewHolder. This is not the right place to setting alarm. Because when you call notifyDataSetChanged it will call onBindViewHolder again and it will set same alarm over and over.

How to stop ringing alarm in Java?

I followed a YouTube guide to get going on an alarm clock app. It seems to be working well, however when the alarm starts to play and I click the button to stop the alarm it does not stop the ringtone service. I've tried looking at other stack overflow questions but could not find a logical answer for myself. I know that my intents are not triggering the ringtone service in the receiver class to stop. Anyone have an idea how to stop the ring tone service from a mainactivityclass and send the trigger to the receiver class?
Mainactivity code to trigger alarm and play ringtone
public void setTimer(View v){
//Make alarmmanager
AlarmManager alarmManager = (AlarmManager)getSystemService(Context.ALARM_SERVICE);
Date currentTime = Calendar.getInstance().getTime();
Calendar cal_alarm = Calendar.getInstance();
Calendar cal_now = Calendar.getInstance();
cal_now.setTime(currentTime);
cal_alarm.setTime(currentTime);
cal_alarm.set(Calendar.HOUR_OF_DAY,mHour);
cal_alarm.set(Calendar.MINUTE,mMin);
cal_alarm.set(Calendar.SECOND,0);
if (cal_alarm.before(cal_now)){
cal_alarm.add(Calendar.DATE,1);
}
//Add alarm to ArrayList
Alarms.add(cal_alarm);
showAlarm();
Intent i = new Intent(MainActivity.this,MyBroadcastReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(MainActivity.this, 1, i, 0);
alarmManager.set(AlarmManager.RTC_WAKEUP,cal_alarm.getTimeInMillis(), pendingIntent);
}
//Stop Alarm
public void cancelAlarm(View v){
Intent i = new Intent(getApplicationContext(), MyBroadcastReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(getApplicationContext(), 1, i, 0);
AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
alarmManager.cancel(pendingIntent);
pendingIntent.cancel();
alarmview.setText("Alarm cancelled");
}
Receiver class
public void onReceive(Context context, Intent intent) {
//Set vibration
Vibrator vibrator = (Vibrator)context.getSystemService(Context.VIBRATOR_SERVICE);
vibrator.vibrate(3000);
//Make notification for alarm
Notification notification = new Notification.Builder(context).setContentTitle("WakeMeYup").setContentText("Wake up!").setSmallIcon(R.mipmap.ic_launcher).build();
//Pass notification to Android system
NotificationManager manager = (NotificationManager)context.getSystemService(Context.NOTIFICATION_SERVICE);
notification.flags|= Notification.FLAG_AUTO_CANCEL;
manager.notify(0, notification);
//Play ringtone
Uri notificati = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_RINGTONE);
Ringtone r = RingtoneManager.getRingtone(context, notificati);
r.play();
}
}
I ended up making a Ringtone class, which receives an int that decides whether it should play or stop the alarm. The onclick listeners put an extra message into the intent which is picked up by the ringtone class and reads them so it knows which bit of code to run.

What else is needed to setup an alarm in Android?

I'm trying to make an app that schedules an alarm at a certain time in which the user is suppose to take their medication. I have done everything that most guides and the documentation say it's required to setup the alarm. Here is the method I call when the user presses the button:
private void scheduleAlarm() {
Intent intentAlarm = new Intent(this, AlarmReceiver.class);
PendingIntent pIntent = PendingIntent.getBroadcast(this, alarmeID, intentAlarm, PendingIntent.FLAG_UPDATE_CURRENT);
AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
alarmManager.set(AlarmManager.RTC_WAKEUP, alarmeTime.getTimeInMillis(), pIntent);
}
Here is the AlarmReceiver.class
public class AlarmReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Uri notification = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
Ringtone ringtone = RingtoneManager.getRingtone(context, notification);
ringtone.play();
}
}
and I have put these two lines in the manifest:
<uses-permission android:name="android.permission.WAKE_LOCK"/>
<receiver android:name=".services.AlarmReceiver"/>
And yet, my application is not working. The alarm doesn't go off. What am I doing wrong? What else is needed?
You are currently playing alarm ringtone from BroadcastReceiver. Instead of doing that, you can open an Activity and start playing alarm tone from there. You can use stop() method to stop it (may be from button click within the activity).
BroadcastReceiver
#Override
public void onReceive(Context context, Intent intent) {
//start activity
Intent i = new Intent(CurrentActivity.this, NextActivity.class);
context.startActivity(i);
}
NextActivity.class
//Start your ringtone here
Uri notification = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
Ringtone ringtone = RingtoneManager.getRingtone(context, notification);
ringtone.play();
//Somewhere inside button click
{
ringtone.stop();
}
Just copy pasting this won't work. I believe you can take concept from
here and implement as per your requirement.
And currently there is no any related code that will stop your ringtone.
Okay I am not really sure wither you are asking how to stop the alarm ? or that the alarm is not working at all after the user presses the button but anyhow.
I replaced The alarm with a repeated alarm and launched it using onCreate method and I closed the app and waited for the alarm to go off and it did!
And here is my code just in case:
private void scheduleAlarm() {
Intent intentAlarm = new Intent(this, AlarmReceiver.class);
PendingIntent pIntent = PendingIntent.getBroadcast(this, uniqueID, intentAlarm, PendingIntent.FLAG_UPDATE_CURRENT);
alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
// alarmManager.set(AlarmManager.RTC_WAKEUP, 10000, pIntent);
alarmManager.setInexactRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime() + 1000, 1000, pIntent);
}
Everything else I copied and pasted from your code above.
Edit: If you are seeking the repeated alarm then this the page to go to:
https://developer.android.com/training/scheduling/alarms.html
note: my virtual device API is 24
Change the code as below -
alarmManager.set(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + 1000*60, pIntent);
May be your alarmeTime.getTimeInMillis() is not properly set. You can try the above line. It fires an alarm after 1 min.

Multiple notification on same intent

I am writing an application and in this application I need to set multiple notification with same intent just like open my application whenever user tap on any notification.
All the notification comes on different time and date without having any data but the problem is, if I set two notification for 03:27 PM and 03:28 PM then the first notification (03:27 PM) is canceled (Overwritten by second) and second is working correctly.
I am currently using this code for achieving this goal:
this method is used to set notification from Activity:
public static void setNotificationOnDateTime(Context context, long fireTime)
{
int requestID = (int) System.currentTimeMillis();
AlarmManager am = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
Intent i = new Intent(context, NotificationReceiver.class);
PendingIntent pi = PendingIntent.getBroadcast(context, requestID, i, 0);
am.set(AlarmManager.RTC_WAKEUP, fireTime, pi);
}
and my NotificationReceiver class look like this:
NotificationManager nm;
#Override
public void onReceive(Context context, Intent intent) {
Log.w("TAG", "Notification fired...");
nm = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
PendingIntent contentIntent;
Bundle bundle = intent.getExtras().getBundle("NotificationBundle");
if(bundle == null)
{
contentIntent = PendingIntent.getActivity(context, 0,
new Intent(context, SplashScreen.class), 0);
}
else
{
contentIntent = PendingIntent.getActivity(context, 0,
new Intent(context, MenuScreen.class)
.putExtra("NotificationBundle", bundle), 0);
}
Notification notif = new Notification(R.drawable.ic_launcher,
"Crazy About Android...", System.currentTimeMillis());
notif.setLatestEventInfo(context, "Me", "Message test", contentIntent);
notif.flags |= Notification.FLAG_AUTO_CANCEL;
nm.notify(1, notif);
}
I alerady spend a lot time on googling and found some solutions but they didn't work for me here is the link of some of them:
android pending intent notification problem
Multiple notifications to the same activity
If any one knows how to do this please help me.
Quote:
Post a notification to be shown in the status bar. If a notification with the same id has already been posted by your application and has not yet been canceled, it will be replaced by the updated information.
But you're always using 1 for the id parameter. Use a unique ID when you post several notifications.
Update If that doesn't help, you can still create Intents which do not compare as being equal, while having an equal effect.
this may be helpful
notif.flags |= Notification.FLAG_ONGOING_EVENT;
the notification will never close...
Try to set as below :
contentIntent=PendingIntent.getActivity(p_context, i, new Intent(context, MenuScreen.class),PendingIntent.FLAG_CANCEL_CURRENT);
It might help you.

Android: How to use AlarmManager

I need to trigger a block of code after 20 minutes from the AlarmManager being set.
Can someone show me sample code on how to use an AlarmManager in ِAndroid?
I have been playing around with some code for a few days and it just won't work.
"Some sample code" is not that easy when it comes to AlarmManager.
Here is a snippet showing the setup of AlarmManager:
AlarmManager mgr=(AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
Intent i=new Intent(context, OnAlarmReceiver.class);
PendingIntent pi=PendingIntent.getBroadcast(context, 0, i, 0);
mgr.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime(), PERIOD, pi);
In this example, I am using setRepeating(). If you want a one-shot alarm, you would just use set(). Be sure to give the time for the alarm to start in the same time base as you use in the initial parameter to set(). In my example above, I am using AlarmManager.ELAPSED_REALTIME_WAKEUP, so my time base is SystemClock.elapsedRealtime().
Here is a larger sample project showing this technique.
There are some good examples in the android sample code
.\android-sdk\samples\android-10\ApiDemos\src\com\example\android\apis\app
The ones to check out are:
AlarmController.java
OneShotAlarm.java
First of, you need a receiver, something that can listen to your alarm when it is triggered. Add the following to your AndroidManifest.xml file
<receiver android:name=".MyAlarmReceiver" />
Then, create the following class
public class MyAlarmReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(context, "Alarm went off", Toast.LENGTH_SHORT).show();
}
}
Then, to trigger an alarm, use the following (for instance in your main activity):
AlarmManager alarmMgr = (AlarmManager)getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(this, MyAlarmReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0, intent, 0);
Calendar time = Calendar.getInstance();
time.setTimeInMillis(System.currentTimeMillis());
time.add(Calendar.SECOND, 30);
alarmMgr.set(AlarmManager.RTC_WAKEUP, time.getTimeInMillis(), pendingIntent);
.
Or, better yet, make a class that handles it all and use it like this
Bundle bundle = new Bundle();
// add extras here..
MyAlarm alarm = new MyAlarm(this, bundle, 30);
this way, you have it all in one place (don't forget to edit the AndroidManifest.xml)
public class MyAlarm extends BroadcastReceiver {
private final String REMINDER_BUNDLE = "MyReminderBundle";
// this constructor is called by the alarm manager.
public MyAlarm(){ }
// you can use this constructor to create the alarm.
// Just pass in the main activity as the context,
// any extras you'd like to get later when triggered
// and the timeout
public MyAlarm(Context context, Bundle extras, int timeoutInSeconds){
AlarmManager alarmMgr =
(AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(context, MyAlarm.class);
intent.putExtra(REMINDER_BUNDLE, extras);
PendingIntent pendingIntent =
PendingIntent.getBroadcast(context, 0, intent,
PendingIntent.FLAG_UPDATE_CURRENT);
Calendar time = Calendar.getInstance();
time.setTimeInMillis(System.currentTimeMillis());
time.add(Calendar.SECOND, timeoutInSeconds);
alarmMgr.set(AlarmManager.RTC_WAKEUP, time.getTimeInMillis(),
pendingIntent);
}
#Override
public void onReceive(Context context, Intent intent) {
// here you can get the extras you passed in when creating the alarm
//intent.getBundleExtra(REMINDER_BUNDLE));
Toast.makeText(context, "Alarm went off", Toast.LENGTH_SHORT).show();
}
}
What you need to do is first create the intent you need to schedule. Then obtain the pendingIntent of that intent. You can schedule activities, services and broadcasts. To schedule an activity e.g MyActivity:
Intent i = new Intent(getApplicationContext(), MyActivity.class);
PendingIntent pi = PendingIntent.getActivity(getApplicationContext(),3333,i,
PendingIntent.FLAG_CANCEL_CURRENT);
Give this pendingIntent to alarmManager:
//getting current time and add 5 seconds in it
Calendar cal = Calendar.getInstance();
cal.add(Calendar.SECOND, 5);
//registering our pending intent with alarmmanager
AlarmManager am = (AlarmManager) getSystemService(ALARM_SERVICE);
am.set(AlarmManager.RTC_WAKEUP,cal.getTimeInMillis(), pi);
Now MyActivity will be launched after 5 seconds of the application launch, no matter you stop your application or device went in sleep state (due to RTC_WAKEUP option).
You can read complete example code Scheduling activities, services and broadcasts #Android
I wanted to comment but <50 rep, so here goes. Friendly reminder that if you're running on 5.1 or above and you use an interval of less than a minute, this happens:
Suspiciously short interval 5000 millis; expanding to 60 seconds
See here.
Some sample code when you want to call a service from the Alarmmanager:
PendingIntent pi;
AlarmManager mgr;
mgr = (AlarmManager)ctx.getSystemService(Context.ALARM_SERVICE);
Intent i = new Intent(DataCollectionActivity.this, HUJIDataCollectionService.class);
pi = PendingIntent.getService(DataCollectionActivity.this, 0, i, 0);
mgr.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime() , 1000, pi);
You dont have to ask userpermissions.
An AlarmManager is used to trigger some code at a specific time.
To start an Alarm Manager you need to first get the instance from the System. Then pass the PendingIntent which would get executed at a future time that you specify
AlarmManager manager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
Intent alarmIntent = new Intent(context, MyAlarmReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, alarmIntent, 0);
int interval = 8000; //repeat interval
manager.setInexactRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(), interval, pendingIntent);
You need to be careful while using the Alarm Manager.
Normally, an alarm manager cannot repeat before a minute. Also in low power mode, the duration can increase to up to 15 minutes.

Categories

Resources