How to create a background notification - android

I want to implement a Service which permit to show a notification (daily, or after XX minutes) even if I close the application. (Actually, when I press back button, I finish the MainActivity...)
I need a runnable notification even if I didn't start the application (after rebooting the device for example, of course when the trigger is declanched)...
I tried some clear examples and tutorials but I doesn't find what I need.
Please HELP!
Thanks in advance,
Mohamed

You can do it with alarm manger:
public class AlarmHelper {
private Context context;
private AlarmManager alarmManager;
private static final String TAG = "AlarmHelper";
public final static String ALARM_ALERT_ACTION = "com.android.alarmclock.ALARM_ALERT";
public AlarmHelper(Context context) {
this.context = context;
alarmManager = (AlarmManager) context
.getSystemService(Context.ALARM_SERVICE);
}
public void setNotifyAlarm(Long milliSecond) {
PendingIntent pendingIntent = getNotifyPendingIntent();
alarmManager.cancel(pendingIntent);
alarmManager.set(AlarmManager.RTC_WAKEUP, milliSecond, pendingIntent);
// alarmManager.set(AlarmManager.RTC_WAKEUP, milliSecond, sender);
}
public void cancelNotifyAlarm() {
PendingIntent pendingIntent = getNotifyPendingIntent();
alarmManager.cancel(pendingIntent);
}
private PendingIntent getNotifyPendingIntent() {
Intent intent = new Intent(context, AlarmExpireService.class);
return PendingIntent.getService(context, 0, intent, 0);
}
public void setExpireAlarm(int minute) {
Calendar calendar = Calendar.getInstance();
calendar.add(Calendar.MINUTE, minute - 1);
PendingIntent pendingIntent = getExpirePendingIntent();
alarmManager.set(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(),
pendingIntent);
}
public void cancelExpireAlarm() {
PendingIntent pendingIntent = getExpirePendingIntent();
alarmManager.cancel(pendingIntent);
}
private PendingIntent getExpirePendingIntent() {
return PendingIntent.getService(context, 0, new Intent(context,
AlarmExpireService.class), 0);
}
}
Now in the AlarmExpireService.java:
public class AlarmExpireService extends Service {
// private static final String TAG = "AlarmExpireService";
private static final String TAG = "AlarmExpireService";
#Override
public void onCreate() {
super.onCreate();
//your logic for start activity or generate notification.
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
AppLog.Log(TAG, "On start command");
return START_STICKY;
}
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onDestroy() {
super.onDestroy();
}
}
Now Register service in the manifest file:
<service android:name="your_package.AlarmExpireService" />
For just call a method from AlarmHelper's setNotifyAlarm method and your work is done pass the time in millisecond (it will start after that time and notification will be pop up).
For more information take a reference of this links:
1. AlarmManager
2. Service
3.Pending Intent

Related

Triggering an alarm at a specific time every day by using setExact()

