This is my code. This code worked fine until yesterday. MyAlarmManager is correctly called (i can see the logs), but MyReceiver is not called. Do you know why?
public class MyReceiver extends BroadcastReceiver
{
#Override
public void onReceive(Context context, Intent intent)
{
//It will start the application at a certain time
Intent i = new Intent(context, Calibration.class);
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(i);
Log.e("MyReceiver", "MyReceiver");
}
}
And this is the AlarmManager class
public void onCreate()
{
//Start
Intent myIntent = new Intent(this, MyReceiver.class);
pendingIntent = PendingIntent.getBroadcast(this, 0, myIntent,0);
AlarmManager alarmManager = (AlarmManager)getSystemService(ALARM_SERVICE);
pref = getApplicationContext().getSharedPreferences(
"settings", MODE_PRIVATE);
int h=pref.getInt("hour", -1);
int m=pref.getInt("minute", -1);
Calendar start=null;
Calendar start2=null;
//If the user added a time in the options activity, the application will start at that time
if(h!=-1 && m!=-1)
{
if(pendingIntent != null)
{
alarmManager.cancel(pendingIntent);
}
Log.e("h e m", h+" "+m);
GregorianCalendar now = new GregorianCalendar();
start = new GregorianCalendar();
start.set(Calendar.HOUR_OF_DAY, h);
start.set(Calendar.MINUTE, m);
start.set(Calendar.SECOND, 0);
if(h>=0 && h<12)
start.set(Calendar.AM_PM,Calendar.AM);
if(h>=12 && h<=23)
start.set(Calendar.AM_PM,Calendar.PM);
if(start.after(now))
{
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, start.getTimeInMillis(), AlarmManager.INTERVAL_DAY, pendingIntent);
alarmManager.set(AlarmManager.RTC, start.getTimeInMillis(), pendingIntent);
Log.e("MyAlarmManager", "MyAlarmManager");
}
}
//Start 2
Intent myIntent2 = new Intent(this, MyReceiver.class);
pendingIntent2 = PendingIntent.getBroadcast(this, 2, myIntent2,0);
int h2=pref.getInt("hour2", -1);
int m2=pref.getInt("minute2", -1);
//If the user added a time in the options activity, the application will start at that time
if(h2!=-1 && m2!=-1)
{
if(pendingIntent3 != null)
{
alarmManager.cancel(pendingIntent2);
}
Log.e("h2 e m2", h2+" "+m2);
GregorianCalendar now = new GregorianCalendar();
start2 = new GregorianCalendar();
start2.set(Calendar.HOUR_OF_DAY, h2);
start2.set(Calendar.MINUTE, m2);
start2.set(Calendar.SECOND, 0);
if(h2>=0 && h2<12)
start2.set(Calendar.AM_PM,Calendar.AM);
if(h2>=12 && h2<=23)
start2.set(Calendar.AM_PM,Calendar.PM);
if(start2.after(now))
{
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, start2.getTimeInMillis(), AlarmManager.INTERVAL_DAY, pendingIntent3);
alarmManager.set(AlarmManager.RTC, start2.getTimeInMillis(), pendingIntent3);
Log.e("MyAlarmManager3", "MyAlarmManager3");
}
}
}
Related
I'm trying to make alarms using the times provided in the sqlite database for the reminders. however I can't seem to be getting it right. the code I have so far is: (in my mainactivity oncreate)
for (int i = 0; i < allRems.size(); i++) {
int mHour = 0, mMin = 0;
String mAlarmTime = allRems.get(i).getRemTime();
int mID = allRems.get(i).getRemId();
if (!(mAlarmTime == null)) {
String[] time = mAlarmTime.split(":");
mHour = Integer.parseInt(time[0].trim());
mMin = Integer.parseInt(time[1].trim());
}
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.HOUR_OF_DAY, mHour);
calendar.set(Calendar.MINUTE, mMin);
calendar.set(Calendar.SECOND, 0);
calendar.set(Calendar.MILLISECOND, 0);
AlarmManager alarmMgr = (AlarmManager) getSystemService(ALARM_SERVICE);
Intent alarmIntent = new Intent(getApplicationContext(), AlarmReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(MainActivity.this, mID, alarmIntent, PendingIntent.FLAG_UPDATE_CURRENT);
alarmMgr.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), AlarmManager.INTERVAL_DAY, pendingIntent);
}
}
and my alarm receiver class is
#Override
public void onReceive(Context context, Intent intent) {
Log.e("onReceive", "--------------------------------------------------------");
Toast.makeText(context, "OnReceive alarm test", Toast.LENGTH_LONG).show();
if (intent.getAction().equals("android.intent.action.BOOT_COMPLETED")) {
Log.e("DEVICE: ", "Device Rebooted");
}
}
i want to be able to set reminders for the specific time for the reminders in the database
Before, the alarm manager was working. I don't think I changed anything, but now it isn't starting at all.
Here is the code where I set the alarm manager:
SettingsActivity.java
Intent intent;
static PendingIntent recurringDownload;
intent = new Intent(context, UpdateScoresService.class);
recurringDownload = PendingIntent.getService(context, 0, intent, 0);
Preference.OnPreferenceChangeListener refreshListener = new Preference.OnPreferenceChangeListener() {
#Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
if(newValue.toString().equals("1")){ /* daily */
background_refresh.setSummary("Scores will be refreshed daily.");
AlarmManager manager = (AlarmManager) getActivity().getSystemService(Context.ALARM_SERVICE);
manager.cancel(recurringDownload);
recurringDownload.cancel();
Log.e("DAILY REFRESH", " ");
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
calendar.set(Calendar.HOUR_OF_DAY,10);
calendar.set(Calendar.MINUTE,00);
if(calendar.before(Calendar.getInstance())){
Log.e("AFTER", "10 AM DAILY");
calendar.add(Calendar.DATE, 1);
}
manager.setInexactRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), AlarmManager.INTERVAL_DAY, recurringDownload);
}else if(newValue.toString().equals("2")){ /* weekly */
Log.e("WEEKLY REFRESH", " ");
background_refresh.setSummary("Scores will be refreshed weekly.");
AlarmManager manager = (AlarmManager) getActivity().getSystemService(Context.ALARM_SERVICE);
manager.cancel(recurringDownload);
recurringDownload.cancel();
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
calendar.set(Calendar.HOUR_OF_DAY,10);
calendar.set(Calendar.MINUTE,00);
if(calendar.before(Calendar.getInstance())){
Log.e("AFTER", "10 AM WEEKLY");
calendar.add(Calendar.DATE, 1);
}
manager.setInexactRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), AlarmManager.INTERVAL_DAY * 7, recurringDownload);
}else{ /* manually */
background_refresh.setSummary("Scores will be refreshed manually.");
Log.e("MANUAL REFRESH", " ");
AlarmManager manager = (AlarmManager) getActivity().getSystemService(Context.ALARM_SERVICE);
manager.cancel(recurringDownload);
recurringDownload.cancel();
}
return true;
}
};
The UpdateScoresService is here:
public class UpdateScoresService extends IntentService {
public int countChanged;
Context context = this;
public UpdateScoresService() {
super("UpdateScoresService");
}
#Override
protected void onHandleIntent(Intent intent) {
Log.e("onHandleIntent", "grabbing scores");
countChanged = new GetAnimeScores(getApplicationContext()).refreshScores();
if(countChanged>0){ //Display notification if any scores changed
Log.d("Creating notification", " ");
NotificationCompat.Builder builder = new NotificationCompat.Builder(context);
builder.setSmallIcon(R.drawable.ic_timeline_white_24dp);
builder.setContentTitle("MAL Score Tracker");
builder.setAutoCancel(true);
if(countChanged==1){
builder.setContentText("1 score changed since you were gone!");
}else{
builder.setContentText(countChanged+" scores changed since you were gone!");
}
Intent intent1 = new Intent(context, MainActivity.class);
TaskStackBuilder stackBuilder = TaskStackBuilder.create(context);
stackBuilder.addParentStack(MainActivity.class);
stackBuilder.addNextIntent(intent1);
PendingIntent pendingIntent = stackBuilder.getPendingIntent(0,PendingIntent.FLAG_UPDATE_CURRENT);
builder.setContentIntent(pendingIntent);
NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(0,builder.build());
}
}
}
}
The Log in the SettingsActivity print but the Log in the onHandleIntent from the Service do not print. I'm not sure what is wrong.
It is better to have a BroadcastReceiver which will be responsible for starting the service. The code for it should look something like this:
Create a BroadcastReceiver class:
public class ReceiverToStartService extends BroadcastReceiver{
#Override
public void onReceive(Context context, Intent intent) {
Intent i = new Intent(context, UpdateScoresService.class);
ComponentName service = context.startService(i);
}
}
Register receiver in your Manifest:
<receiver android:name=".ReceiverToStartService"/>
Now change the Intent in your Activity that you are passing to PendingIntent:
intent = new Intent(context, ReceiverToStartService.class);
recurringDownload = PendingIntent.getService(context, 0, intent, 0);
I made an app which has a number picker ranging from 1 to 60 minutes, and I connected it to a repeated alarm manager. When I gave it a try, I noticed that it's not accurate sometimes, it either takes more minutes to work or less.
What could be the problem?
For the start button:
startB.setOnClickListener(new OnClickListener()
{
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
if (startB.isChecked())
{
Calendar calSet = Calendar.getInstance();
calSet.set(Calendar.MINUTE, picker2.getValue());
calSet.set(Calendar.SECOND, 0);
calSet.set(Calendar.MILLISECOND, 0);
setAlarm(calSet);
SharedPreferences.Editor editor = getPreferences(MODE_PRIVATE).edit();
editor.putBoolean("toggleButton", startB.isChecked());
editor.commit();
timerHasStarted = true;
}
else
{
Intent intent = new Intent(getBaseContext(), MainReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(getBaseContext(), RQS_1, intent, 0);
AlarmManager alarmManager = (AlarmManager)getSystemService(Context.ALARM_SERVICE);
alarmManager.cancel(pendingIntent);
SharedPreferences.Editor editor = getPreferences(MODE_PRIVATE).edit();
editor.putBoolean("toggleButton", startB.isChecked());
editor.commit();
timerHasStarted = false;
}
}
});
For the alarm:
private void setAlarm(Calendar targetCal ) {
// TODO Auto-generated method stub
Intent intent = new Intent(getBaseContext(), MainReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(getBaseContext(), RQS_1, intent, 0);
AlarmManager alarmManager = (AlarmManager)getSystemService(Context.ALARM_SERVICE);
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP,
targetCal.getTimeInMillis(),
TimeUnit.MINUTES.toMillis(picker2.getValue()),
pendingIntent);
}
Receiver:
#Override
public void onReceive(Context context, Intent intent) {
MediaPlayer m=MediaPlayer.create(context, R.raw.sound);
m.start();
}
The Android OS is able to shift alarms in order to minimize wakeups and battery consumption (since API 19). Take a look here. I noticed delays up to a few seconds.
A pretty nice tutorial on alarms in general could be found here
I've got a question for you. I want to use a notification service through BroadcastReceiver and AlarmManager. I set the alarm manager with a dynamic list of times from my db.
I use this method that i call on my MainActivity OnCreate(), but doesn't work
private void restartNotify() {
AlarmManager am = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(this, AlarmReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0,
intent, PendingIntent.FLAG_CANCEL_CURRENT);
am.cancel(pendingIntent);
ArrayList<String> item = new ArrayList<String>();
item = GetLists.GetTimesListForNotification(this);
for (int i = 0; i < item.size(); ++i) {
String time = item.get(i);
int Position = time.indexOf(":");
int hour = Integer.parseInt(time.substring(0, Position));
int min = Integer.parseInt(time.substring(Position + 1));
Calendar cal = Calendar.getInstance();
cal.set(Calendar.HOUR_OF_DAY, hour);
cal.set(Calendar.MINUTE, min);
cal.set(Calendar.SECOND, 0);
cal.set(Calendar.MILLISECOND, 0);
am.set(AlarmManager.RTC, cal.getTimeInMillis(),
pendingIntent);
}
this is my broadcast receiver
public class AlarmReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
NotificationManager mManager;
mManager = (NotificationManager) context.getApplicationContext()
.getSystemService(
context.getApplicationContext().NOTIFICATION_SERVICE);
Intent intent1 = new Intent(context.getApplicationContext(),
MainActivity.class);
Notification notification = new Notification(R.drawable.ic_launcher,
"Nuovo messaggio da cura alert", System.currentTimeMillis());
intent1.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP
| Intent.FLAG_ACTIVITY_CLEAR_TOP);
PendingIntent pendingNotificationIntent = PendingIntent.getActivity(
context.getApplicationContext(), 0, intent1,
PendingIntent.FLAG_UPDATE_CURRENT);
notification.flags |= Notification.FLAG_AUTO_CANCEL;
notification.setLatestEventInfo(context.getApplicationContext(),
"Le notifiche funzionano", "it is working",
pendingNotificationIntent);
mManager.notify(0, notification);
}
}
Thank you.
Well this is because your pending intents request code is same though you are running a loop. What you can do is get your pending intent intu your loop and set the request code i. This may work. Though it is late but this may help others
I would like to create a custom notification service in my app.
I wouldn't use the google service (google cloud messaging).
Is there a way to create a daemon that check every X seconds a particular condition on my app db and show a notification?
Thank you,
edit
I call this method in MainActivity's oncreate(). I get the times from my db
private void restartNotify() {
AlarmManager am = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(this, AlarmReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0,
intent, PendingIntent.FLAG_CANCEL_CURRENT);
am.cancel(pendingIntent);
ArrayList<String> item = new ArrayList<String>();
item = GetLists.GetTimesListForNotification(this);
for (int i = 0; i < item.size(); ++i) {
String time = item.get(i);
int Position = time.indexOf(":");
int hour = Integer.parseInt(time.substring(0, Position));
int min = Integer.parseInt(time.substring(Position + 1));
Calendar cal = Calendar.getInstance();
cal.set(Calendar.HOUR_OF_DAY, hour);
cal.set(Calendar.MINUTE, min);
cal.set(Calendar.SECOND, 0);
cal.set(Calendar.MILLISECOND, 0);
am.set(AlarmManager.RTC, cal.getTimeInMillis(),
pendingIntent);
}
And this is my broadcast receiver
public class AlarmReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
NotificationManager mManager;
mManager = (NotificationManager) context.getApplicationContext()
.getSystemService(
context.getApplicationContext().NOTIFICATION_SERVICE);
Intent intent1 = new Intent(context.getApplicationContext(),
MainActivity.class);
Notification notification = new Notification(R.drawable.ic_launcher,
"New message to read", System.currentTimeMillis());
intent1.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP
| Intent.FLAG_ACTIVITY_CLEAR_TOP);
PendingIntent pendingNotificationIntent = PendingIntent.getActivity(
context.getApplicationContext(), 0, intent1,
PendingIntent.FLAG_UPDATE_CURRENT);
notification.flags |= Notification.FLAG_AUTO_CANCEL;
notification.setLatestEventInfo(context.getApplicationContext(),
"notification are work", "it's work",
pendingNotificationIntent);
mManager.notify(0, notification);
}
}
You can use AlarmManager + BroadcastReceiver like so:
private void setRecurringAlarm(Context context) {
Intent downloader = new Intent(this, MyStartServiceReceiver.class);
downloader.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0, downloader, PendingIntent.FLAG_UPDATE_CURRENT);
AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
alarmManager.cancel(pendingIntent);
alarmManager.setInexactRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + 6000, 10000, pendingIntent);
}
BroadcastReceiver class:
public class MyStartServiceReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
//do the stuff...
}
}
And don't forget to register receiver in your manifest:
<receiver android:name=".MyStartServiceReceiver"
android:enabled="true"/>
You have to use Alarm Manager to schedule code for execution every specific period. take a look here:
http://developer.android.com/training/scheduling/alarms.html