This is my code. It works fine, if I use this in a separate Android studio project. But when I integrate the code to another project it is causing a problem.
If app is open I am able to receive the notifications. But on app close, the notifications are not received.
Also I have observed one thing - I set my alarm at 1:10 (let's say) and close, and re-open the app at 1.09. I am receiving the notification at 1.10 !!.
I am not able to identify what's happening. Please tell me even if am doing silly mistake, Thank you.
public class BroadCast {
public void broadcastIntent(int selected, Context context, long userMilli) {
Intent intent = new Intent(context.getApplicationContext(), ReminderReceiver.class);
Bundle bundle = new Bundle();
bundle.putInt("selected", selected);
intent.putExtras(bundle);
intent.setAction("android.media.action.DISPLAY_NOTIFICATION");
intent.addCategory("android.intent.category.DEFAULT");
Calendar calendar = Calendar.getInstance();
long curMilli = calendar.getTimeInMillis();
PendingIntent pendingIntent = PendingIntent.getBroadcast(context.getApplicationContext(), selected, intent, PendingIntent.FLAG_UPDATE_CURRENT);
AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
if(Build.VERSION.SDK_INT > Build.VERSION_CODES.KITKAT)
alarmManager.setExact(AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime() + (userMilli-curMilli), pendingIntent);
else
alarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime() + (userMilli-curMilli), pendingIntent);
}
}
Above code creates an intent and broadcast using alarmManager.
public class ReminderReceiver extends BroadcastReceiver {
public ReminderReceiver() {
}
#Override
public void onReceive(Context context, Intent intent) {
Bundle bundle = intent.getExtras();
int selected = bundle.getInt("selected");
sendNotification(context, selected);
}
private void sendNotification(Context context, int selected) {
String notificationContentText = "String to display";
NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
NotificationCompat.Builder builder = new NotificationCompat.Builder(context);
builder.setSmallIcon(R.drawable.alarm)
.setContentTitle("Title")
.setPriority(Notification.PRIORITY_MAX)
.setSound(RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION))
.setContentText(notificationContentText)
.setColor(Color.rgb(58,95,205));
notificationManager.notify(selected, builder.build());
}
}
Above code building the notification
This is my AndroidManifest file
<receiver
android:name=".ReminderReceiver"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="android.media.action.DISPLAY_NOTIFICATION"/>
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</receiver>
It was not the problem of BroadcastReceiver or the Service. I had to change my notification settings in my mobile. I use Asus, there you have to check power management option. If it is in power saving mode then the notifications are denied on app close.
Related
that's my code for scheduled notification for my android app, but it does nothing for some reason. Please tell me where is the problem.
Another question: I also made a button which send a notification - just for learning, and for some reason it works only on my samsung s6. When I run the app on the android studio emulator it gives me an error about notification package. Why is that?
Thank a lot!
public void setAlarm(View view) {
Long alertTime = new GregorianCalendar().getTimeInMillis()+5*1000;
Intent alertIntent = new Intent(this, AlertReceiver.class);
AlarmManager alarmManager = (AlarmManager)
getSystemService(Context.ALARM_SERVICE);
alarmManager.set(AlarmManager.RTC_WAKEUP, alertTime,
PendingIntent.getBroadcast(this, 1, alertIntent, PendingIntent.FLAG_UPDATE_CURRENT));
}
}
public class AlertReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
createNotification(context, "Time Up", "5 Seconds Has Passed", "Alert");
}
public void createNotification(Context context, String msg, String msgText, String msgAlert) {
PendingIntent noficitIntent = PendingIntent.getActivity(context, 0,
new Intent(context, MainActivity.class), 0);
NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(context)
.setSmallIcon(R.drawable.ic_launcher)
.setContentTitle(msg)
.setTicker(msgAlert)
.setContentText(msgText);
mBuilder.setContentIntent(noficitIntent);
mBuilder.setDefaults(NotificationCompat.DEFAULT_SOUND);
mBuilder.setAutoCancel(true);
NotificationManager mNotificationManager =
(NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
mNotificationManager.notify(1, mBuilder.build());
}
}
Based on your comments, it seems you just forgot to register your BroadcastReceiver. Per Android docs you will only be able to receive intents on your receiver if you register it first:
You can either dynamically register an instance of this class with Context.registerReceiver() or statically declare an implementation with the tag in your AndroidManifest.xml.
Since you are sending a broadcast directly to your receiver like that:
Intent alertIntent = new Intent(this, AlertReceiver.class);
There is no point in declaring any intent-filter for it, so you just need to add the following line to your AndroidManifest.xml (inside <application> tag):
<receiver android:name="com.your.package.AlertReceiver" />
Hope it helps.
I make one app in that I write service which detect the wifi network and send data to server, for that I write Alarm Manager and broadcast receiver and then through alarm manager and broadcast receiver call service onCreate method. My code below:
BootCompletedIntentReceiver class call broadcast receiver with 30sec.
public class BootCompletedIntentReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
AlarmManager service = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
Intent background = new Intent(context, AlarmReceiver.class);
PendingIntent pending = PendingIntent.getBroadcast(context, 0, background,
PendingIntent.FLAG_CANCEL_CURRENT);
Calendar cal = Calendar.getInstance();
// start 30 seconds after boot completed
cal.add(Calendar.SECOND, 30);
// fetch every 30 seconds
// InexactRepeating allows Android to optimize the energy consumption
service.setInexactRepeating(AlarmManager.RTC_WAKEUP,
cal.getTimeInMillis(),2000, pending);
}
}
AlarmReceiver Class
public class AlarmReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Intent background = new Intent(context, MyService.class);
context.startService(background);
String ns = Context.NOTIFICATION_SERVICE;
NotificationManager mNotificationManager = (NotificationManager)context.getSystemService(ns);
int icon = R.drawable.ic_launcher;
CharSequence tickerText = "Service Started";
long when = System.currentTimeMillis();
Notification notification = new Notification(icon,tickerText, when);
notification.flags |= Notification.FLAG_AUTO_CANCEL;
CharSequence contentTitle = "Service Start!";
CharSequence contentText = "";
Intent notificationIntent = new Intent(context,AlarmReceiver.class);
PendingIntent contentIntent = PendingIntent
.getActivity(context, 0, notificationIntent, 0);
notification.setLatestEventInfo(context, contentTitle, contentText, contentIntent);
mNotificationManager.notify(1, notification);
// Log.d("test", "Saving Data to File from Service.");
}
}
From AlarReceiver service gets call and first onCreate method and then OnstartCommand.. And I write thread to detect the wifi.. This code is run for some phone but some phone service never start. why this is happened??
My Manifest file code is below:
<service android:name="com.edbeans.attendance.MyService"
android:enabled="true"
android:process=":my_process"
android:exported="true"
android:icon="#drawable/ic_launcher"></service>
<receiver android:name="com.edbeans.attendance.AlarmReceiver">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
<receiver android:name="com.edbeans.attendance.BootCompletedIntentReceiver" >
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
Why this is happened that service gets call from some phone and successfully run but some phone service never starts..
The system may go back to a low power state immediately after your alarm received has run. In order to ensure that your Service runs you need to coordinate between the BroadcastReceiver and the Service using a wakelock. Check out the WakefulReceiver as an option to help with this.
I have a small problem about alarmmanager but I couldn't find a answer which fits to my code.
My question is simple. I have a list of alarms which is set to future. While my app is running, I can recieve Notification.
But when I close my app, It doesn't send notification to me and if I run my app again, past notifications can be seen in notification center.
Here is my codes.
In MainActivity.java I use this method which can take a Person List and sets alarm of each of Person. I run this method in onCreate()
private void createScheduledNotification(List<Person> people)
{
for(int i = 0; i<people.size();i++) {
// Get new calendar object
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.MONTH, people.get(i).getMonth());
calendar.set(Calendar.DAY_OF_MONTH, people.get(i).getDay());
calendar.set(Calendar.YEAR, Calendar.getInstance().get(Calendar.YEAR));
calendar.set(Calendar.HOUR_OF_DAY, people.get(i).getHour());
calendar.set(Calendar.MINUTE, people.get(i).getMinute());
calendar.set(Calendar.SECOND, 0);
// Retrieve alarm manager from the system
AlarmManager alarmManager = (AlarmManager) getApplicationContext().getSystemService(getBaseContext().ALARM_SERVICE);
// Every scheduled intent needs a different ID, else it is just executed once
int id = (int) System.currentTimeMillis();
// Prepare the intent which should be launched at the date
Intent intent = new Intent(this, TimeAlarm.class);
intent.putExtra("person", people.get(i));
// Prepare the pending intent
PendingIntent pendingIntent = PendingIntent.getBroadcast(getApplicationContext(), id, intent, PendingIntent.FLAG_UPDATE_CURRENT);
// Register the alert in the system. You have the option to define if the device has to wake up on the alert or not
alarmManager.set(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), pendingIntent);
}
}
And I have a TimeAlarm class which extends BroadcastReciever.
public class TimeAlarm extends BroadcastReceiver {
private Person person;
#Override
public void onReceive(Context context, Intent paramIntent) {
Bundle bundle = paramIntent.getExtras();
person = (Person) bundle.getSerializable("person");
// Request the notification manager
NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
// Create a new intent which will be fired if you click on the notification
Intent intent = new Intent("android.intent.action.VIEW");
// Attach the intent to a pending intent
PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
// Create the notification
Notification notification = new Notification(R.drawable.logo24px, "Never Forget", System.currentTimeMillis());
//
notification.setLatestEventInfo(context, "It's " + person.getName() + " " + person.getSname() + "'s Birthday!", "Celebrate his/her birthday! ",pendingIntent);
// Fire the notification
notificationManager.notify(1, notification);
}
}
Also I add these lines to AndroidManifest.xml
<receiver android:name=".TimeAlarm" >
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
It works fine when app is running but when I close my app in Active Applications page, it doesn't send any notification.
Try use this when you create your intent
Bundle extras = new Bundle();
extras.putSerializable("person", people.get(i));
intent.putExtras(extras);
And in your BroadcastReciver check if the action is a boot completed action. (it could also be your alarm).
#Override
public void onReceive(Context context, Intent paramIntent) {
//CHECK IF IS BOOT COPLETED
if (intent.getAction().equals("android.intent.action.BOOT_COMPLETED")) {
/* Setting the alarm here Alarm are automatically cleaned on phone shutdown*/}
else{
Bundle bundle = paramIntent.getExtras();
person = (Person) bundle.getSerializable("person");
// Request the notification manager
NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
// Create a new intent which will be fired if you click on the notification
Intent intent = new Intent("android.intent.action.VIEW");
// Attach the intent to a pending intent
PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
// Create the notification
Notification notification = new Notification(R.drawable.logo24px, "Never Forget", System.currentTimeMillis());
//
notification.setLatestEventInfo(context, "It's " + person.getName() + " " + person.getSname() + "'s Birthday!", "Celebrate his/her birthday! ",pendingIntent);
// Fire the notification
notificationManager.notify(1, notification);}
}
}
Also check this
PendingIntent pendingIntent = PendingIntent.getBroadcast(getApplicationContext(), id, intent, PendingIntent.FLAG_UPDATE_CURRENT);
because it seems that you are continusly updating the same intent, is what you want?
Edit:
Sorry I didn't remember to insert it, your reciever declaration sholuld be like this.
<receiver android:name=".TimeAlarm"
android:process=":remote"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
In my app, i am setting the Notification as like below code:
// for the PAYE 18 APRIL 2011 // 1
AM_EM_APRIL_2011 = (AlarmManager) getApplicationContext().getSystemService(Context.ALARM_SERVICE);
Intent in1 = new Intent(this, AlarmReceiverNotificationForEveryMonth.class);
in1.putExtra("MyMessage","Your PAYE return is DUE on 20th April 2011.");
PI_EM_APRIL_2011 = PendingIntent.getBroadcast(this, 1, in1, PendingIntent.FLAG_UPDATE_CURRENT);
Calendar calendar_PAYE_18_APRIL_2011 = Calendar.getInstance();
calendar_PAYE_18_APRIL_2011.setTimeInMillis(System.currentTimeMillis());
calendar_PAYE_18_APRIL_2011.set(2011, 3, 18,mHour, mMinute, 0);
AM_EM_APRIL_2011.set(AlarmManager.RTC_WAKEUP, calendar_PAYE_18_APRIL_2011.getTimeInMillis(),PI_EM_APRIL_2011);
Broadcast class for notification is:
public class AlarmReceiverNotificationForTwoMonth extends BroadcastReceiver{
//private Intent intent;
private NotificationManager notificationManager;
private Notification notification;
public static CharSequence contentText;
#Override
public void onReceive(Context context, Intent intent) {
// TODO Auto-generated method stub
// My Notification Code
notificationManager = (NotificationManager)context.getSystemService(Context.NOTIFICATION_SERVICE);
int icon = R.drawable.app_icon;
//System.out.println("The ID Number is: "+Long.parseLong(intent.getData().getSchemeSpecificPart()) );
contentText = intent.getStringExtra("MyMessage");
System.out.println("The Message is: "+intent.getStringExtra("MyMessage"));
CharSequence text = "Your tax amount due period";
CharSequence contentTitle = "Tax Calculator App";
long when = System.currentTimeMillis();
intent = new Intent(context, MenuPageActivity.class);
intent.putExtra("twoMonth", "twoMonth");
PendingIntent contentIntent = PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
notification = new Notification(icon,text,when);
long[] vibrate = {0,100,200,300};
notification.vibrate = vibrate; // To vibrate the Device
notification.ledARGB = Color.RED;
notification.ledOffMS = 300;
notification.ledOnMS = 300;
notification.defaults |= Notification.DEFAULT_LIGHTS;
//notification.flags |= Notification.FLAG_SHOW_LIGHTS;
notification.setLatestEventInfo(context, contentTitle, contentText, contentIntent);
notificationManager.notify(NotificationConstants.NOTIFICATION_ID_TWO_MONTH, notification);
}
}
All Works good with this code. and i got the Notification. But using this i got notification everytime when ever i restart the device. and there are no any message in that notification. Why it is happend like this???
Please help me for this. or what wrong in my code ???
Thanks.
Edited
I have done like this in manifest.xml
<!-- To receive the Alarm Notification for two months-->
<receiver android:name=".AlarmReceiverNotificationForTwoMonth" android:enabled="true">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED"/>
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
</receiver>
Is your AlarmReceiverNotificationForTwoMonth class specified in your manifest as the receiver of the BOOT_COMPLETED broadcast?
If so, then the AlarmReceiverNotifictionForTwoMonth.onReceive() method will be triggered every time the device has booted, and as a result show a notification.
EDIT: Your approach with using the AlarmManager is good. The only problem is that alarms are not restored when the device is rebooted. Therefore you need to recreate any existing alarm when the device reboots. My suggestion would be to change your manifest to this:
<receiver android:name=".AlarmReceiverNotificationForTwoMonth" android:enabled="true" >
</receiver>
<receiver android:name=".RecreateAlarms" >
<intent-filter >
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
Then create a new class
public class RecreateAlarms extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
// reschedule alarms here
}
I don't know your logic when an alarm should be triggered. You may need to save an alarm to a file/database in your AlarmReceiverNotificationForTwoMonth method and read it in the RescheduleAlarms to know if there are any alarms to recreate
For some Android applications, I would like to integrate the following feature:
The user can define a time when he wants to be reminded of something. When the time has come then, the application should create a notification in the notification bar even when the user doesn't use the app at this moment.
For this purpose, the classes AlarmManager, NotificationManager und Notification.Builder are the ones to look at, right?
So how do I create a timed notification in advance? My code (so far) is this:
Add this under to the AndroidManifest to register the broadcast receiver:
<receiver android:name="AlarmNotificationReceiver"></receiver>
Create a new class file which handles the alarm that it receives:
public class AlarmNotificationReceiver extends BroadcastReceiver {
public void onReceive(Context context, Intent intent) {
Bundle extras = intent.getExtras();
if (extras != null) {
String additionalData = extras.getString("displayText");
// show the notification now
NotificationManager mNotificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
Notification mNotification = new Notification(R.drawable.ic_launcher, context.getString(R.string.app_name), System.currentTimeMillis());
PendingIntent pi = PendingIntent.getActivity(context, 0, new Intent(context, MainActivity.class), 0); // open MainActivity if the user selects this notification
mNotification.setLatestEventInfo(context, context.getString(R.string.app_name), additionalData, pi);
mNotification.flags |= Notification.FLAG_AUTO_CANCEL | Notification.DEFAULT_SOUND;
mNotificationManager.notify(1, mNotification);
}
}
}
Use this code (for example in MainActivity) to set the alarm to 3 seconds from now:
Intent i = new Intent(this, AlarmNotificationReceiver.class);
i.putExtra("displayText", "sample text");
PendingIntent pi = PendingIntent.getBroadcast(this.getApplicationContext(), 234324246, i, 0);
AlarmManager mAlarm = (AlarmManager) getApplicationContext().getSystemService(Context.ALARM_SERVICE);
mAlarm.set(AlarmManager.RTC_WAKEUP, System.currentTimeMillis()+3*1000, pi);
What do I need to change to make this work? Thank you!
The two problems are:
The notification's text does not change when I change it in code. It only changes when I change the requestCode in PendingIntent.getBroadcast(...). What is this request code all about? Can it be a random value or 0?
After rebooting my phone, the "planned" notification, or the alarm, is gone. But now I've seen that this is normal behaviour, right? How can I circumvent this?
Not sure about part 1, but for part 2 the general approach is to intercept the BOOT_COMPLETED intent and use that to re-register all alarms. This does unfortunately mean that for each alarm you have registered with the alarm manager you have to store it in your app's db as well.
So, you'll need a broadcast receiver to intercept the BOOT_COMPLETED intent:
public class BootReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
// get your stored alarms from your database
// reregister them with the alarm manager
}
}
To get the BOOT_COMPLETED intent, you must put the following permission in your manifest:
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
And the BootReceiver also needs to be registered in your manifest with the following intent filter:
<receiver android:enabled="true" android:name=".receiver.BootReceiver"
android:permission="android.permission.RECEIVE_BOOT_COMPLETED">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</receiver>
It's important to note that if your app is installed to the sdcard, it can never receive the BOOT_COMPLETED intent. Also, it's worth noting that this implementation is a bit naive in that it executes code immediately on booting which can slow the user's phone down at startup. So, I recommend delaying your execution for a few minutes after intercepting the boot intent.
I personally would do it without a Broadcast Receiver. I'd get the AlarmManager to fire the intent to start a seperate Activity, rather than receiver. Then this new Activity could make the notification for you. I'm not sure if this is a better way, but it seems less complicated to me.
Edit: A Service would probably be better still than an Activity
In your MainActivity:
Intent i = new Intent(getBaseContext(), NotificationService.class);
PendingIntent pi = PendingIntent.getService(getBaseContext(), 0, i, 0);
AlarmManager mAlarm = (AlarmManager) Context.getSystemService(Context.ALARM_SERVICE);
mAlarm.set(AlarmManager.RTC_WAKEUP, System.currentTimeMillis()+10*60*1000, pi);
Your Service:
public class NotificationService extends Service {
public int onStartCommand(Intent intent, int flags, int startId) {
//Create the notification here
return START_NOT_STICKY;
}
Your Manifest:
<service android:name="com.android.yourpath.NotificationService"></service>