I am trying to trigger an alarm once at a specific time everyday. But like all others I am using setExact() instead of setRepeating(). Alarm is firing at the correct time. But once it fires it keeps on repeating itself after every 5sec. How can I trigger it only once in a day at a specific time? Here is my code:
MainActivity.java:
public class MainActivity extends AppCompatActivity implements Observer {
private AlarmManager alarmManager = null;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
BroadcastObserver.getInstance().addObserver(this);
}
#Override
public void update(Observable o, Object arg) {
Log.e("MainActivity", "Alarm set through observer");
cancelAlarm();
setAlarm();
}
#Override
protected void onStart() {
super.onStart();
if (!checkAlarm()) {
setAlarm();
}
}
public void setAlarm() {
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.HOUR_OF_DAY, 14);
calendar.set(Calendar.MINUTE, 13);
calendar.set(Calendar.SECOND, 0);
alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(this, MyReceiver.class);
intent.setAction(MyReceiver.ACTION_RECEIVER);
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 1001, intent, PendingIntent.FLAG_CANCEL_CURRENT);
alarmManager.setExact(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), pendingIntent);
}
private boolean checkAlarm() {
Intent intent = new Intent(this, MyReceiver.class);
intent.setAction(MyReceiver.ACTION_RECEIVER);
boolean isSet = PendingIntent.getBroadcast(this, 1001, intent, PendingIntent.FLAG_NO_CREATE) != null;
Log.e("MainActivity", isSet + " :Alarm is set");
return isSet;
}
#Override
protected void onStop() {
super.onStop();
cancelAlarm();
}
private void cancelAlarm() {
Intent intent = new Intent(this, MyReceiver.class);
intent.setAction(MyReceiver.ACTION_RECEIVER);
final PendingIntent pendingIntent =
PendingIntent.getBroadcast(MainActivity.this, 1001, intent,
PendingIntent.FLAG_NO_CREATE);
if (pendingIntent != null) {
alarmManager.cancel(pendingIntent);
pendingIntent.cancel();
}
}
}
BroadcastReceiver:
public class MyReceiver extends BroadcastReceiver {
public static final String ACTION_RECEIVER = "Receiver";
#Override
public void onReceive(Context context, Intent intent) {
Log.e("MainActivity", "triggered");
BroadcastObserver.getInstance().updateValue(intent);
}
}
BroadcastObserver:
public class BroadcastObserver extends Observable {
private static BroadcastObserver instance = new BroadcastObserver();
public static BroadcastObserver getInstance(){
return instance;
}
private BroadcastObserver(){}
public void updateValue(Object data) {
synchronized (this) {
setChanged();
notifyObservers(data);
}
}
}
once it fires it keeps on repeating itself after every 5 sec
You are setting an alarm for 14:13 for a given day. When the alarm fires the Observer is notified and it sets the exact same alarm (for 14:13).
At this point we're past 14:13, so the alarm will fire immediately, notifying the Observer again, resulting in an infinite loop of the above steps.
The simplest solution might be to check the time when setting the alarm and if it's in the past, then add a day to it:
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.HOUR_OF_DAY, 14);
calendar.set(Calendar.MINUTE, 13);
calendar.set(Calendar.SECOND, 0);
if (calendar.before(Calendar.getInstance())) {
calendar.add(Calendar.DAY_OF_YEAR, 1);
}
To avoid memory leaks you need to remove the Observer when appropriate:
#Override
protected void onDestroy() {
BroadcastObserver.getInstance().deleteObserver(this);
super.onDestroy();
}
Also, cancelling the alarm in update() is redundant. This is not a repeating alarm, so it makes no sense to cancel it after it fired.

push notification repearting for every second

Hi guys i am trying to create the push notification using the alarm manager where push notification must come at morning 8AM everything is good but notification is also coming but after 8AM notification is completed the notification coming when ever i open the App or clear from recents or for every one hour notification is coming please help me out facing this problem from last 1 Week
MainActivity.class
am = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
Intent notificationintent = new Intent(this, Notify.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 100, notificationintent, PendingIntent.FLAG_UPDATE_CURRENT);
notificationintent.setData((Uri.parse("custom://"+System.currentTimeMillis())));
Calendar calnotify = Calendar.getInstance();
Calendar now=Calendar.getInstance();
//Time Alaram manager
calnotify.set(Calendar.HOUR_OF_DAY, 10);
calnotify.set(Calendar.MINUTE, 00);
calnotify.set(Calendar.SECOND, 0);
if (now.after(calnotify)){
calnotify.add(Calendar.DATE,1);
}
am.setRepeating(AlarmManager.RTC_WAKEUP, calnotify.getTimeInMillis(), AlarmManager.INTERVAL_DAY, pendingIntent);
Notify.class
//BroadCastReceiver class
public class Notify extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Intent pushservice=new Intent(context,PushNotification.class);
pushservice.setData((Uri.parse("custom://"+System.currentTimeMillis())));
context.startService(pushservice);
}
}
PushNotification.class
public class PushNotification extends Service {
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onCreate() {
super.onCreate();
Resources resources = getResources();
getnotify(resources);
}
#Override
public void onStart(Intent intent, int startId) {
super.onStart(intent, startId);
Resources resources = getResources();
getnotify(resources);
/*Notify notify=new Notify();
notify.abortBroadcast();*/
}
private void getnotify(Resources resources) {
Bitmap icon = BitmapFactory.decodeResource(resources,
R.drawable.sr_notification_icon);
PugNotification.with(this)
.load()
.title(getResources().getString(R.string.app_name))
.message("Latest Chitka")
.bigTextStyle(getResources().getString(R.string.app_name))
.smallIcon(getNotificationIcon())
.largeIcon(icon)
.flags(android.app.Notification.DEFAULT_ALL).autoCancel(true).click(MyCalendarActivity.class)
.simple()
.build();
}
private int getNotificationIcon() {
boolean useWhiteIcon = (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP);
return useWhiteIcon ? R.drawable.sr_icon : R.drawable.sr_notification_icon;
}
}
Looks like the code for setting alarm is executing multiple times as it is called from the main Activity of the application. You should set a flag that gets set to true once the alarm is set. Next time skip the alarm setting based on this flag.

