Starting up Service with AlarmManager , which already might be running - android

I need to run a service in time interval, for example every 2 minutes. I register it with AlarmManager, it works fine when the service stops itself before that 2 minutes is up, but there is a great chance it will take more than 2 minutes, in this case I'll need the service to be terminated and start up a new one, how can I do this?
AlarmManager am = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
Intent i = new Intent(getApplicationContext(), Sender.class);
PendingIntent pi = PendingIntent.getService(getApplicationContext(), 0, i, 0);
am.setRepeating(AlarmManager.RTC_WAKEUP,System.currentTimeMillis(),1000 * 30, pi);

Instead of starting service by AlarmManager use broadcast. Set AlarmManager to send some broadcast intent. Create your own BroadcastReceiver that will receive that intent and in onReceive method restart(stop and start) service.
//Start AlarmManager sending broadcast
Intent intent = new Intent(context, MyBroadcastReceiver.class); // explicit
peningIntent = PendingIntent.getBroadcast(context, 0, intent, 0);
mAlarmManager.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(), 30 * 1000, pendingIntent);
.
//BroadcastReceiver
public class MyBroadcastReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Intent serviceIntent = new Intent(SynchronizationService.class.getName());
context.stopService(serviceIntent);
context.startService(serviceIntent);
}
}
.
//Register receiver in AndroidManifest.xml in Application tag
<receiver
android:name="com.example.MyBroadcastReceiver" >
</receiver>

You should write a login in onStartCommand itself.
Check if service is running or not using variable.
If its running call stopSelf method on service,then again call startservice for same service.

start a alarm manager services u have to use this code
Intent intent = new Intent(activity.this,Sender.class);
pendingIntent = PendingIntent.getBroadcast(activity.this.getApplicationContext(),1, intent, 0);
alarmManager.set(AlarmManager.RTC_WAKEUP,System.currentTimeMillis(),1000 * 30, pendingIntent);
for stop this broadcast receiver use this code
Intent intent = new Intent(activity.this,Sender.class);
pendingIntent = PendingIntent.getBroadcast(activity.this.getApplicationContext(), 1,intent, 0);
pendingIntent.cancel() ;

Related

I use "Action to make Phone Call" but I need to make a called automatically for 5 or 10 min

This is an example
But I need to make a called for 5 minutes or 10 minute automatically. How I can make it?
Intent in=new Intent(Intent.ACTION_CALL,Uri.parse("0000000000"))
try{
startActivity(in);
}
you can use broadcast receiver and set action as Time change.And set Alarm for every 5 min to send action to broadcast receiver.
Add this code in your activity:
PendingIntent service = null;
Intent intentForService = new Intent(context.getApplicationContext(), YourService.class);
final AlarmManager alarmManager = (AlarmManager) context
.getSystemService(Context.ALARM_SERVICE);
final Calendar time = Calendar.getInstance();
time.set(Calendar.MINUTE, 0);
time.set(Calendar.SECOND, 0);
time.set(Calendar.MILLISECOND, 0);
if (service == null) {
service = PendingIntent.getService(context, 0,
intentForService, PendingIntent.FLAG_CANCEL_CURRENT);
}
alarmManager.setRepeating(AlarmManager.RTC, time.getTime()
.getTime(), 60000, service);
Create Broadcast Receiver and add code for Make Call in onReceive() of receiver.
public class MyBroadcastReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Log.d("BroadcastReceiver", "debut receive");
Intent in=new Intent(Intent.ACTION_CALL,Uri.parse("0000000000"))
startActivity(in);
}
}
I hope its helpful to you.
Happy Coding..

Pending intent with different intent but same ID

