I have made an android application that displays a notification message at a particular time (say 6:15:00 pm) of the day. I have used the Calendar along with AlarmManager class for this purpose.
However, when I installed the app on my phone to test it, it showed me the message/notification at the specified time but continues to show the same at any time..I mean the notification keeps on coming throughout the day in my phone even though I have set the time for it in my app.
Here is my code
1) Activity class
import java.util.Calendar;
import android.app.Activity;
import android.app.AlarmManager;
import android.app.PendingIntent;
import android.content.Intent;
import android.os.Bundle;
public class MainActivity extends Activity
{
private PendingIntent pendingIntent;
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.MONTH, 6);
calendar.set(Calendar.YEAR, 2013);
calendar.set(Calendar.DAY_OF_MONTH, 13);
calendar.set(Calendar.HOUR_OF_DAY, 20);
calendar.set(Calendar.MINUTE, 48);
calendar.set(Calendar.SECOND, 0);
calendar.set(Calendar.AM_PM,Calendar.PM);
Intent myIntent = new Intent(MainActivity.this, MyReceiver.class);
pendingIntent = PendingIntent.getBroadcast(MainActivity.this, 0, myIntent,0);
AlarmManager alarmManager = (AlarmManager)getSystemService(ALARM_SERVICE);
alarmManager.set(AlarmManager.RTC, calendar.getTimeInMillis(), pendingIntent);
} //end onCreate
}
2) Receiver
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
public class MyReceiver extends BroadcastReceiver
{
#Override
public void onReceive(Context context, Intent intent)
{
Intent service1 = new Intent(context, MyAlarmService.class);
context.startService(service1);
}
}
3) Service class
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
public class MyAlarmService extends Service
{
private NotificationManager mManager;
#Override
public IBinder onBind(Intent arg0)
{
// TODO Auto-generated method stub
return null;
}
#Override
public void onCreate()
{
// TODO Auto-generated method stub
super.onCreate();
}
#SuppressWarnings("static-access")
#Override
public void onStart(Intent intent, int startId)
{
super.onStart(intent, startId);
mManager = (NotificationManager) this.getApplicationContext().getSystemService(this.getApplicationContext().NOTIFICATION_SERVICE);
Intent intent1 = new Intent(this.getApplicationContext(),MainActivity.class);
Notification notification = new Notification(R.drawable.ic_launcher,"This is a test message!", System.currentTimeMillis());
intent1.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP| Intent.FLAG_ACTIVITY_CLEAR_TOP);
PendingIntent pendingNotificationIntent = PendingIntent.getActivity( this.getApplicationContext(),0, intent1,PendingIntent.FLAG_UPDATE_CURRENT);
notification.flags |= Notification.FLAG_AUTO_CANCEL;
notification.setLatestEventInfo(this.getApplicationContext(), "AlarmManagerDemo", "This is a test message!", pendingNotificationIntent);
mManager.notify(0, notification);
}
#Override
public void onDestroy()
{
// TODO Auto-generated method stub
super.onDestroy();
}
}
I have added both service and receiver in manifest.xml file. Please can anyone tell me what should I do to display the notification only once during the entire day?
I guess the reason was the onCreate method was called multiple times and so your alarmManager.set was called multiple times. For example, whenever the screen orientation is changed, that activity is destroyed and a new activity starts by onCreate() method. So every time you rotate the screen that activity will be destroyed and a new activity starts by onCreate() method and alarmManager.set was called again.
You may save a state member in onSaveInstanceState(Bundle bundle) method. Android calls this method whenever the screen is rotated, and that given bundle bundle would be passed to oncreate(Bundle bundle). In your onCreate, check the Bundle is null before try to call alarmManager.set.
I did not ever use BroadcastReceiver like
Intent myIntent = new Intent(MainActivity.this, MyReceiver.class);
So I doubt whether the usage of BroadcastReceiver is wrong, usually we use BroadcastReceiver as below:
<receiver android:name=".MyReceiver">
<intent-filter>
<action android:name="mypackage.START_ALARM" ></action>
</intent-filter>
</receiver>
Intent i = new Intent("mypackage.START_ALARM");
try this its working fine for me :
Calendar cal = Calendar.getInstance();
cal.set(Calendar.HOUR_OF_DAY, 11);
cal.set(Calendar.MINUTE, 54);
cal.set(Calendar.SECOND, 0);
ca.set(Calendar.MILLISECOND, 0);
Intent intent = new Intent(getBaseContext(), Receiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(
getBaseContext(), 1, intent, 0);
AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
alarmManager.set(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(),
pendingIntent);
Related
I have an app work on remind the user with timetable
I put a calendar in new class with notification and go to main activity and called it.
but it the first method only showed the notification but the second not showed it why ????????
MainActivity.java
package com.osman.calendar;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import com.pushbots.push.Pushbots;
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Pushbots.sharedInstance().init(this);
new section(this,1, 18, 30,"Title","new message","new message");
new section(this,2, 18, 37,"Title","get new","get new");
}
}
section.java
package com.osman.calendar;
import android.app.AlarmManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import java.util.Calendar;
public class section {
public section(Context context,int id,int Hours,int Minute, String Tilte , String Text, String Alert){
AlarmManager alarmMgr = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(context, AlarmReceiver.class);
intent.putExtra("id",id);
intent.putExtra("Title",Tilte);
intent.putExtra("Text",Text);
intent.putExtra("Alert",Alert);
PendingIntent alarmIntent = PendingIntent.getBroadcast(context.getApplicationContext(), 0, intent, 0);
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
calendar.set(Calendar.HOUR_OF_DAY, Hours);
calendar.set(Calendar.MINUTE, Minute);
alarmMgr.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(),
1000 * 60 * 60 * 24 * 7, alarmIntent);
}
}
AlarmReceiver.java
package com.osman.calendar;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.Vibrator;
import android.support.v4.app.NotificationCompat;
import android.widget.Toast;
public class AlarmReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(context, "Time is up!!!!.",Toast.LENGTH_LONG).show();
String Title = intent.getExtras().getString("Title");
String Text = intent.getExtras().getString("Text");
String Alert = intent.getExtras().getString("Alert");
int id = intent.getExtras().getInt("id");
createNotification(context, Title, Text, Alert,id);
// Vibrate the mobile phone
Vibrator vibrator = (Vibrator) context.getSystemService(Context.VIBRATOR_SERVICE);
vibrator.vibrate(2000);
}
public void createNotification (Context context, String msg,String msgText, String msgAlert,int id){
PendingIntent notificIntent = PendingIntent.getActivity(context, 0, new Intent(context, MainActivity.class), 0);
NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(context)
.setSmallIcon(R.mipmap.ic_launcher)
.setContentTitle(msg)
.setContentText(msgText)
.setTicker(msgAlert);
mBuilder.setContentIntent(notificIntent);
mBuilder.setDefaults(NotificationCompat.DEFAULT_SOUND);
mBuilder.setAutoCancel(true);
NotificationManager mNotificationMAnger =(NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
mNotificationMAnger.notify(id, mBuilder.build());
}
}
If you schedule a alarm with the same PendingIntent as before, the alarm you set before is updated and not a new one is set. Only one alarm is firing because your PendingIntent didn't change when you use it the second time, only the extras change (according to this question's answer this isn't considered a change).
To not update the old alarm but set a new one, you have to use a different request-code (the second parameter in getBroadcast() - currently you use 0 for both alarms).
Just use the id you already have as parameter in your section-constructor as request-code.
I successfully used the AlarmManager to set an alarm in the future and I was able to have a BroadcastReceiver getting called at alarm time. I read that you can use the PowerManager to turn device on in case it went to sleep and use the KeyguardManager to unlock the device.
But I also need to start my app or bring it into foreground. Will this be done automatically? I can not find a hint to this in the Internet.
You can do this by sending a startActivity in your broadcast receiver with your main activity as the intent.
Got it :)
//The Main Activity
public class FullscreenActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED | WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD | WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON);
}
Context context=this;
Alarm alarm = new Alarm();
public void onDummyButton(View view) {
alarm.SetAlarm(this);
}
}
//The Alarm Receiver
import android.app.AlarmManager;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.util.Log;
import android.widget.Toast;
import java.util.Calendar;
public class Alarm extends BroadcastReceiver
{
#Override
public void onReceive(Context context, Intent intent)
{
//Log.d("Alarm", "onReceive");
// Put here YOUR code.
// Start the MainActivity
Intent i = new Intent(context, FullscreenActivity.class);
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(i);
Toast.makeText(context, "Alarm !!!!!!!!!!", Toast.LENGTH_LONG).show(); // For example
}
public void SetAlarm(Context context)
{
AlarmManager am =( AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
Intent i = new Intent(context, Alarm.class);
PendingIntent pi = PendingIntent.getBroadcast(context, 0, i, 0);
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis() + 1000 * 15);
//calendar.set(Calendar.HOUR_OF_DAY, calendar.get(Calendar.HOUR_OF_DAY));
//calendar.set(Calendar.MINUTE, calendar.get(Calendar.MINUTE)+1);
am.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), 1000 * 60 * 10, pi); // Millisec * Second * Minute
Toast.makeText(context, "Alarm scheduled for: " + calendar.get(Calendar.HOUR_OF_DAY)+':'+calendar.get(Calendar.MINUTE)+':'+calendar.get(Calendar.SECOND), Toast.LENGTH_LONG).show();
}
public void CancelAlarm(Context context)
{
Intent intent = new Intent(context, Alarm.class);
PendingIntent sender = PendingIntent.getBroadcast(context, 0, intent, 0);
AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
alarmManager.cancel(sender);
}
I am making a sample app just for educational purposes, where I create a notification every minute. I also have a button to cancel the alarm.
What I do is that when the notification comes, I click it and click the unset button I have set to run unsetAlarm(). But it continues to bother me every minute.
How do I stop the notifications? Could it be that the activity is somehow duplicated? If this is the case, how do I ensure there is only one instance of the MainActivity?
MainActivity class
package no.perandersen.notifyontimeexample;
import java.util.Calendar;
import android.app.Activity;
import android.app.AlarmManager;
import android.app.PendingIntent;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
public class MainActivity extends Activity {
private AlarmManager alarmManager;
private PendingIntent notifyIntent;
private static final String TAG = "MainActivity";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
}
public void setAlarm(View v) {
Intent myIntent = new Intent(MainActivity.this,
NotificationService.class);
notifyIntent = PendingIntent.getService(MainActivity.this, 0,
myIntent, 0);
Calendar calendar = Calendar.getInstance();
calendar.add(Calendar.MINUTE, 1);
Log.v(TAG, "time for alarm trigger:" + calendar.getTime().toString());
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP,
calendar.getTimeInMillis(), 1 * 60 * 1000, notifyIntent);
}
public void unsetAlarm(View v) {
alarmManager.cancel(notifyIntent);
Log.v(TAG, "cancelling notification");
}
}
NotificationService class
package no.perandersen.notifyontimeexample;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.support.v4.app.NotificationCompat;
import android.util.Log;
public class NotificationService extends Service {
private NotificationManager nm;
private static final String TAG = "NotificationService";
#Override
public void onCreate() {
// TODO Auto-generated method stub
super.onCreate();
Log.v(TAG, "on onCreate");
}
#Override
public void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
nm = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
Log.v(TAG, "on onStartCommand");
Intent mainActivityIntent = new Intent(this, MainActivity.class);
PendingIntent pIntent = PendingIntent.getActivity(this, 0, mainActivityIntent, 0);
Notification notification = new NotificationCompat.Builder(this)
.setContentTitle("bothering you")
.setContentText("Just bothering you from example code")
.setSmallIcon(R.drawable.ic_launcher)
.setContentIntent(pIntent)
.build();
notification.flags |= Notification.FLAG_AUTO_CANCEL;
notification.flags |= Notification.FLAG_SHOW_LIGHTS;
notification.defaults |= Notification.DEFAULT_SOUND;
notification.defaults |= Notification.DEFAULT_VIBRATE;
notification.defaults|= Notification.DEFAULT_LIGHTS;
nm.notify(0, notification);
return super.onStartCommand(intent, flags, startId);
}
#Override
public IBinder onBind(Intent arg0) {
// TODO Auto-generated method stub
return null;
}
}
The problem is that to cancel an Alarm you need to recreate the PendingIntent exactly how you created it when you set the alarm. So change your unsetAlarm() to
public void unsetAlarm(View v) {
Intent myIntent = new Intent(MainActivity.this,
NotificationService.class);
notifyIntent = PendingIntent.getService(MainActivity.this, 0,
myIntent, 0); // recreate it here before calling cancel
alarmManager.cancel(notifyIntent);
Log.v(TAG, "cancelling notification");
}
Not able to get the notification for particular date set using calendar class .
I have set the year, date time, month , second using calendar class, Not able to get Notification.
any help would be appreciated , Below is the code snippet.
public class CalActivity extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
final Intent chartNotifier = new Intent(CalActivity.this,
CRT.class);
PendingIntent pendingIntent = PendingIntent
.getBroadcast(
CalActivity.this,
234324243,
chartNotifier,
PendingIntent.FLAG_UPDATE_CURRENT);
Calendar calendar = Calendar.getInstance();
//calendar.set(year, month, day, hour, min, 0);
//calendar.set(2012, 8, 15, 12, 18,0);
calendar.set(Calendar.YEAR,2012);
calendar.set(Calendar.MONTH, 8-1);
calendar.set(Calendar.DAY_OF_MONTH,15);
calendar.set(Calendar.HOUR, 12);
calendar.set(Calendar.MINUTE,32);
calendar.set(Calendar.SECOND, 15);
long when =calendar.getTimeInMillis();
AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
alarmManager.set(AlarmManager.RTC_WAKEUP,when,
pendingIntent);
}
}
Receiver Class
public class CRT extends BroadcastReceiver {
String trainNo, journeyDate;
#Override
public void onReceive(Context context, Intent intent) {
// TODO Auto-generated method stub
System.out.println("Has arrived inside Receiver");
// Call Service
Intent service = new Intent(context, ChartNotifierService.class);
context.startService(service);
}
}
Service class is
package com.cal;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.os.IBinder;
public class ChartNotifierService extends Service {
String trainNo;
String journeyDate;
#Override
public IBinder onBind(Intent arg0) {
// TODO Auto-generated method stub
return null;
}
#Override
public void onStart(Intent intent, int startId) {
// TODO Auto-generated method stub
super.onStart(intent, startId);
String ns = Context.NOTIFICATION_SERVICE;
NotificationManager notificationManager = (NotificationManager) ChartNotifierService.this
.getSystemService(ns);
long when = System.currentTimeMillis();
Notification notification = new Notification(R.drawable.ic_launcher, "Time",
when);
notification.flags |= Notification.FLAG_INSISTENT
| Notification.FLAG_AUTO_CANCEL;
Intent enterPnr = new Intent(ChartNotifierService.this, CalActivity.class);
enterPnr.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
PendingIntent enterIntent = PendingIntent.getActivity(
ChartNotifierService.this, 0, enterPnr, 0);
notification.setLatestEventInfo(ChartNotifierService.this, "Date",
"time", enterIntent);
notificationManager.notify(0, notification);
}
#Override
public void onCreate() {
// TODO Auto-generated method stub
super.onCreate();
}
}
Change
Calendar.setField(Calendar.HOUR, xx)
to
Calendar.setField(Calendar.HOUR_OF_DAY, xx)
I'd like develop an Alarm Application.
The application should work like this:
launch it
the activity show me the time
I can set the alarm
I can close the application
when the alarm time comes , it starts an activity (even if the device is locked)
I have tried to adapt this sample https://github.com/commonsguy/cwac-wakeful but I cannot launch an activity when the alarm time comes.
I use this code to setup the alarm (for test I have inserted this code on an onCreate method of activity):
Intent intent = new Intent(this, OnAlarmReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0, intent, 0);
Calendar cal = Calendar.getInstance();
cal.add(Calendar.SECOND, 10);
AlarmManager alarm = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
alarm.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, cal.getTimeInMillis(),
pendingIntent);
this is the OnAlarmReceiver class:
public class OnAlarmReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Log.i(ClockActivity.LOG_TAG, "OnAlarmReceiver::onReceive");
WakefulIntentService.sendWakefulWork(context, AlarmService.class);
}
}
this is the service class:
public class AlarmService extends WakefulIntentService {
public AlarmService(String name) {
super(name);
}
#Override
protected void doWakefulWork(Intent intent) {
Log.i(ClockActivity.LOG_TAG, "AlarmService::doWakefulWork");
Intent newIntent = new Intent(getApplicationContext(), ClockActivity.class);
newIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
newIntent.setAction(ClockActivity.ALARM_ACTION);
getApplicationContext().startActivity(newIntent);
}
}
this is the portion of Manifest where are setup the service and the receiver:
<receiver android:name=".OnAlarmReceiver"></receiver>
<service android:name=".AlarmService"></service>
the doWakefulWork method is never called!
I have made this application:
AlarmActivity.java
package com.foo;
import pack.breceiver.MyBroadcastReceiver;
import android.app.Activity;
import android.app.AlarmManager;
import android.app.PendingIntent;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.EditText;
import android.widget.Toast;
import android.app.Activity;
import android.os.Bundle;
public class AlarmActivity extends Activity {
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
public void startAlert(View view) {
EditText text = (EditText) findViewById(R.id.time);
int i = Integer.parseInt(text.getText().toString());
Intent intent = new Intent(this, MyBroadcastReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(
this.getApplicationContext(), 234324243, intent, 0);
AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
alarmManager.set(AlarmManager.RTC_WAKEUP, System.currentTimeMillis()
+ (i * 1000), pendingIntent);
Toast.makeText(this, "Alarm set in " + i + " seconds",
Toast.LENGTH_LONG).show();
}
}
MyBroadcastReceiver.java
package pack.breceiver;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.Vibrator;
import android.widget.Toast;
public class MyBroadcastReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(context, "Don't panik but your time is up!!!!",
Toast.LENGTH_LONG).show();
/*// Vibrate the mobile phone
Vibrator vibrator = (Vibrator) context.getSystemService(Context.VIBRATOR_SERVICE);
vibrator.vibrate(2000); */
}
}
check this out : http://blog.nelsondev.net/?p=124
using"alarmmanager"
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP,
AlarmCal.getTimeInMillis(), AlarmManager.INTERVAL_FIFTEEN_MINUTES,
pendingAlarmIntent);
I had a similar problem and I resolved removing the receiver from manifest and set in my code registering him with registerReceiver.
Do you get an instantiation exception maybe ?
You should have a public no arg constructor in your service :
public class AlarmService extends WakefulIntentService {
public AlarmService() {
super("AlarmService");
}
// etc
}