Why Background Service stops working when app is closed?

I am trying to create a background service that will be called every ten minutes, perform a task and this should not be killed when the application is closed.
The following is the code snippet:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_location_service);
Intent intent = new Intent(this, AlarmReceiverLifeLog.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT);
AlarmManager alarms = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
Calendar calendar = Calendar.getInstance();
alarms.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), 10 * 60 * 1000, pendingIntent);
}
In onCreate, it will call the AlarmReceiverLifeLog class every ten minutes. The following is the code for AlarmReceiverLifeLog class:
public class AlarmReceiverLifeLog extends BroadcastReceiver {
static Context context;
#Override
public void onReceive(Context context, Intent intent) {
Intent ll24Service = new Intent(context, LifeLogService.class);
context.startService(ll24Service);
}
}
public class LifeLogService extends Service {
#Override
public void onCreate() {
super.onCreate();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
return START_STICKY;
}
#Override
public void onDestroy() {
}
#Override
public void onTaskRemoved(Intent rootIntent) {
Intent restartService = new Intent(getApplicationContext(), this.getClass());
restartService.setPackage(getPackageName());
PendingIntent restartServicePI = PendingIntent.getService(getApplicationContext(), 1, restartService, PendingIntent.FLAG_ONE_SHOT);
Calendar calendar = Calendar.getInstance();
AlarmManager alarmService = (AlarmManager) getApplicationContext().getSystemService(Context.ALARM_SERVICE);
alarmService.set(AlarmManager.ELAPSED_REALTIME, calendar.getTimeInMillis() + 100, restartServicePI);
}
#Override
public IBinder onBind(Intent intent) {
return null;
}
}
I am not able to figure out what I have missed. When I close the app the background services is getting killed.
Can anyone suggest anything regarding this?
when the app is closed the service get closed also because they are in a one thread, so the service should be on another thread in order fot it not to be closed, look into that and look into keeping the service alive with alarm manager here an example http://www.vogella.com/articles/AndroidServices/article.html this way your service won't be shown in notification.

Android service does not start with setInexactRepeating

