Android: display alert at specific time - java

I am trying to display an alert at a specific time every day (a specific hour and minute),
I used the below code and it worked with me and the alert display at the time I choose,
only when I open the app first time, but the problem is whenever I try to open the app again the alert display even that I set a different time.
Here is my code:
Mainactivity.java
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
startAlarmBroadcastReceiver(this);
}
public static void startAlarmBroadcastReceiver(Context context) {
Intent _intent = new Intent(context, MyBroadcastReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, _intent, 0);
AlarmManager alarmManager = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
alarmManager.cancel(pendingIntent);
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
calendar.set(Calendar.HOUR_OF_DAY, 11);
calendar.set(Calendar.MINUTE, 16);
calendar.set(Calendar.SECOND, 0);
alarmManager.set(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), pendingIntent);
}
MyBroadcastReceiver.java
public class MyBroadcastReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(context, "Alarm....", Toast.LENGTH_LONG).show();
}
}
Any help will be appreciated.

Related

How to set multiple alarms firing distinct notifications for each in Android

I am trying to develop an application in which the user can create more than 1 alarms for the same time ,say, 09:48. And for this time, each alarm has to create its own notification which leads the user to an activity when the notification is clicked. The other alarms which were scheduled at the same time must keep ringing until their notifications are clicked. Now, I am able to create alarms for different times and get their corresponding notifications which lead to an activity in which the user can dismiss or snooze the alarm. However, when I schedule more than one alarm for the same time, only 1 alarm is ringing and the other one gets lost. I share my code pieces at the below.
public void schedule(Context context) {
AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(context, AlarmBroadcastReceiver.class);
PendingIntent alarmPendingIntent = PendingIntent.getBroadcast(context, alarmId, intent, 0);
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
calendar.set(Calendar.HOUR_OF_DAY, hour);
calendar.set(Calendar.MINUTE, minute);
calendar.set(Calendar.SECOND, 0);
calendar.set(Calendar.MILLISECOND, 0);
alarmManager.setExact(
AlarmManager.RTC_WAKEUP,
calendar.getTimeInMillis(),
alarmPendingIntent
);
In my broadcastReceiver class:
private void startAlarmService(Context context, Intent intent) {
Intent intentService = new Intent(context, AlarmService.class);
Log.println(Log.DEBUG, "DEBUG", "************Alarm Broadcast Receiver**********");
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
context.startForegroundService(intentService);
} else {
context.startService(intentService);
}
}
In my AlarmService :
#Override
public void onCreate() {
super.onCreate();
mediaPlayer = MediaPlayer.create(this, R.raw.alarm);
mediaPlayer.setLooping(true);
vibrator = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Intent notificationIntent = new Intent(this, RingActivity.class);
int requestCode = new Random().nextInt(Integer.MAX_VALUE);
PendingIntent pendingIntent = PendingIntent.getActivity(this, requestCode, notificationIntent, 0);
//String alarmTitle = String.format("%s Alarm", intent.getStringExtra(TITLE));
int notificationId = new Random().nextInt(Integer.MAX_VALUE);
Notification notification = new NotificationCompat.Builder(this, String.valueOf(notificationId))
.setContentTitle("PASS1")
.setContentText("PASS2")
.setSmallIcon(R.drawable.pill)
.setContentIntent(pendingIntent)
.build();
mediaPlayer.start();
long[] pattern = { 0, 100, 1000 };
vibrator.vibrate(pattern, 0);
startForeground(1, notification);
return START_STICKY;
}
#Override
public void onDestroy() {
super.onDestroy();
mediaPlayer.stop();
vibrator.cancel();
}
in this code
startForeground(1, notification);
you are using 1 as the id.
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.
So the second alarm notification with the same id (because you are using a fixed value of 1) is replacing the old one

Broadcast Receiver issue, Wakeful Broadcast Receiver