I have two pending Intent to use with Alarm Manager one is:
Intent i = new Intent(context, TriggerAlarm.class);
PendingIntent pi =PendingIntent.getBroadcast(context,0,i,PendingIntent.FLAG_CANCEL_CURRENT);
and the other is:
Intent i = new Intent(context, TriggerNotification.class);
PendingIntent pi = PendingIntent.getBroadcast(context,0, i,PendingIntent.FLAG_CANCEL_CURRENT);
I use these two in different methods in my application
my question is:
Are these pendingIntents differnt from each other?? because the intents are different but the Ids are same
If I set alarm manager for each of these pending intent do both of them trigger or one replace another?
So the easy way is test it directly by yourself.
I have tested it on my computer and here is what i got:
Are these pendingIntents different from each other?? because the intents are different but the Ids are same
-Yes they are different each other although the Ids are same
If I set alarm manager for each of these pending intent do both of them trigger or one replace another?
-Both of them will be triggered
Here are my code for test, you can copy and try it by yourself
Copy this method to your activity, and call it
private void setAlarmManager() {
Log.v("AlarmManager", "Configuring AlarmManager...");
Intent startIntent1 = new Intent(context, AlarmReceiverFirst.class);
PendingIntent pendingIntent1 = PendingIntent.getBroadcast(context, 0, startIntent1, PendingIntent.FLAG_CANCEL_CURRENT);
Intent startIntent2 = new Intent(context, AlarmReceiverSecond.class);
PendingIntent pendingIntent2 = PendingIntent.getBroadcast(context, 0, startIntent2, PendingIntent.FLAG_CANCEL_CURRENT);
AlarmManager alarm = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
calendar.add(Calendar.SECOND, 20);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
Log.v("AlarmManager", "Starting AlarmManager for >= KITKAT version");
alarm.setExact(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), pendingIntent1);
alarm.setExact(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), pendingIntent2);
} else {
Log.v("AlarmManager", "Starting AlarmManager for < KITKAT version");
alarm.set(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), pendingIntent1);
alarm.set(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), pendingIntent2);
}
Log.v("AlarmManager", "AlarmManager has been started");
}
Create your first receiver class
public class AlarmReceiverFirst extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Log.v(this.getClass().getSimpleName(), "first alarm receiver is called");
}
}
Create your second receiver class
public class AlarmReceiverSecond extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Log.v(this.getClass().getSimpleName(), "second alarm receiver is called");
}
}
Register those receivers to your manifest
<receiver android:name=".AlarmReceiverFirst" />
<receiver android:name=".AlarmReceiverSecond" />
Not to be confused, what you called Id here is called request code. It is used for cancelling the pending intent.
Intents are just the action PendingIntent is bound to execute once it triggers. But this triggering criteria are entirely depending on PendingIntent itself and RequestCode is playing here a pretty good role to uniquely identify, manage and trigger PendingIntent.
Therefore, no matter what the Intent is, if the requestCode is repeated then the latter PendingIntent will trigger. If you need to trigger multiple PendingIntents, the requestCode must be different from each other.
You can have same name of intents but with different ids like following,
Intent i = new Intent(context, TriggerAlarm.class);
PendingIntent pi =PendingIntent.getBroadcast(context,System.currentTimeMillis(),i,PendingIntent.FLAG_CANCEL_CURRENT);
And
Intent i = new Intent(context, TriggerNotification.class);
PendingIntent pi = PendingIntent.getBroadcast(context,System.currentTimeMillis(), i,PendingIntent.FLAG_CANCEL_CURRENT);
This way both the intents would be distinguished differently from each other and will get triggered.You can have any unique id instead of System.currentTimeMillis()

Android is killing my service?

with a BroadCastReceiver, I execute a service at the smartphone boot:
public class BootReceiver extends BroadcastReceiver{
#Override
public void onReceive(Context context, Intent intent) {
Intent startServiceIntent = new Intent(context, MyService.class);
context.startService(startServiceIntent);
}
}
MyService:
private Runnable myRunnable = new Runnable() {
public void run() {
parsing.cancel(true);
parsing = new Parsing();
parsing.execute();
handler.postDelayed(this, timeoutUpdate);
}
};
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
handler.removeCallbacks(myRunnable);
handler.postDelayed(myRunnable, 1000);
return Service.START_STICKY;
}
The service is really executed at the boot, but if I set a timeout of 1 hour between executions, service is not executed (maybe the system is killing it). Otherwise, if I set 60 sec between repetition, all works.
How can I do it? Thanks.
You may run the service in the foreground using startForeground().
A foreground service is a service that's considered to be something
the user is actively aware of and thus not a candidate for the system
to kill when low on memory.
But bear in mind that a foreground service must provide a notification for the status bar (read here), and that the notification cannot be dismissed unless the service is either stopped or removed from the foreground.
Note: This still does not absolutely guarantee that the service won't be killed under extremely low memory conditions. It only makes it less likely to be killed.
OR
If you dont want to run the service in the foreground then you can run service in a periodic intervals using AlarmManager
Intent intent = new Intent(context, MyService.class);
PendingIntent pintent = PendingIntent.getService(this, 0, intent, 0);
AlarmManager alarm = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
alarm.setRepeating(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), AlarmManager.INTERVAL_HOUR, pintent);
Update
Cancel the registered event by using
Intent intent = new Intent(context, MyService.class);
PendingIntent pintent = PendingIntent.getService(this, 0, intent, 0);
AlarmManager alarm = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
alarmManager.cancel(pintent);
To schedule a job use AlarmManager in BroadcastReciever.
Intent intent = new Intent(context, MyService.class);
PendingIntent pintent = PendingIntent.getService(context, 0, intent, 0);
AlarmManager alarm = (AlarmManager)getSystemService(Context.ALARM_SERVICE);
alarm. setRepeating(AlarmManager.RTC_WAKEUP, triggerInMillis, intervalMillis, pintent);
System will awake your service and then you will be able to execute task immediately.
set highest priority for your service
<intent-filter
android:priority="integer" >
</intent-filter>
The value must be an integer, such as "100". Higher numbers have a higher priority. The default value is 0. The value must be greater than -1000 and less than 1000.