I'm trying to create a service that increments some variables every 10 seconds permanently. To do so, i used setInexactRepeating to launch it in onCreate of MainActivity, but the service is never created...
public class MainActivity extends Activity {
Mothership mothership;
AlarmManager manager;
Calendar calendar;
Intent i;
PendingIntent pIntent;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mothership = (Mothership) getApplicationContext();
mothership.initTopBar((ImageView) findViewById(R.id.exposure_eye),(TextView) findViewById(R.id.energy_level), (TextView) findViewById(R.id.human_number));
mothership.data.changeCurrentActivity(DynamicData.Main);
manager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
i = new Intent(MainActivity.this, TimerService.class);
pIntent = PendingIntent.getService(this, 0, i, 0); // paramètres à analyser
calendar = Calendar.getInstance();
calendar.set(Calendar.SECOND, 10);
// Service
manager.cancel(pIntent);
manager.setInexactRepeating(AlarmManager.ELAPSED_REALTIME, calendar.getTimeInMillis(), AlarmManager.INTERVAL_FIFTEEN_MINUTES/90, pIntent);
}
TimerService only contains 2 instructions in order the variables when it's called :
public class TimerService extends IntentService {
private final static String TAG = "TimerService";
Mothership mothership;
public TimerService() {
super(TAG);
}
#Override
protected void onHandleIntent(Intent intent) {
incEnergy();
decStealth();
}
#Override
public void onCreate() {
super.onCreate();
mothership = (Mothership) getApplicationContext();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
return super.onStartCommand(intent, flags, startId);
}
#Override
public void onDestroy() {
super.onDestroy();
}
public void incEnergy() {
mothership.data.energyInc();
mothership.topbar.update();
}
public void decStealth() {
mothership.data.exposureDecrease();
mothership.topbar.update();
}
}
What am I doing wrong?
I've empirically found that for both inexact and exact (pre-19 when all become inexact) repeating alarms, the minimum time seems to be about 30 minutes. Even then, I've found the timing for repeating alarms to be wildly unpredictable. For instance, when I've asked for a 35 minute period, I'll get some alarms at about 35 minutes intervals, some hours apart, and some within a few minutes of each other.
I've found it much more predictable to just ask for a one-shot alarm and then resubmit a new one each time the alarm fires.

How to stop Alarm Manager?

I have created the start alarm as shown below
public class MyScheduleReceiver extends BroadcastReceiver {
// Restart service every 30 seconds
private static final long REPEAT_TIME = 1000 * 5;
#Override
public void onReceive(Context context, Intent intent) {
AlarmManager service = (AlarmManager) context
.getSystemService(Context.ALARM_SERVICE);
Intent i = new Intent(context, MyStartServiceReceiver.class);
PendingIntent pending = PendingIntent.getBroadcast(context, 0, i,
PendingIntent.FLAG_CANCEL_CURRENT);
Calendar cal = Calendar.getInstance();
cal.add(Calendar.SECOND, 5);
service.setInexactRepeating(AlarmManager.RTC_WAKEUP,
cal.getTimeInMillis(), REPEAT_TIME, pending);
I crate this for stop alarm and i call it from main activity.Manifest i think is ok...Work repeat but no stop!!!
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.setup);
sendBroadcast(new Intent(this,MyScheduleReceiver.class));
}
public void StopRepeat(View view) {
sendBroadcast(new Intent(this,MyStopReceiver.class));
}
public class MyStartServiceReceiver extends BroadcastReceiver {
public void onReceive(Context context, Intent intent) {
Toast.makeText(context, "Repeat service!.",
Toast.LENGTH_LONG).show();
}
public class MyStopReceiver extends BroadcastReceiver {
// Restart service every 30 seconds
private static final long REPEAT_TIME = 1000 * 5;
#Override
public void onReceive(Context context, Intent intent) {
AlarmManager service = (AlarmManager) context
.getSystemService(Context.ALARM_SERVICE);
Intent istop = new Intent(context, MyStartServiceReceiver.class);
PendingIntent pending = PendingIntent.getBroadcast(context, 0, istop,
PendingIntent.FLAG_CANCEL_CURRENT);
Calendar cal = Calendar.getInstance();
cal.add(Calendar.SECOND, 5);
service.cancel(pending);
But the service is not stopping. What might be the issue?Thanks.
The simplest option is to restart your device. (If you created a BOOT_COMPLETED listener just remove it for now.)
You can also cancel an alarm by passing the PendingIntent you used to create the alarm to AlarmManager#cancel(). You have already written the code to do this, but do you have a Button with the XML attribute android:onClick="StopRepeat" in setup.xml? Did you click it?
Solution
We eventually discovered you had a mistake in your Manifest file, so MyStopServiceReceiver was never called...

Categories

Resources