I'm using wakeful broadcast receiver with alarm manager in my app to performing some tasks at a specific time.
its working well. But I'm facing a minor problem
for example I set my alarm manager at 9:00 PM after that if I remove my app from recent app it's definitely working in background, But after that specific time (9:00 PM) whenever I'm using my app my alarm trigger immediately.
I hope everyone (relating this problem) understand my point.
If anyone knows about this problem tell me.
Thanks.
Here I'm registering my receiver
<receiver
android:name="com.example.chartdemo.MyBroadcastReceiver"
android:enabled="true"
android:exported="true">
</receiver>
Here's my MainActivity.java code
public class MainActivity extends AppCompatActivity {
public static TextView textView,textView1;
Button button, button1,button2,button3;
public static int counter=0, time;
MyBroadcastReceiver myBroadcastReceiver;
myDbAdapter helper;
//private final MyDateChangeReceiver mDateReceiver = new MyDateChangeReceiver();
#RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textView=findViewById(R.id.text);
textView1=findViewById(R.id.text1);
button=findViewById(R.id.counterbtn);
button1=findViewById(R.id.showbtn);
button2=findViewById(R.id.savebtn);
button3=findViewById(R.id.delbtn);
helper = new myDbAdapter(this);
loadData(); //for data retrieving from shared preferences
startAlarm(this);
}
private void startAlarm(Context context) {
Calendar cal = Calendar.getInstance();
cal.set(Calendar.HOUR_OF_DAY, 9);
cal.set(Calendar.MINUTE, 0);
cal.set(Calendar.SECOND, 0);
cal.set(Calendar.MILLISECOND, 0);
cal.set(AM_PM, PM);
time= (int) cal.getTimeInMillis();
AlarmManager alarmManager = (AlarmManager)context.getSystemService(ALARM_SERVICE);
Intent intent = new Intent(context, MyBroadcastReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 234, intent, 0);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
alarmManager.setAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), pendingIntent);
Toast.makeText(context, "alarm set after "+cal.getTimeInMillis(), Toast.LENGTH_SHORT).show();
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
alarmManager.setExact(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), pendingIntent);
Toast.makeText(context, "alarm set after "+cal.getTimeInMillis(), Toast.LENGTH_SHORT).show();
} else {
alarmManager.set(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), pendingIntent);
Toast.makeText(context, "alarm set after "+cal.getTimeInMillis(), Toast.LENGTH_SHORT).show();
}
}
And Here's my WakefulBroadcastReceiver.java code
public class MyBroadcastReceiver extends WakefulBroadcastReceiver {
MediaPlayer mp;
myDbAdapter helper;
MainActivity mainActivity=new MainActivity();
#Override
public void onReceive(Context context, Intent intent) {
SharedPreferences sh = context.getSharedPreferences("MySharedPref", MODE_PRIVATE);
int a = sh.getInt("counter", 0);
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
String date = sdf.format(new Date());
helper = new myDbAdapter(context);
long id = helper.insertData(date, String.valueOf(a));
if (id <= 0) {
Toast.makeText(context, "Insertion UnSuccessful", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(context, "Insertion Successful", Toast.LENGTH_SHORT).show();
}
mp = MediaPlayer.create(context, R.raw.alarm);
mp.start();
Toast.makeText(context, "Alarm...!!!!!! ", Toast.LENGTH_LONG).show();
SharedPreferences sharedPreferences = context.getSharedPreferences("MySharedPref", MODE_PRIVATE);
SharedPreferences.Editor myEdit = sharedPreferences.edit();
myEdit.putInt("counter", 0);
myEdit.commit();
}

I get intent error for create alarm clock

I would create an alarm clock, i wrote this code but return this error:
2019-02-05 10:58:13.902 2663-10077/com.google.android.gms
E/ChromeSync: [Sync,SyncIntentOperation] Error handling the intent:
Intent { act=android.intent.action.PACKAGE_ADDED
dat=package:com.example.iacopo.alarmgroup flg=0x4000010
cmp=com.google.android.gms/.chimera.GmsIntentOperationService (has
extras) }.
How can i fix it? thanks
And this code doesn't create a icon af alarm in the notification panel, near the clock
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Calendar cal = Calendar.getInstance();
cal.setTimeInMillis(System.currentTimeMillis());
cal.clear();
cal.set(2018,1,5,10,0);
AlarmManager alarmMgr = (AlarmManager)getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(MainActivity.this, AlarmReceiver.class);
this.startService(intent);
PendingIntent pendingIntent = PendingIntent.getBroadcast(MainActivity.this, 0, intent, 0);
alarmMgr.set(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), pendingIntent);
}
}
and the receiver
public class AlarmReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Log.i("test","ok");
}
}