Why an Alarm Broadcast receiver not receiving broadcast?

I am trying to start a service at specific intervals with help of a BroadcastReceiver. I have defined the receiver as an inner class in service itself as follows:
public class AlarmReciever extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Log.d("RTESPLDebug", "Recieved Broadcast!"); //Never appears in LogCat
//Intent i = new Intent(context, LocationUpdateService.class);
context.startService(intent);
}
};
I register the alarm receiver in service's onCreate():
context = super.getApplicationContext();
AlarmReceiver ar = new AlarmReceiver();
IntentFilter intfilter = new IntentFilter(Intent.ACTION_DEFAULT);
intfilter.addCategory(Intent.CATEGORY_DEFAULT);
registerReceiver(ar, intfilter);
I first start the service from my first activity and then register a single alarm there:
Intent i = new Intent(context, LocationUpdateService.class);
context.startService(i);
// Schedule first alarm
int nextUpdateInterval = 30*1000; // Let first alarm be after 30 sec
Calendar cal = Calendar.getInstance();
Intent intent = new Intent(context, LocationUpdateService.class);
intent.setAction(Intent.ACTION_DEFAULT);
intent.addCategory(Intent.CATEGORY_DEFAULT);
PendingIntent pintent = PendingIntent.getBroadcast(context, 0, intent, 0);
AlarmManager alarm = (AlarmManager)getSystemService(Context.ALARM_SERVICE);
alarm.set(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis()+nextUpdateInterval, pintent);
In the service I register for a single location update, and when I receive update (I do receive), I process it (I have debugged this, processing indeed completes without errors), and then I register next alarm in similar way as above:
int nextUpdateInterval = getNextUpdateInterval(); // Returns 30000
Calendar cal = Calendar.getInstance();
Intent intent = new Intent(context, LocationUpdateService.class);
intent.setAction(Intent.ACTION_DEFAULT);
intent.addCategory(Intent.CATEGORY_DEFAULT);
PendingIntent pintent = PendingIntent.getBroadcast(context, 0, intent, 0);
AlarmManager alarm = (AlarmManager)getSystemService(Context.ALARM_SERVICE);
alarm.set(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis()+nextUpdateInterval, pintent);
Lots of code and a long questions.

Alarm + Notification: nothing happens

I am trying to implement an alarm that would display a notification everyday at the same hour of the day.
Here is the function I'm calling in my activity:
private void restartNotify() {
AlarmManager am = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
// Intent for our BroadcastReceiver
Intent intent = new Intent(this, AlarmReceiver.class);
// PendingIntent for AlarmManager
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT );
// In case we have already set up AlarmManager, we cancel.
am.cancel(pendingIntent);
am.set(AlarmManager.RTC_WAKEUP, System.currentTimeMillis()+10000, pendingIntent);
}
And here is my broadcast receiver class
public class AlarmReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
NotificationManager nm = (NotificationManager)context.getSystemService(Context.NOTIFICATION_SERVICE);
Notification notification = new Notification(R.drawable.icon_notif, context.getString(R.string.NotificationLaunchMssg), System.currentTimeMillis());
// This is intent we want to launch when user clicks on the notification.
Intent intentTL = new Intent(context, MyClass.class);
notification.setLatestEventInfo(context, context.getString(R.string.NotificationTitle), context.getString(R.string.NotificationBody),
PendingIntent.getActivity(context, 0, intentTL, PendingIntent.FLAG_CANCEL_CURRENT));
nm.notify(1, notification);
//Here we set next notification, in day interval
AlarmManager am = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT);
am.set(AlarmManager.RTC_WAKEUP, System.currentTimeMillis()+10000, pendingIntent);
}
}
As you can see in this code I am using a test value (+10000 milliseconds) because I am simply trying to trigger the alarm 10 seconds after my app has started. But it doesn't work, nothing is displayed.
I don't know if the alarm has a problem, or the notification, nothing is happening.
Do you have any idea why?
Thanks for your help
EDIT: after adding some test code in AlarmReceiver method, it turns out this code is never run. So I probably don't call it properly, what is wrong?
Do not use this approach try setInexactRepeating(...) or setRepeating(...) instead. Why are u giving extra work to the BroadcastReceiver for setting alarm every time it receives the intent.
here is a little code:
alarmManager.setInexactRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP,
0, 10000, pendingIntent);
// The pending intent will the same as yours. 10000 is the
// interval for between consecutive alarms
as azertiti mentioned in comments " By the time it's registered that time will already be in the past." so use 0 or System.currentTimeMillis().

Categories

Resources