I'm setting up a daily alarm. It works if the app is running at alarm time, but does not work if the app is not running.
This is how I declare the receiver in the Manifest:
<receiver android:name="com.myAppPackage.alarm.AlarmReceiver"
android:enabled="true"
android:exported="true"/>
Studio warns me: Exported receiver does not require permission.
True I have not added an android:permission nor and Intent to the receiver and the application section doesn't have any permission tags.
And this is the broadcastreceiver:
package com.myAppPackage.alarm;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
public class AlarmReceiver extends BroadcastReceiver {
public AlarmReceiver(){}
#Override
public void onReceive(Context context, Intent intent) {
final Intent syncIntent = new Intent(context, AlarmActivity.class);
syncIntent.addFlags(FLAG_ACTIVITY_NEW_TASK);
context.startActivity(syncIntent);
}
}
The alarm is configured in the following method (in this example configured to set-off daily inexact at 13:48):
public static void configureDailySync(Context context) {
AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
Intent alarmIntent = new Intent(context, AlarmReceiver.class);
PendingIntent alarmPendingIntent = PendingIntent.getBroadcast(context, 0, alarmIntent, 0);
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
final int hourOfDay = 13;
final int minuteOfHour = 48;
calendar.set(Calendar.HOUR_OF_DAY, hourOfDay);
calendar.set(Calendar.MINUTE, minuteOfHour);
alarmManager.setInexactRepeating(
AlarmManager.RTC_WAKEUP,
calendar.getTimeInMillis(),
AlarmManager.INTERVAL_DAY,
alarmPendingIntent);
}
Any help is very welcome! Thank you!!
news: getting closer... if I copy the alarm-setting code in the MainActivity onCreate() method it works! This is the code I copied:
AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
Intent alarmIntent = new Intent(this, AlarmReceiver.class);
PendingIntent alarmPendingIntent = PendingIntent.getBroadcast(this, 0, alarmIntent, 0);
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
final int hourOfDay = 13;
final int minuteOfHour = 48;
calendar.set(Calendar.HOUR_OF_DAY, hourOfDay);
calendar.set(Calendar.MINUTE, minuteOfHour);
alarmManager.setInexactRepeating(
AlarmManager.RTC_WAKEUP,
calendar.getTimeInMillis(),
AlarmManager.INTERVAL_DAY,
alarmPendingIntent);
When the alarm is created as above in the onCreate() of the MainActivity then it DOES trigger even when the app is closed...
But when I call the call the method from the MainActivity like this:
MyAppAccount.configureDailySync(this);
it doesn't work!
MyAppAccount is an plain class not extending anything... I've tried to have MyAppAccount extend AppCompatActivity in case it mattered but nothing...
Oh well... it seems that the above try of executing the alarm-setting in the onCreate() method of the MainActivity is not always working... what is most puzzling!!! :-(
SOLVED: It had nothing to do with coding!! The problem was the way I was closing the application. When closing the application using the stop button of Android Studio the alarm is NOT set. When closing the application from the phone, using the back button for instance and / or removing the application from the list of applications (with the square button), then the alarm works!
Why? No idea...
Related
I am busy with a daily quote app... Alarm Manager is set up to run a method in the MainActivity that populates a listView with a quote from the database each morning at 0900. The method runs and the listView populates just fine but ignores the alarm schedule and the populated data doesn't persist.
If users leaves the main activity then returns, or closes and reopens the app, the method is run again and the list view is populated with a new quote rather than persisting and only running at the scheduled interval.
Any ideas on how to fix this?
Here is my code:
Here I register the alarm dynamically in the MainActivity's onCreate method:
mTodaysQuoteReceiverStaticInnerClass = new
TodaysQuoteReceiverInnerStaticClass();
IntentFilter filter = new
IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION);
filter.addAction(Intent.ACTION_BOOT_COMPLETED);
this.registerReceiver(mTodaysQuoteReceiverStaticInnerClass, filter);
Here is my receiver class (which I made an inner class in the MainActivity):
public class TodaysQuoteReceiverInnerStaticClass extends BroadcastReceiver{
#Override
public void onReceive(final Context context, final Intent intent){
MainActivity.this.PopulateTodaysQuote();
}
}
Here is the method that sets my alarm. I call this method from the onCreateMethod in the MainActivity:
public void todaysQuoteAlarm(){
long currentTime = System.currentTimeMillis();
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.HOUR_OF_DAY, 20);
calendar.set(Calendar.MINUTE, 9);
calendar.set(Calendar.SECOND, 0);
if (currentTime <= calendar.getTimeInMillis()) {
Intent myIntent = new Intent(this,
TodaysQuoteReceiverInnerStaticClass.class);
int ALARM1_ID = 10000;
PendingIntent pendingIntent = PendingIntent.getBroadcast(this,
ALARM1_ID, myIntent, PendingIntent.FLAG_UPDATE_CURRENT);
AlarmManager alarmManager = (AlarmManager)
this.getSystemService(Context.ALARM_SERVICE);
alarmManager.setInexactRepeating(AlarmManager.RTC_WAKEUP,
calendar.getTimeInMillis(), AlarmManager.INTERVAL_DAY, pendingIntent);
}
else{
private void startAlarm() {
AlarmManager alarmMgr;
PendingIntent alarmIntent;
alarmMgr = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(MainActivity.this, AlarmReceiver.class);
alarmIntent = PendingIntent.getBroadcast(MainActivity.this, 0, intent, 0);
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
calendar.set(Calendar.HOUR_OF_DAY, 23);
calendar.set(Calendar.MINUTE, 52);
alarmMgr.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(),
1000 * 60 * 20, alarmIntent);
}
startAlarm() method is in the MainActivity class.
The following code should display a toast (declared in onReceive() method of the AlarmReceiver class) at 23:52 and every 20 minutes thereafter
AlarmReceiver extends BroadcastReceiver.
The code compiles without errors but for some reason it is not displaying the toast.
NOTE : The code worked fine with ELAPSED_REALTIME_WAKEUP. I am having problem with RTC_WAKEUP only. So everything else has to be correct. There is something wrong inside the startAlarm() method only.
I have tried your code with some modification as below .
private void startAlarm() {
AlarmManager alarmMgr;
PendingIntent alarmIntent;
alarmMgr = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(MainActivity.this, AlarmReceiver.class);
alarmIntent = PendingIntent.getBroadcast(MainActivity.this, 0, intent, 0);
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
calendar.set(Calendar.HOUR_OF_DAY, 0);
calendar.set(Calendar.MINUTE, 2);
alarmMgr.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(),
1000 * 20, alarmIntent);
}
This code works fine with AlarmManager.RTC_WAKEUP. If it does not work for you, please reboot your device after installing it. After reboot completed, start your app. Then it should fire the alarm and every 20 sec interval the alarm fires repeatedly.
You can also check the difference between RTC_WAKEUP and ELAPSED_REALTIME_WAKEUP. From android docs, elapsedRealtime means, Returns milliseconds since boot, including time spent in sleep and RTC means, time in System.currentTimeMillis() (wall clock time in UTC).
Looks like You need to set an action to the intent:
Intent intent = new Intent(MainActivity.this, AlarmReceiver.class);
intent.setAction("YourPackageName.YourAction");
alarmIntent = PendingIntent.getBroadcast(MainActivity.this, 0, intent, 0);
And in the manifest:
<receiver android:name=".AlarmReciever">
<intent-filter>
<action android:name="YourPackageName.YourAction" />
</intent-filter>
</receiver>
This should fix the issue. You must have a unique action in the intent for use it with broadcast receiver.
I want use String start = "16:00"; in specific time, start another activity.
I must use String start = "16:00"
MainActivity.class
String start = "16:00";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
setAlarmTime(this);
}
private void setAlarmTime(Context context) {
String[] strStart = start.split(":") // delete ":"
Calendar cal_start = Calendar.getInstance();
cal_start.set(Calendar.HOUR_OF_DAY, Integer.parseInt(strStart[0])); // hour
cal_start.set(Calendar.MINUTE, Integer.parseInt(strStart[1])); //minute
AlarmManager alarm = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(this, AlarmActivity.class);
PendingIntent pIntent = PendingIntent.getActivity(context, 0, intent, 0);
alarm.set(AlarmManager.RTC, cal_start.getTimeInMillis(), pIntent);
}
I want while the app is running, current time 4 o'clock , start AlarmActivity.class .
But it does not work.
How to every specific time start another activity on android?
#update
private void setAlarmTime(Context context) {
String[] strStart = start.split(":");
Calendar cal_start = Calendar.getInstance();
cal_start.set(Calendar.HOUR_OF_DAY, Integer.parseInt(strStart[0]));
cal_start.set(Calendar.MINUTE, Integer.parseInt(strStart[1]));
AlarmManager alarm = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(this, AlarmReceiver.class);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, 0);
alarm.set(AlarmManager.RTC_WAKEUP, cal_start.getTimeInMillis(), pendingIntent);
this source not work.
not work alarmManager.
Please consider to use AlarmManager.RTC_WAKEUP if you need to wake up the device even if it goes off.
alarm.set(AlarmManager.RTC_WAKEUP, cal_start.getTimeInMillis(), pIntent);
AlarmManager.RTC will NOT wake the device up.
Reference: https://developer.android.com/reference/android/app/AlarmManager.html#RTC
Btw, you do not need to pass the context reference to method:
PendingIntent pIntent = PendingIntent.getActivity(this /*can use this as it is a context already */ , 0, intent, 0);
Update:
Please also set the second and millisecond of the cal_start; otherwise it will be the values that you get the calendar instance.
cal_start.set(Calendar.SECOND, 0);
cal_start.set(Calendar.MILLISECOND, 0);
Update 2:
It works in my side, you may try to add
<uses-permission android:name="android.permission.WAKE_LOCK" />
in Manifests.
Btw, if you want this alarm repeat every day
AlarmManager alarm = (AlarmManager) getSystemService(ALARM_SERVICE);
alarm.setRepeating(AlarmManager.RTC_WAKEUP, cal_start.getTimeInMillis(), AlarmManager.INTERVAL_DAY, pIntent);
Add this permission in your manifest
<uses-permission android:name="android.permission.WAKE_LOCK" />
register your receiver class in the application tag in the manifest file
<receiver android:name=".AlarmActivity" />
Resister your alarm that will trigger AlarmActivity at a specific time in your case its 16:00
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.HOUR_OF_DAY, 16);
calendar.set(Calendar.MINUTE, 0);
calendar.set(Calendar.SECOND, 0);
Intent intent = new Intent(getApplicationContext(), AlarmActivity.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(getApplicationContext(), 100, intent, PendingIntent.FLAG_UPDATE_CURRENT);
AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), AlarmManager.INTERVAL_DAY, pendingIntent);
Make sure your register class extend BroadcastReceiver like this
class AlarmActivity extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
// Do whatever you want
// you can generate notifications here
// or can start your application activity you want
}
}
No matter how I try, I cannot get the alarmManager and receiver to work - there seem to be SO many different ways to do it from what i've searched, but nothing seems to work.
I have in Manifest:
<receiver android:name="AlarmReceiver" />
I am using inner class for broadcastReceiver:
private class AlarmReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Log.d("ALARM","TRIGGERED");
Notification(filteredList.get(0).getTitle());
}
}
I call function SetAlarm to start the manager:
private void SetAlarm(long time) {
AlarmManager alarm_mgr = (AlarmManager)(this.getSystemService( Context.ALARM_SERVICE ));
Intent intent = new Intent(MainActivity.this, AlarmReceiver.class);
//PendingIntent pi = PendingIntent.getService(MainActivity.this, 0, intent, 0);
PendingIntent pi = PendingIntent.getBroadcast(this, 111, intent, PendingIntent.FLAG_UPDATE_CURRENT);
Calendar calendar = Calendar.getInstance();
alarm_mgr.set(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), pi);
Log.d("ALARMSET", "Alarm " + calendar.getTime().toString());
}
As you can see, in the receiver I have a notification call - I won't post because I know this works, but there is also a log that is not working.
For testing purposes I've set time to current time using the Calendar function.
You can see the pendingIntent, i have tried both getService and getBroadcast, I can't figure out which I need, but neither works anyway.
I'm sure I'm missing something, i don't know what, and I can't seem to find any answers at Google.
Is the AlarmReceiver ok as an inner class ? I have put it there because I need access to my "filteredList" List object.
thx
I am using inner class for broadcastReceiver:
This will not work. Android has to be able to create an instance of your BroadcastReceiver, and it cannot do so. At best, your BroadcastReceiver could be a static nested class, but then you would have to fix your manifest entry to refer to the outer class:
<receiver android:name="OuterClass$AlarmReceiver" />
No, actually the BroadcastReceiver needs to be public.Only then you can register it in manifest and access them. Place the AlarmReceiver code in a separate .java file. You will see the log inside the BroadcastReceiver.
try this
private AlarmManager alarmMgr;
private PendingIntent alarmIntent;
...
alarmMgr = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(context, AlarmReceiver.class);
alarmIntent = PendingIntent.getBroadcast(context, 0, intent, 0);
// Set the alarm to start at 8:30 a.m.
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
calendar.set(Calendar.HOUR_OF_DAY, 8);
calendar.set(Calendar.MINUTE, 30);
// setRepeating() lets you specify a precise custom interval--in this case,
// 20 minutes.
alarmMgr.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(),
1000 * 60 * 20, alarmIntent);
For more details.. Look this
I stucked 1 day for this problem, and finally solved this.
AlarmManager is used to generate a broadcast every 30 seconds, and a broadcast receiver is used to receive the message and execute ...
So the main problem is the following 2 steps
1. In the AndroidManifist.xml a action filter needed.
<receiver android:name="com.istep.gps.straight.MyTimerReceiver">
<intent-filter>
<action android:name="com.istep.gps.straight.MyTimerReceiver.Action"/>
</intent-filter>
</receiver>
2. The most important is the Intent need to be empty, no AAA.class
private void initTimer(Context context) {
Intent intent = new Intent().setAction("com.istep.gps.straight.MyTimerReceiver.Action")
.putExtra("id",UniqueID.getID(context));
PendingIntent sender = PendingIntent.getBroadcast(context, 18, intent, 0);
AlarmManager am = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
am.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime(), 1000 * 30, sender);
}
When you use calendar, you should setTimeInMillis
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
I am implement a simple alarm function, which is used to trigger some function at the specific date time.
The problem is I have set the time already, but the receiver seems never called.
Here is how I implement:......
1) in manifest :
<uses-permission android:name="com.android.alarm.permission.SET_ALARM" />
and
<receiver android:name=".Listener.AlarmReceiver" />
2) in the main activity (I would like to trigger on 4th June 2014, 02:06 p.m.)
profilePic.setOnClickListener(new OnClickListener(){
#Override
public void onClick(View v) {
GregorianCalendar date = new GregorianCalendar(2014,6,4,14,6);
long dateTime = date.getTimeInMillis();
Log.d("test1",date.toString());
AlarmManager alarmManager = (AlarmManager) ctx.getSystemService(Context.ALARM_SERVICE);
Intent intentAlarm = new Intent(ctx, AlarmReceiver.class);
alarmManager.set(AlarmManager.RTC_WAKEUP, dateTime, PendingIntent.getBroadcast(ctx, 1, intentAlarm, PendingIntent.FLAG_UPDATE_CURRENT));
}
});
And I have also log the time
java.util.GregorianCalendar[time=1404453960000,areFieldsSet=true,lenient=true,zone=Asia/Hong_Kong,firstDayOfWeek=1,minimalDaysInFirstWeek=1,ERA=1,YEAR=2014,MONTH=6,WEEK_OF_YEAR=27,WEEK_OF_MONTH=1,DAY_OF_MONTH=4,DAY_OF_YEAR=185,DAY_OF_WEEK=6,DAY_OF_WEEK_IN_MONTH=1,AM_PM=1,HOUR=2,HOUR_OF_DAY=14,MINUTE=6,SECOND=0,MILLISECOND=0,ZONE_OFFSET=28800000,DST_OFFSET=0]
3) Receiver
public class AlarmReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Log.d("test1", "alarm");
Toast.makeText(context, "Alarm Triggered", Toast.LENGTH_LONG).show();
}
}
I waited until the 02:06p.m. but nothing happened, and receiver is not called. How to fix the problem? Also, is it possible to set more than one alarm, is it all I need to do is to create another datetime and fire the alarmManager.set() again, will it overwrite the old timer? Thanks for helping.
Updated
For the AlarmReceiver in the mainifest ,
I changed to
<receiver android:name="com.example.antismoke.Listener.AlarmReceiver" />
And the class is
package com.example.antismoke.Listener;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.util.Log;
import android.widget.Toast;
public class AlarmReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Log.d("test1", "alarm");
Toast.makeText(context, "Alarm Triggered", Toast.LENGTH_LONG).show();
}
}
so I think package name is not the root cause? Thanks for helping
Instead of using GregorianCalendar , try to use Calendar.
Try the following, it should work:
Intent i = new Intent(getApplicationContext(), AlarmReceiver.class);
PendingIntent sender = PendingIntent.getBroadcast(AlarmSample.this, 0, i, 0);
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.HOUR_OF_DAY, hour); // set hour
calendar.set(Calendar.MINUTE, minuite); // set minute
calendar.set(Calendar.SECOND, 0); // set seconds
AlarmManager am = (AlarmManager)getSystemService(ALARM_SERVICE);
am.set(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), sender);
you should use package name correctly, if you have different package ,
receiver android:name="XXX.XXXXXXXXXXXXXXX.AlarmReceiver" />
check this out
1) You don't need this persmission (com.android.alarm.permission.SET_ALARM) to receive alarm.
2) Change this line:
<receiver android:name=".Listener.AlarmReceiver" />
to
<receiver android:name=".AlarmReceiver" />
replace alarmManager.set with alarmManager.setRepeating
or try to use this:
public static AlarmManager am = null;
public static PendingIntent sender;
Intent intent1 = new Intent(ctx, Reciver.class);
sender = PendingIntent.getBroadcast(ctx, 1, intent1, 0);
am = (AlarmManager) getSystemService(ALARM_SERVICE);
long l = new Date().getTime();
am.setRepeating(AlarmManager.RTC_WAKEUP, l, 1500, sender);
Ok , finally I figure out it is because the month start at 0 in GregorianCalendar. So June should use 5 instead of 6
I should have noticed the problem. Thanks for all you guys