Alarm successfully sets for future time, but not for Calendar date

I have this app where i want to set a notification on a specific date the user defines. I saw lots of code and relative answers here on SO but for some reason nothing works so far.
In this test project i have 2 methods. One that sets an alarm to ring 5 seconds on future and one that assigns the desired date.
Problem:
If i set the alarm to a second delay it works fine. The notification is shown within 5 seconds after the alarm assignment. But if i use the method that passes a Calendar date, it does nothing. Not triggers no notification
MainActivity.java
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
public void setAlarmOnClick(View view){
// this method call works fine
setAlarm(getNotification("Date test"), 3000);
// this one doesn't
// setAlarm(getNotification("Date test"), getDate());
}
// Here nothing happens when the date comes
private void setAlarm(Notification notification, Calendar cal) {
Intent notificationIntent = new Intent(this, NotificationPublisher.class);
notificationIntent.putExtra(NotificationPublisher.NOTIFICATION_ID, 1);
notificationIntent.putExtra(NotificationPublisher.NOTIFICATION, notification);
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT | Intent.FILL_IN_DATA);
AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
alarmManager.set(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(),pendingIntent );
Toast.makeText(this, "Alarm worked.", Toast.LENGTH_LONG).show();
}
// This alarm get successfully trigger here showing the notification
private void setAlarm(Notification notification, int delay) {
Intent notificationIntent = new Intent(this, NotificationPublisher.class);
notificationIntent.putExtra(NotificationPublisher.NOTIFICATION_ID, 1);
notificationIntent.putExtra(NotificationPublisher.NOTIFICATION, notification);
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT | Intent.FILL_IN_DATA);
AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
alarmManager.set(AlarmManager.RTC_WAKEUP, delay, pendingIntent );
Toast.makeText(this, "Alarm worked.", Toast.LENGTH_LONG).show();
}
private Calendar getDate(){
Calendar cal=Calendar.getInstance();
cal.set(Calendar.MONTH,8);
cal.set(Calendar.YEAR,2017);
cal.set(Calendar.DAY_OF_MONTH,29);
cal.set(Calendar.HOUR_OF_DAY,11);
cal.set(Calendar.MINUTE,47);
return cal;
}
#TargetApi(Build.VERSION_CODES.JELLY_BEAN)
private Notification getNotification(String content) {
Notification.Builder builder = new Notification.Builder(this);
builder.setContentTitle("Scheduled Notification");
builder.setContentText(content);
builder.setSmallIcon(R.mipmap.ic_launcher);
return builder.build();
}
}
NotificationPublisher.java
public class NotificationPublisher extends BroadcastReceiver {
public static String NOTIFICATION_ID = "notification-id";
public static String NOTIFICATION = "notification";
public void onReceive(Context context, Intent intent) {
Toast.makeText(context, "Alarm worked.", Toast.LENGTH_LONG).show();
int id = intent.getIntExtra(NOTIFICATION_ID, 0);
NotificationManager notofManager = (NotificationManager)context. getSystemService(Context.NOTIFICATION_SERVICE);
Notification notification = intent.getParcelableExtra(NOTIFICATION);
notofManager.notify(id, notification);
}
}
I would really appreciate anykind of help!
P.S.
How can i be sure that an alarm was successfully set on a date. Even if a code works and a date is set a week form now. How can i test that it will trigger then? Obviously we can't wait a week to see that. Changing the device date is working? Thank you
Calendar month goes from 0-11 instead of 1-12 as u assumed.
So something like:
cal.set(Calendar.Month, 7 );
would set your calendar month to August.

AlarmManager responding at wrong time

