I want my app to run a specific task at exactly 9 pm every day. I have read multiple examples of it being implemented in Android apps, and I have tried almost every one of them, but nothing seems to work. To test the code out, I try to show a toast message at a certain time, but no toast message comes up, even minutes later after the set time because I read on some sites that the Alarm time may not be exact. Please help me figure out what the problem with my code is.
MainActivity.java:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
Intent intent = new Intent(this, MyBroadcastReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 101, intent, PendingIntent.FLAG_UPDATE_CURRENT);
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
calendar.set(Calendar.HOUR_OF_DAY, 21);
calendar.set(Calendar.MINUTE, 00);
if (alarmManager != null) {
alarmManager.setExact(AlarmManager.RTC, calendar.getTimeInMillis(), pendingIntent);
}
}
public class MyBroadcastReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(MainActivity.this, "Alarm...", Toast.LENGTH_SHORT).show();
}
}
AndroidManifest.xml:
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="com.android.alarm.permission.SET_ALARM"/>
Any help is highly appreciated. I have been stuck with this issue for hours. Thank you.
Related
I'm trying to set my alarm manager working, just simple schedule, firing toast every minute, but it's not working, what's wrong with the code?
Main Activity :
public void klik(View view) {
startalarm();
}
public void startalarm(){
AlarmManager manager = (AlarmManager)getSystemService(Context.ALARM_SERVICE);
Intent intent;
PendingIntent pendingIntent;
intent = new Intent(this, AlarmToastReciever.class);
pendingIntent = PendingIntent.getBroadcast(this,0,intent,0);
manager.setRepeating(AlarmManager.RTC_WAKEUP, SystemClock.elapsedRealtime()+3000,+60000,pendingIntent);
}
}
AlarmToastReciever class :
public class AlarmToastReciever extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent){
Toast.makeText(context,"GOWNO", Toast.LENGTH_SHORT).show();
}
}
As stated in documentation
As of Android 4.4 (API Level 19), all repeating alarms are inexact. Note that while setInexactRepeating() is an improvement over setRepeating(), it can still overwhelm a server if every instance of an app hits the server around the same time. Therefore, for network requests, add some randomness to your alarms, as discussed above.
You can use "setInexactRepeating()" or set an exact one time alarm then set next alarm in On Receive method
Also make sure you added your receiver to the manifest file, between application tag, like
<receiver android:name=".AlarmToastReciever"
android:enabled="true">
<intent-filter>
</intent-filter>
</receiver>
Use this code to initialize alarm manager.
public void setupAlarm() {
final Calendar calNow = Calendar.getInstance();
final Calendar calSet = (Calendar) calNow.clone();
calSet.set(Calendar.HOUR_OF_DAY, calNow.get(Calendar.HOUR_OF_DAY));
calSet.set(Calendar.MINUTE, calNow.get(Calendar.MINUTE) + 1);
calSet.set(Calendar.SECOND, calNow.get(Calendar.SECOND));
final Intent intent = new Intent(this, UploadStarterReceiver.class);
final PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 1,
intent, 0);
final AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
alarmManager.setInexactRepeating(AlarmManager.RTC_WAKEUP, calSet.getTimeInMillis(),
60 * 1000, pendingIntent);
}
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.
I am using the following code to execute the Alarm at 10:30 AM and then keep executing every 8seconds, but the problem is, this code execute the Alarm manager even when the time is not 10:30.
I have tried everything but the code keep executing the Alarm regardless of what time is set,
public class MainActivity extends Activity {
private PendingIntent pendingIntent;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
/* Retrieve a PendingIntent that will perform a broadcast */
Intent alarmIntent = new Intent(MainActivity.this, AlarmReceiver.class);
pendingIntent = PendingIntent.getBroadcast(MainActivity.this, 0, alarmIntent, 0);
startAt10();
}
public void startAt10() {
AlarmManager manager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
/* Set the alarm to start at 10:30 AM */
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
calendar.set(Calendar.HOUR_OF_DAY, 10);
calendar.set(Calendar.MINUTE, 30);
/* Repeating on every 8 seconds interval */
manager.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(),
1000 * 8, pendingIntent);
}
}
and this is my AlarmReceiver class,
public class AlarmReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
// For our recurring task, we'll just display a message
Toast.makeText(context, "Welcome Back ! ", Toast.LENGTH_SHORT).show();
}
I have also added this in my AndroidManifest.xml,
<receiver android:name="com.example.test2.AlarmReceiver" android:enabled="true" >
</receiver>
How to make it to only execute at 10:30AM ?
Your code is correct. The alarm will start at 10:30 am and repeats at every 8 seconds. But once check the time in the device or emulator in which your app is running. If the time is already past then the alarm starts executing immediately.
If the time is not completed then once uninstall the application and run again it may work.
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);
I am new to Android and I would appreciate any help on this.
I am trying to use Alarm Manager so that it would call my BroadcastReceiver class at a specific time in future set by DatePicker and TimePicker widgets.
However, i cannot get the broadcastreceiver class to perform its function.
below is the code that i put in the manifest file for the broadcastreceiver class to receive the broadcast message from OS:
<receiver android:name="androidapp.scheduler.MyBroadcastReceiver" >
<intent-filter>
<action android:name="android.intent.action.MYBROADCASTRECEIVER" >
</action>
</intent-filter>
</receiver>
And below is the code that i have put in my Next button's onclicklistener so that it would inform OS of the time of the call.
TimePicker myTp = (TimePicker)findViewById(R.id.tpTime);
cal.set(Calendar.YEAR,myDatePicker.getYear() );
cal.set(Calendar.MONTH, myDatePicker.getMonth());
cal.set(Calendar.DAY_OF_MONTH, myDatePicker.getDayOfMonth());
cal.set(Calendar.HOUR, myTp.getCurrentHour());
cal.set(Calendar.MINUTE, myTp.getCurrentMinute());
cal.set(Calendar.SECOND, 0);
Log.i("SCheduling", cal.getTime().toString());
Intent intent = new Intent(Scheduling.this, MyBroadcastReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(Scheduling.this, 234324243, intent, 0);
AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
alarmManager.set(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), pendingIntent);
Intent nextForm = new Intent(this,Sender.class);
nextForm.putExtra("contacts", contacts);
startActivity(nextForm);
Log.i("SCheduling", "everything set");
Finally, MybroadcastReceivers class code is shown below:
public class MyBroadcastReceiver extends BroadcastReceiver{
#Override
public void onReceive(Context context, Intent intent) {
Log.i("brreceiver", "BroadcastReciever");
Toast.makeText(context, "schedule set!.",
Toast.LENGTH_LONG).show();
}
}
What am I missing here?
In the following statement change Scheduling.this to this.getApplicationContext()
PendingIntent pendingIntent = PendingIntent.getBroadcast(Scheduling.this, 234324243, intent, 0);
it seems the code was correct, the problem was with the Emulator. I still don't know what was wrong with the emulator but i tested the code again and it worked and i did receive the log's output.