First of all , i'd read many many answers about this problem ,
I want to set 5 alarms working but with different times , the problem is the last one overrides the others so i see the last one only ,
i tried to change the request code of the PendingIntent to make it unique but the problems still as it is :
i'd rewritten the code many times really but the same result,
i tried to make one method for all the alarms and changing the request code in but no use , also i tried to make different methods for every alarm with unique request codes but still the last alarm overrides the others,
here is my code for two methods as an example :
Note :
variables that i have
fajrMillis,dhuhrMillis : are the milliseconds which are converted to a calendar to set the time in
fajrMessage,dhuhrMessage : the string messages to be sent to the receiver class to the notification in it
Calling the two methods :
setFajrAlarm(fajrMillis, 1, fajrMessage);
setDhuhrAlarm(dhuhrMillis, 2, dhuhrMessage);
public void setFajrAlarm(long millis, int id, String message) {
Calendar c = Calendar.getInstance();
c.setTimeInMillis(millis);
PrayersReceiver.notificationId = id;// 1
PrayersReceiver.notificationMessage = message;// "حان الآن موعد صلاة الفجر"
Intent intent = new Intent(getBaseContext(), PrayersReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(getBaseContext(), 1, intent, PendingIntent.FLAG_UPDATE_CURRENT | Intent.FILL_IN_DATA);
AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP,
c.getTimeInMillis(),30000, pendingIntent);
}
public void setDhuhrAlarm(long millis, int id, String message) {
Calendar c = Calendar.getInstance();
c.setTimeInMillis(millis);
PrayersReceiver.notificationId = id;// 1
PrayersReceiver.notificationMessage = message;// "حان الآن موعد صلاة الظهر
Intent intent = new Intent(getBaseContext(), PrayersReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(getBaseContext(), 2, intent, PendingIntent.FLAG_UPDATE_CURRENT | Intent.FILL_IN_DATA);
AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP,
c.getTimeInMillis(), 5000, pendingIntent);
}
//---------------------------------------------------------------------------------
The Receiver Class
package com.prayers;
import android.app.NotificationManager;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.support.v4.app.NotificationCompat;
import android.widget.Toast;
public class PrayersReceiver extends BroadcastReceiver {
public static String notificationMessage = "";
public static int notificationId ;
#Override
public void onReceive(Context context, Intent intent) {
// TODO Auto-generated method stub
Toast.makeText(context, "Time For Prayer", 3000).show();
// -----------------
// --------------Notification Part---------------------------
NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(
context).setSmallIcon(R.drawable.ic_launcher)
.setContentTitle("حان الآن موعد الصلاة")
.setContentText(notificationMessage);
NotificationManager mNotificationManager = (NotificationManager) context
.getSystemService(Context.NOTIFICATION_SERVICE);
mNotificationManager.notify(notificationId, mBuilder.build());
}
}
Thanks in advance , hope to get the answers soon
I knew the answer so if anyone faces this problem to get the solution :
i was setting the variables values in the receiver class so the last method call overrides the previous calls :
PrayersReceiver.notificationId = id;
PrayersReceiver.notificationMessage = message;
the problem was in these two lines in the method body :
so it got solved by :
Intent intent = new Intent(getBaseContext(), PrayersReceiver.class);
intent.putExtra("notificationId", id);
intent.putExtra("notificationMessage", message);
and in the receiver class get the two values :
Bundle bundle = intent.getExtras();
if (bundle == null) {
Log.i("PrayersReceiver", "bundle is null");
return;
}
notificationId = bundle.getInt("notificationId");
notificationMessage = bundle.getString("notificationMessage");
Related
I am creating an android app in which user can add multiple babies, each baby have multiple dates on which alarm being called.
I am getting dates from SQLite Database After fetching dates, the alarm will be setting to those dates. I have set everything correctly, but alarm not working properly.
Here is the code .
List babyDataList = new ArrayList<>();
List listItems = new ArrayList<>();
Database db = new Database();
babyDataList = db.getAllBabies();
calendar = Calendar.getInstance();
calenderThird = Calendar.getInstance();
for(BabyModal b : babyDataList ){
String name = b.getBabyName();
String first = b.getFirstVac(); // FirstDate
String sec = b.getSecVac(); //SecondDate
String[] val1 = first.split("-");
int dateSec = Integer.parseInt(val1[0]);
int monthSec = Integer.parseInt(val1[1]);
int yearSec = Integer.parseInt(val1[2]);
calendar.set(
yearSec, monthSec-1, dateSec, 8, 30, 30
);
setAlarm(calendar);
String[] val2 = sec.split("-");
int dateThird = Integer.parseInt(val2[0]);
int monthThird = Integer.parseInt(val2[1]);
int yearThird = Integer.parseInt(val2[2]);
calenderThird.set(
yearThird, monthThird-1, dateThird, 8, 30, 30
);
setAlarm(calendarThird);
listItems.add(b);
}
The Method for setAlarm is
private void setAlarm(Calendar cal){
Intent intent = new Intent(this, AlarmReceiver.class);
PendingIntent pendingIntent = PendingIntent.getActivity(this,
(int) cal.getTimeInMillis(), intent, PendingIntent.FLAG_CANCEL_CURRENT);
AlarmManager am =
(AlarmManager)getSystemService(Activity.ALARM_SERVICE);
am.set(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(),
pendingIntent);
}
AlarmReceiver class :
public class AlarmReceiver extends BroadcastReceiver{
#Override
public void onReceive(Context context, Intent intent) {
Intent intent1 = new Intent(context, MyNewIntentService.class);
context.startService(intent1);
}
}
MyNewIntentService class:
public class MyNewIntentService extends IntentService {
private static final int NOTIFICATION_ID = 3;
public MyNewIntentService(String name) {
super(name);
}
#Override
protected void onHandleIntent(#Nullable Intent intent) {
Notification.Builder builder = new Notification.Builder(this);
builder.setContentTitle("Vaccination Time");
builder.setContentText(" ");
builder.setSmallIcon(R.drawable.health);
builder.setVibrate(new long[] { 1000, 1000, 1000, 1000, 1000 });
builder.setLights(Color.RED, 3000, 3000);
Uri alarmSound = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
builder.setSound(alarmSound);
PowerManager pm = (PowerManager)this.getSystemService(Context.POWER_SERVICE);
boolean isScreenOn = pm.isScreenOn();
if(isScreenOn==false){
PowerManager.WakeLock wl = pm.newWakeLock(PowerManager.FULL_WAKE_LOCK |PowerManager.ACQUIRE_CAUSES_WAKEUP |PowerManager.ON_AFTER_RELEASE,"MyLock");
wl.acquire(10000);
PowerManager.WakeLock wl_cpu = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,"MyCpuLock");
wl_cpu.acquire(10000);
}
Intent notifyIntent = new Intent(this, BabiesList.class);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 2, notifyIntent, PendingIntent.FLAG_UPDATE_CURRENT);
//to be able to launch your activity from the notification
builder.setContentIntent(pendingIntent);
Notification notificationCompat = builder.build();
NotificationManagerCompat managerCompat = NotificationManagerCompat.from(this);
managerCompat.notify(NOTIFICATION_ID, notificationCompat);
}
}
Thanks in advance.
I am not gonna solve your problem whatever you have posted and wants to resolve; rather i would try to clear basics...
What is alarm manager
It is not the one which system uses for traditional alarms for waking up the persons from sleep, rather it is the same concept... but for the developers; who wants to wake up their piece of code at the specified time...
How to wake up my code then...
Note below code is working across 4.0 to the latest android P; tested on all
Calendar CalendarEvent = Calendar.getInstance(TimeZone.getDefault(), Locale.getDefault());
CalendarEvent.set(Calendar.HOUR_OF_DAY, 14);
CalendarEvent.set(Calendar.MINUTE, 00);
CalendarEvent.set(Calendar.SECOND, 00);
Log.d("SCHEDULER : ", "CALENDAR SET TIME :"+CalendarEvent.getTime()+"\n");
Intent myintent = new Intent(this, MyService.class);
PendingIntent pi = PendingIntent.getService(this, 0, myintent, 0);
AlarmManager alarm_manager = (AlarmManager)getSystemService(Context.ALARM_SERVICE);
alarm_manager.set(AlarmManager.RTC, CalendarEvent.getTimeInMillis(), pi);
What is this...??
Here HOUR_OF_DAY is set to 14 meaning 2PM in the afternoon as per your default timezone. On 2PM, it will start MyService and note it is not necessary that your application must remain in foreground or background or in recents...!! IT WILL GET CALLED...
What the permissions are needed
only <uses-permission android:name="android.permission.WAKE_LOCK" /> if you wants... Note that <uses-permission android:name="com.android.alarm.permission.SET_ALARM" /> is not necessary as it is intended for traditional alarms
What are the deadlines...?
Until next-boot these alarms are remembered by the android systems..!! On the next boot all the alarms are deleted by android system... It means if you set the alarm on 20 jan 2018 and if device is rebooted on the day before or even the timeinmillis before... android will forget it
How to remember it across every boot...?
Use a BOOT_COMPLETED intent for receiver with <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" /> permission and re-set all the alarms manually... again... with the help of database table
It is not the answer of my question which i asked....
Yes, it is. Implement this concept first in a sample new project. clear the concept with such a code which runs across the android platforms in the all cases you wants... And then implement it in the way you wants ... in the main projects.
Huuushhhh...
In my android app I'm willing to show multiple notifications on a particular day,for this I'm using Alarm Manager and Broadcast Receiver problem is when I used alarm it worked fine but when I add notification builder to show the notification its not working
Here is my mainActivity
public static final String ACTION_ONE = "Hello, Test Message 1";
public static final String ACTION_TWO = "Hello, Test Message 2";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
AlarmManager alarmManager1 = (AlarmManager) getSystemService(ALARM_SERVICE);
Calendar cal = Calendar.getInstance();
cal.setTimeInMillis(System.currentTimeMillis());
Intent myIntent1 = new Intent(this, AlarmBroadCustReciver.class);
myIntent1.setAction(ACTION_ONE);
PendingIntent pendingIntent1 = PendingIntent.getBroadcast(this, 1253, myIntent1,
PendingIntent.FLAG_UPDATE_CURRENT);
// Set the time for first alarm here
cal.set(2015, 10, 20, 15, 55);
alarmManager1.set(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), pendingIntent1);
Intent myIntent2 = new Intent(this, AlarmBroadCustReciver.class);
myIntent2.setAction(ACTION_TWO);
PendingIntent pendingIntent2 = PendingIntent.getBroadcast(this, 1263, myIntent2,
PendingIntent.FLAG_UPDATE_CURRENT);
// Set the time for second alarm here
cal.set(2015, 10, 20, 15, 56);
alarmManager1.set(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), pendingIntent2);
// In this way set time for all the rest of the alarms
Here is BroadCastReceiver
public class AlarmBroadCustReciver extends BroadcastReceiver {
public static final String ACTION_ONE = "Hello, welcome to the Server1";
public static final String ACTION_TWO = "Hello, welcome to the Server2";
#Override
public void onReceive(Context context, Intent intent) {
NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
NotificationCompat.Builder builder = new NotificationCompat.Builder(context);
builder.setLargeIcon(BitmapFactory.decodeResource(context.getResources(), R.mipmap.ic_launcher));
builder.setContentTitle(context.getString(R.string.app_name));
if (intent.getAction().equalsIgnoreCase(ACTION_ONE)) {
builder.setContentText("Alarm one");
} else {
builder.setContentText("Alarm two");
}
Notification notification = builder.build();
int notificationID = 0;
notificationManager.notify(notificationID, notification);
You need to pass different notification id for each Notification . If you pass same id (i.e., 0 in your case), the existed notification will be updated with the new data.
change the notification id: eg have a variable and increment it. notificationid++
I had a similar issue, I was creating multiple notifications with different IDs, however, when I clicked on one, only the first one opened the specific scree, all the sequential notifications were ignore (clicking on them didn't do anything, they were just dismissed). Then I tried to do this:
intent.setAction(context.getPackageName() + "." + notificationId);
Which means that each unique notification also carries its own unique Intent and in this case the Intents weren't ignored and each of them opened the needed screen. I must note that my Intents were the same (e.g. NoteDetails.class), so I guess I had to separate them somehow...i'm glad it worked anyways.
Box's answer was a nudge in the right direction for me.
I just had to change the requestCode in the PendingIntent I was passing to the AlarmManager, so it wasn't the same value.
Old code:
PendingIntent pI = PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
New code:
PendingIntent pI = PendingIntent.getBroadcast(context, notificationId, intent, PendingIntent.FLAG_UPDATE_CURRENT);
What the application should do, is get a String from the editReminder EditText and send it to the AlarmManager using an intent. That works, the first time.
But when you close the app and try it again, the notification does not use the string you just typed into the EditText but it uses the text you typed in the first time you ran the app.
How do we make the newly inserted text appear in the notification instead of the old text?
MainActivity: the method executed on buttonclick
public void setAlarm(View v) {
//get user input
EditText editText = (EditText) findViewById(R.id.editReminder);
String reminder = editText.getText().toString();
String snoozeString = getString(R.string.snooze_result);
//the AlarmManager
AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
//get date and time
Calendar c = Calendar.getInstance();
//sets time for alarm
c.set(Calendar.YEAR, year);
c.set(Calendar.MONTH, month);
c.set(Calendar.DAY_OF_MONTH, day);
c.set(Calendar.HOUR_OF_DAY, hour);
c.set(Calendar.MINUTE, minute);
c.set(Calendar.SECOND, 0);
//pIntent to launch activity when alarm triggers
Intent intent = new Intent("com.garden.DisplayNotification"); //(1)From here to DisplayNotification ...
//DisplayNotification is the activity that is intended to be evoked
//sometimes you have to use (this,DisplayNotification.class)?
//when the alarm is triggered
//assign an ID of 1, and add the text
intent.putExtra("NotifID", 1);
intent.putExtra("notification", reminder); //("STRING_I_NEED",strname)
intent.putExtra("notifyAction", snoozeString); //string for the action button
//set the flags so the mainactivity isn't started when the notification is triggered
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
PendingIntent displayIntent = PendingIntent.getActivity(
getBaseContext(), 0,
intent, 0); //this intent instead of new Intent("com.garden.Reminder")
//sets alarm
alarmManager.set(AlarmManager.RTC_WAKEUP,
c.getTimeInMillis(), displayIntent);
showConfirmDialog(v);
}
DisplayNotification: executed when the alarm for the notification triggers
package com.garden.gardenapp;
import android.app.Activity;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Intent;
import android.os.Bundle;
public class DisplayNotification extends Activity {
/**
* This activity is to display a notification only. It is called when
* the system alarm goes off.
*/
//called when activity is first created
//don't forget to update the manifest!!
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//get notification ID passed by MainActivity
int notifID = getIntent().getExtras().getInt("NotifID");
//----Oh of course, have to pass on the strings again.....-----
//initialize strings (reminder is also used for notification text
String reminderText = getIntent().getStringExtra("notification");
String snoozeString = getIntent().getStringExtra("notifyAction");
//pIntent to launch activity if user selects notification
/** making a new Intent has to be done with (this, Reminder.class) instead
* of ("com.garden.Reminder")... why? (otherwise the reminder text is not shown)
*/
Intent reminderIntent = new Intent(this, Reminder.class); //(2)... and from here to Reminder ...
reminderIntent.putExtra("NotifID", notifID);
//pass on strings again in the intent
reminderIntent.putExtra("notification", reminderText);
//intent.putExtra("notifyAction",snoozeString); //---> in different intent
PendingIntent reminderPIntent = PendingIntent
.getActivity(this, 0, reminderIntent, 0);
Intent actionIntent = new Intent(this, Reminder.class);
actionIntent.putExtra("notifyAction", snoozeString); //("STRING_I_NEED", strName)
//don't forget to pass the notifID also to the second intent
actionIntent.putExtra("NotifID",notifID);
PendingIntent actionPIntent = PendingIntent.getActivity(this,
(int) System.currentTimeMillis(), actionIntent, 0);
//create notification
Notification notif = new Notification.Builder(this) //build the notification
.setContentTitle(getString(R.string.app_name)) //required
.setContentText(reminderText) //required
.setSmallIcon(R.drawable.garden) //required
.setContentIntent(reminderPIntent)
//associate pendingIntent with a gesture of NotificationCompat.Builder: click
.addAction(R.drawable.pixel, "Snooze me", actionPIntent)
//should be addAction(NotificationCompat.Action action)
.setAutoCancel(true) //to be dismissed in the Reminder activity
.setPriority(Notification.PRIORITY_MAX) //to show the action buttons by default
// .setVibrate(new long[] {200, 600, 200, 600})
.build();
NotificationManager nm = (NotificationManager)
getSystemService(NOTIFICATION_SERVICE);
nm.notify(notifID, notif); //(int id, Notification notification);
finish(); //because this doesn't have a GUI we don't need it anymore
}
}
(In the DisplayNotification class we split the strings into two intents, so when you click the snooze (notification action) button it fires a different intent than when you click on the notification)
We think it has to do with the AlarmManager not updating the String that comes with the intent or something. Because when we make a notification without the AlarmManager the app works perfectly fine.
Please let me know if you need additional code.
We found it! You don't need to cancel the alarm manager, but you need to give the intent a flag FLAG_UPDATE_CURRENT to let the alarm manager update the intent with the new string you put in the intent.
So in this case, the PendingIntent displayIntent becomes
PendingIntent displayIntent = PendingIntent.getActivity(
getBaseContext(), 0,
intent, PendingIntent.FLAG_UPDATE_CURRENT);
And that solved the problem of updating the string.
I have done some research and tried to implement a one time alarm that sends a notification to the user, but for some reason I cannot understand, when the time comes, the alarm is not being activated. I think the onReceive method is not being called, but I don't know why, since it's the first time I try to implement an alarm.
=== Edit: it seems that the alarm's onReceive is working after all, I got the toast message "Alarm!!" at the right time (don't know why it didn't the first time I tested), but no notification was received, though... Any clues?
This is the code for the Alarm class:
public class Alarm extends BroadcastReceiver {
public static final String PREFS_FILE_NAME = MainActivity.PREFS_FILE_NAME;
#Override
public void onReceive(Context context, Intent intent) {
// TODO Auto-generated method stub
// send notification
Toast.makeText(context, "Alarm!!", Toast.LENGTH_SHORT).show();
// API < 16 so have to use compat
NotificationCompat.Builder mBuilder =
new NotificationCompat.Builder(context)
.setContentTitle(context.getResources().getString(R.string.memo_test_ready))
.setContentText(context.getResources().getString(R.string.click_to_start));
Intent resultIntent = new Intent(context, UpcomingTest.class);
TaskStackBuilder stackBuilder = TaskStackBuilder.create(context);
stackBuilder.addParentStack(UpcomingTest.class);
stackBuilder.addNextIntent(resultIntent);
PendingIntent resultPendingIntent =
stackBuilder.getPendingIntent(
0,
PendingIntent.FLAG_UPDATE_CURRENT
);
mBuilder.setContentIntent(resultPendingIntent);
NotificationManager mNotificationManager =
(NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
mNotificationManager.notify(123, mBuilder.build());
}
public void Set(Context context)
{
DatabaseHandler db = new DatabaseHandler(context);
MemoryTestLevel memoTestLevel = new MemoryTestLevel();
long timeInterval;
long memoryTest_dateTime;
String alarmMemoLevel;
List<Phrase> studyPhrasesList = db.getPhrasesWithState(Phrase.START_STUDYING);
if (studyPhrasesList.size() > 0 ){ // if there are any phrases here, update them; dateTime == level 1
alarmMemoLevel = "Level 1 ";
memoTestLevel = db.getMemoryTestLevelWithLevel(MemoryTestLevel.LEVEL_1);
timeInterval = memoTestLevel.getTimeInterval();
TestDateTimeCalculator datetimeCalc = new TestDateTimeCalculator();
memoryTest_dateTime = datetimeCalc.calculate(timeInterval);
for(Phrase phrase : studyPhrasesList){
phrase.setMemoryTestPending(memoTestLevel.getMemoryTest_id(), memoryTest_dateTime);
db.updatePhrase(phrase);
}
} else {
// if there are no phrases to be set at level 1, then get the lowest memoTest_datime of
// the ones that are pending
alarmMemoLevel = "next after L1 ";
memoryTest_dateTime = db.getLowestMemoTestDateTime();
}
/* 2. Set new Alarm
* 2.1. Determine which phrases will go into this new alarm */
List<Phrase> nextMemoryTestPhrases = db.getNextMemoryTestPhrases(memoryTest_dateTime);
for(Phrase phrase : nextMemoryTestPhrases) {
phrase.setState(Phrase.MEMORY_TEST_SCHEDULED);
db.updatePhrase(phrase);
}
// 2.3 set alarm for required dateTime
AlarmManager alarmMgr = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(context, Alarm.class);
PendingIntent pendingInt = PendingIntent.getBroadcast(context, 0, intent, 0);
alarmMgr.set(AlarmManager.RTC_WAKEUP, memoryTest_dateTime, pendingInt);
// 2.4 save the alarm.dateTime in the preferences so it can be used in the "upcoming test" activity
SharedPreferences preferences = context.getSharedPreferences(PREFS_FILE_NAME, Context.MODE_PRIVATE);
Editor editor = preferences.edit();
editor.putLong("NEXT_TEST_DATETIME", memoryTest_dateTime);
SimpleDateFormat sdf = new SimpleDateFormat("EEE, MMM d, yyyy hh:mm");
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(memoryTest_dateTime);
String nextTestDateStr = sdf.format(calendar.getTime());
Toast.makeText(context, "Alarm set to " + alarmMemoLevel + nextTestDateStr, Toast.LENGTH_LONG).show();
editor.commit();
}
public void Cancel(Context context)
{
Intent intent = new Intent(context, MyBroadcastReceiver.class);
PendingIntent sender = PendingIntent.getBroadcast(context, 0, intent, 0);
AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
alarmManager.cancel(sender);
}
}
And I have a broadcast receiver in case the phone is rebooted:
public class MyBroadcastReceiver extends BroadcastReceiver {
public static final String PREFS_FILE_NAME = MainActivity.PREFS_FILE_NAME;
#Override
public void onReceive(Context context, Intent intent) {
// TODO setup alarm again (get datetime from system)
Alarm alarm = new Alarm();
if (intent.getAction().equals("android.intent.action.BOOT_COMPLETED"))
{
SharedPreferences preferences = context.getSharedPreferences(PREFS_FILE_NAME, Context.MODE_PRIVATE);
long nextTestDateInMillis = preferences.getLong("NEXT_TEST_DATETIME", 0);
if(nextTestDateInMillis > 0){
alarm.Set(context);
}
}
}
}
From the research I found, it seems that something is missing/wrong in my manifest. This is what I have there:
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"></uses-permission>
The below is inside application:
<receiver android:name="liliana.phrasememo.util.MyBroadcastReceiver">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
<receiver android:process=":remote" android:name="liliana.phrasememo.util.Alarm"/>
Also, if you see anything else that's wrong in my implementation of Alarm + Notification it would be brilliant to give me the heads up. Thank you very much :-)
to set alarm may be this code helps you
Intent myIntent = new Intent(yourcontext, Alarm.class);
PendingIntent pendingIntent = PendingIntent.getService(act, 0, myIntent, 0);
AlarmManager alarmManager = (AlarmManager)act.getSystemService(act.ALARM_SERVICE);
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.HOUR_OF_DAY, 8);
calendar.set(Calendar.MINUTE,22);
calendar.set(Calendar.SECOND, 0);
alarmManager.set(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), pendingIntent);
also you must implement service instead of broadcastreciever to run at alarm time
Thanks very much to answer posted here, what is missing in my code is the notification icon, which I have added like this:
NotificationCompat.Builder mBuilder =
new NotificationCompat.Builder(context)
.setSmallIcon(R.drawable.ic_launcher) // this was missing
.setContentTitle(context.getResources().getString(R.string.memo_test_ready))
.setContentText(context.getResources().getString(R.string.click_to_start));
And in fact, if we look at the documentation, it does specify that the small icon must be in the notification:
Required notification contents
A Notification object must contain the following:
A small icon, set by setSmallIcon()
A title, set by setContentTitle()
Detail text, set by setContentText()
The LogCat does have a file not found error:
05-05 12:39:39.191: A/NetworkStats(89): Caused by: java.io.FileNotFoundException: /proc/net/xt_qtaguid/stats: open failed: ENOENT (No such file or directory)
But it doesn't cause any crashes so you might not realise it. I'm not sure anything could be added to the notification constructor itself that would allow the user to see right away that something is missing. I don't have very advanced Java knowledge.
So far and thanks to this website, I've been able to set up an alarm that will be set up and active, even if I turn of my phone.
Now, I set up a alarm to show a reminder for event A and I need the application to setup another alarm to show another reminder for event B.
I must be doing something wrong, because it only fires the reminder for event A. It seems that once set up, any other alarm is understood as the same one. :-(
Here is the detail of what I am doing in two steps:
1) From an activity I set an alarm that at certain time and date will call a receiver
Intent intent = new Intent(Activity_Reminder.this,
AlarmReceiver_SetOnService.class);
intent.putExtra("item_name", prescription
.getItemName());
intent
.putExtra(
"message",
Activity_Reminder.this
.getString(R.string.notif_text));
intent.putExtra("item_id", itemId);
intent.putExtra("activityToTrigg",
"com.companyName.appName.main.Activity_Reminder");
PendingIntent mAlarmSender;
mAlarmSender = PendingIntent.getBroadcast(
Activity_Reminder.this, 0, intent, 0);
long alarmTime = dateMgmt.getTimeForAlarm(pickedDate);
Calendar c = Calendar.getInstance();
c.setTimeInMillis(alarmTime);
// Schedule the alarm!
AlarmManager am = (AlarmManager) getSystemService(ALARM_SERVICE);
am.set(AlarmManager.RTC_WAKEUP, alarmTime + 15000,
mAlarmSender);
2) From the receiver I call a service
Bundle bundle = intent.getExtras();
String itemName = bundle.getString("item_name");
String reminderOrAlarmMessage = bundle.getString("message");
String activityToTrigg = bundle.getString("activityToTrigg");
int itemId = Integer.parseInt(bundle.getString("item_id"));
NotificationManager nm = (NotificationManager) context.getSystemService("notification");
CharSequence text = itemName + " "+reminderOrAlarmMessage;
Notification notification = new Notification(R.drawable.icon, text,
System.currentTimeMillis());
Intent newIntent = new Intent();
newIntent.setAction(activityToTrigg);
newIntent.putExtra("item_id", itemId);
CharSequence text1= itemName + " "+reminderOrAlarmMessage;
CharSequence text2= context.getString(R.string.notif_Go_To_Details);
PendingIntent pIntent = PendingIntent.getActivity(context,0, newIntent, 0);
notification.setLatestEventInfo(context, text1, text2, pIntent);
notification.flags = Notification.FLAG_AUTO_CANCEL;
notification.defaults = Notification.DEFAULT_ALL;
nm.notify(itemId, notification);
Thanks in Advance,
monn3t
Ok, when you set an PendingIntent, you're supposed to assign it a unique ID to it, incase you want to identify it later (for modifying/canceling it)
static PendingIntent getActivity(Context context, int requestCode, Intent intent, int flags)
//Retrieve a PendingIntent that will start a new activity, like calling Context.startActivity(Intent).
static PendingIntent getBroadcast(Context context, int requestCode, Intent intent, int flags)
//Retrieve a PendingIntent that will perform a broadcast, like calling Context.sendBroadcast().
The Request code is that ID.
In your code, you keep resetting the SAME PendingIntent, instead use a different RequestCode each time.
PendingIntent pIntent = PendingIntent.getActivity(context,uniqueRQCODE, newIntent, 0);
It has to be an integer, i suppose you have a primaryid (itemId) that can identify Alarm A from Alarm B.
You can set up multiple alarms by supplying different request code in pendingIntent.getBroadcast(......)
The approach which I used to setup multiple alarm is that I created a single alarm. I initialized a static integer in alarm setting class which will be incremented each time from my main activity whenever I click on "add alarm" button in my main activity.
E.g.
MainActivity.java
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
public void addAlarmClick(View v) {
AlarmActivity.broadcastCode++;
startActivity(new Intent(this, AlarmActivity.class));
}
}
AlarmActivity.java
public class AlarmActivity extends AppCompatActivity {`
//........
public static int broadcastCode=0;
//........
Intent myIntent = new Intent(AlarmActivity.this, AlarmReceiver.class);
pendingIntent = PendingIntent.getBroadcast(AlarmActivity.this,
broadcastCode, myIntent, 0);
For an easier way, if you are listing your Alarms by RecyclerView,
PendingIntent pendingIntent = PendingIntent.getBroadcast(getBaseContext(), recyclerAdapterAlarm.getItemCount()+1, intent, PendingIntent.FLAG_UPDATE_CURRENT);
It works for me.