Sorry if answered before, but i looked everywhere but didn't get the proper solution
I am using AlarmManager to automatically fire a notification at 9am everyday, but when i try to run it on emulator it executes immediately, and every half hour (31-32min to be precise) after that instead of only once at 9am everyday.
Any ideas why? help appreciated.
code is as below:
public class Home extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_bsheet);
notificationAlert(savedInstanceState);
}
private void notificationAlert(Bundle savedInstanceState) {
AlarmManager manager;
PendingIntent pendingIntent;
Intent intent=new Intent(Home.this, Notify.class);
manager=(AlarmManager)getSystemService(ALARM_SERVICE);
pendingIntent=PendingIntent.getService(Home.this,
0, intent, 0);
GregorianCalendar gcal = new GregorianCalendar();
gcal.set(Calendar.HOUR_OF_DAY, 9);
gcal.set(Calendar.MINUTE, 0);
gcal.set(Calendar.SECOND, 0);
gcal.set(Calendar.MILLISECOND, 0);
long initTime = gcal.getTimeInMillis();
manager.setRepeating(AlarmManager.RTC_WAKEUP, initTime,
24*60*60*1000, pendingIntent);
}
}
cheers,
EDIT: my intention is that, once the app is installed, it fires this alarm at 9am. i have put the alarm in the onCreate, so im not sure if the alarm is only being created everytime i start the app and something weird is happening when i hide the app... again insight would be appreciated!
manager.setRepeating(AlarmManager.RTC_WAKEUP, initTime, 24*60*60*1000, pendingIntent);
Alarm manager will fire immidiatly if initTime < System.currentTimeMillis()
from docs:
If the time occurs in the past, the alarm will be triggered immediately, with an alarm count depending on how far in the past the trigger time is relative to the repeat interval.
According to the code you've provided, gcal.getTimeInMillis() will return millisecods corresponding to Today 9.00. So if you'll try to run your code after this time, initTime will be less then current system time which triggers immidiate run of AlarmManager.
To fix this, for example, you can add one day to your calendar before passing its gcal.getTimeInMillis() if it is already in past so it will point to Tomorrow 9.00 to let it run tomorrows morning
Update1
Tried code like this and it worked as expected for me - fired service every 10 seconds:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
initManager();
}
private void initManager() {
AlarmManager manager;
PendingIntent pendingIntent;
Intent intent = new Intent(this, NotifyService.class);
manager=(AlarmManager)getSystemService(ALARM_SERVICE);
pendingIntent=PendingIntent.getService(this, 0, intent, 0);
long initTime = System.currentTimeMillis() + 5000;
manager.setRepeating(AlarmManager.RTC_WAKEUP, initTime,
10*1000, pendingIntent);
}
However you can use another option: there is AlarmManager.set() method
You can fire it like this
long runTime = /* your calendar time + 24 hours in millis*/
manager.set(AlarmManager.RTC_WAKEUP, runTime, pendingIntent);
so it will fire your service at runTime. And then in the service invoke the same method with recalculated runTime for another day so it could look something like that:
public MainActivity extends Activity{
protected onCreate(Bundle bundle){
....
initManager();
}
private initManager(){
...
long runTime = /* time of your first alarm/notification/whatever you develope */
Intent intent = new Intent(this, NotifyService.class);
pendingIntent=PendingIntent.getService(this, 0, intent, 0);
manager.set(AlarmManager.RTC_WAKEUP, runTime, pendingIntent);
}
}
And the service:
public NotifyService extends Service{
...
public int onStartCommand(...){
...
/* do stuff */
Intent intent = new Intent(getApplicationContext(), NotifyService.class);
pendingIntent=PendingIntent.getService(this, 0, intent, 0);
long runTime = /* recalculate it according to the next time of firing this service*/
manager.set(AlarmManager.RTC_WAKEUP, runTime, pendingIntent);
}
}
So your service will register an intent in AlarmManager itself everytime the service fires.
try this :
Calendar currentTime = Calendar.getInstance();
Calendar alarmTime = Calendar.getInstance();
currentTime.set(Calendar.HOUR_OF_DAY, 9;
currentTime.set(Calendar.MINUTE, 0);
currentTime.set(Calendar.SECOND, 0);
currentTime.set(Calendar.MILLISECOND, 0);
if (alarmTime.compareTo(currentTime) <= 0) {
// check for time
alarmTime.add(Calendar.DATE, 1);
}
Intent intent = new Intent(getBaseContext(), Receiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(
getBaseContext(), 1, intent, 0);
AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
am.setRepeating(AlarmManager.RTC_WAKEUP, alarmTime.getTimeInMillis(),
AlarmManager.INTERVAL_DAY, pendingIntent);

Categories

Resources