Hi i need to stop the Background service which is already started after particular time.I will get the duration from server for when to stop the service.I have tried the Alarm Manager in android.
Calendar cal = Calendar.getInstance();
Intent intent = new Intent(context, MyService.class);
PendingIntent pintent = PendingIntent.getService(context, 0, intent, 0);
AlarmManager alarm = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
// Start every 30 seconds
alarm.setRepeating(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), 60*1000, pintent);
Log.e(TAG, "Service started in Activity");
This above code is starting the service after every one minute.But i dont want to start the service.I need to stop the service after a minute.How to do that.Is that possible to do with Alarm Manager.Please guide me.
Try that:
add parameter to your pendingIntent
Intent intent = new Intent(context, MyService.class);
intent.putExtra("param_name", "end");
PendingIntent pintent = PendingIntent.getService(context, 0, intent, 0);
Override onStartCommand() method in your Service
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
try{
String parameter = intent.getStringExtra("param_name");
if(parameter.equals("end")){
stopSelf();
}
}catch(Exception ex){
}
}
Also you can try to use Handler in your service:
Handler variable:
private Handler handler = new Handler() {
#Override
public void handleMessage(Message msg) {
switch (msg.what) {
case 1: {
stopSelf();
}break;
}
}
}
Delayed task:
handler.sendEmptyMessageDelayed(1, 60 * 1000);
Create the timer task to stop the service and assign the delay time which you are getting from your server
Timer timer = new Timer ();
TimerTask hourlyTask = new TimerTask () {
#Override
public void run () {
// your code here to stop the service ...
}
};
// schedule the task to run assign the time (DelayTime) which you are getting from server
timer.schedule (hourlyTask, DelayTime);
So what is the particular time.
You can do 1 thing make note of the starting time of the service. and if you want to stop the service after a specified duration or the specific time get the system current time compare it with that time if it match's stop the service. this should resolve the problem.
Tell me if it works for you..
======>
Just Follow the steps provided steps below:
Use sharedprefrence to save the start time of the service.
If your not familiar to shearedprefrence URL:http://examples.javacodegeeks.com/android/core/content/android-sharedpreferences-example/
Then in the service onStart method get the system current time if it
matches the time stop the service.
You have to create an broadcast receiver:
Calendar cal = Calendar.getInstance(); // this will return current time
// if you want to trigger after 1 minute then add into calender object
cal.add(Calendar.MINUTE, 1);
Intent intentAlarm = new Intent(this, AlarmReciever.class);
intentAlarm.setAction("My_Action");
AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
PendingIntent pendingIntent = PendingIntent.getBroadcast(
MainActivity.this, REQUEST_CODE, intentAlarm,
PendingIntent.FLAG_UPDATE_CURRENT);
// set the alarm for particular time
alarmManager.set(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), pendingIntent);
AlarmReciever .java
public class AlarmReciever extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
// call method to stop service
}
}
Also declare this AlarmReceiver class in menifest file
<receiver android:name=".AlarmReciever" >
</receiver>
> here i used the countdowntime for 30second
after 30second call stopself() method it will stop your
services..u can also do what ever u want on finsih you can also pass a
notification to the user....
new CountDownTimer(30000, 1000) {
#Override
public void onTick(long l) {
}
#Override
public void onFinish() {
//r u can also pass a notification
stopSelf();
}
}.start();
Related
I am trying to make an alarm that triggers an event some number of seconds from now, one time, from within a DialogFragment.
Here is the relevant code, I put in onCreate():
broadcastReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context c, Intent i) {
Toast.makeText(c, "Rise and Shine!", Toast.LENGTH_LONG).show();
}
};
getActivity().registerReceiver(broadcastReceiver, new IntentFilter(ALARM_MANAGER_TAG) );
pendingIntent = PendingIntent.getBroadcast(getActivity(), 0, new Intent(ALARM_MANAGER_TAG), 0 );
alarmManager = (AlarmManager)(getActivity().getSystemService( Context.ALARM_SERVICE ));
And then when I press the start button:
alarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, timestampEnd, pendingIntent);
In this case timestampEnd = System.currentTimeMillis() + 10 * 1000;, 10 seconds.
And then I have overridden destroy:
#Override
public void onDestroy() {
alarmManager.cancel(pendingIntent);
getActivity().unregisterReceiver(broadcastReceiver);
super.onDestroy();
}
And yet, nothing happens for some reason.
You're passing AlarmManager.ELAPSED_REALTIME_WAKEUP, which means the AlarmManager is going to use SystemClock.elapsedRealtime() when checking timestamps. Since you're passing something calculated off of System.currentTimeMillis(), you are going to have to wait about 47 years before the alarm fires.
Either change your first argument to AlarmManager.RTC_WAKEUP or change your timestamp to be calculated off of SystemClock.elapsedRealtime().
I know there are so many questions about this.
I tried most of them and spent so much time on it.
but not getting any solution
Actually, I want a background process to run to infinite time even app is removed from recent app
I want to take GPS location of user repetitively after 15 minute
so first I had tried with following
TRY 1******
I have created broadcast receiver who will call my service
name of that broadcast receiver is LocationServiceRestarter
I am initiating alarm repeater who will call LocationServiceRestarter at regular interval of 5 seconds
Intent intent = new Intent("com.lmf.overduereport.gpstimer.LocationServiceRestarter");
intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
PendingIntent pendingIntent = PendingIntent.getBroadcast(getApplicationContext(),
0, intent, PendingIntent.FLAG_CANCEL_CURRENT);
AlarmManager am =
(AlarmManager)getSystemService(Activity.ALARM_SERVICE);
alarm_manager.setRepeating(AlarmManager.RTC_WAKEUP,SystemClock.elapsedRealtime()+5*1000,5*1000,pendingIntent);
it works fine if I don't remove app from recent apps
I have added a log inside broadcast receiver who writes log in my folder about if broadcast receiver called or not.
in this case broadcast receiver itself is not called from alarm manager then it will obviously not call service that i want to be called to record location.
TRY 2******
I have also tried services who can run infinitely. but it also stops working after app closes
TRY 3******
This time I will not call repetitive alarm manager instead of that I did following
Intent intent = new Intent("com.lmf.overduereport.gpstimer.LocationServiceRestarter");
intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
PendingIntent pendingIntent = PendingIntent.getBroadcast(getApplicationContext(),
0, intent, PendingIntent.FLAG_CANCEL_CURRENT);
AlarmManager am =
(AlarmManager)getSystemService(Activity.ALARM_SERVICE);
//--
am.set(AlarmManager.ELAPSED_REALTIME_WAKEUP,
SystemClock.elapsedRealtime() + 5000, pendingIntent);
above will call broadcast receiver and in broadcast receiver I have added alarm manager as follows
LocationServiceM.appendLog("Got Reciever******");
intent = new Intent("com.lmf.overduereport.gpstimer.LocationServiceRestarter");
intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
PendingIntent pendingIntent = PendingIntent.getBroadcast(context,
12345, intent, PendingIntent.FLAG_CANCEL_CURRENT);
AlarmManager am =
(AlarmManager) context.getSystemService(Activity.ALARM_SERVICE);
am.set(AlarmManager.ELAPSED_REALTIME_WAKEUP,
SystemClock.elapsedRealtime() + 5000, pendingIntent);
above will reinitiate broadcast receiver with new schedule time so chain will continue.
but sadly that also don't work. it works fine if app is not removed from the recent app.
even I had tried same above thing with service and intent service with no luck.
Conclusion: alarm manager or Broadcast receiver is not called after app is removed from the recent app.
but I have seen many app that runs in background even app is closed from recent app.
you can use START_STICKY which tells the OS to recreate the service after it has enough memory and call onStartCommand() again with a null intent. START_NOT_STICKY tells the OS to not bother recreating the service again.
you can use a service to fired when app is closed or kill from the task:
public class SensorService extends Service {
public int counter=0;
public SensorService(Context applicationContext) {
super();
Log.i("HERE", "here I am!");
}
public SensorService() {
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
super.onStartCommand(intent, flags, startId);
startTimer();
return START_STICKY;
}
#Override
public void onDestroy() {
super.onDestroy();
Log.i("EXIT", "ondestroy!");
Intent broadcastIntent = new Intent("uk.ac.shef.oak.ActivityRecognition.RestartSensor");
sendBroadcast(broadcastIntent);
stoptimertask();
}
private Timer timer;
private TimerTask timerTask;
long oldTime=0;
public void startTimer() {
//set a new Timer
timer = new Timer();
//initialize the TimerTask's job
initializeTimerTask();
//schedule the timer, to wake up every 1 second
timer.schedule(timerTask, 1000, 1000); //
}
/**
* it sets the timer to print the counter every x seconds
*/
public void initializeTimerTask() {
timerTask = new TimerTask() {
public void run() {
Log.i("in timer", "in timer ++++ "+ (counter++));
}
};
}
/**
* not needed
*/
public void stoptimertask() {
//stop the timer, if it's not already null
if (timer != null) {
timer.cancel();
timer = null;
}
}
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
you also need a BroadcastReceiver which will receive a signal when someone or something kills the service; its role is to restart the service.
public class SensorRestarterBroadcastReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Log.i(SensorRestarterBroadcastReceiver.class.getSimpleName(), "Service Stops! Oooooooooooooppppssssss!!!!");
context.startService(new Intent(context, SensorService.class));;
}
}
For full implementation see this link
http://fabcirablog.weebly.com/blog/creating-a-never-ending-background-service-in-android
here is my code in application class inside oncreate method: But I can't see any message from my app. Can anyone help me to do this?
Intent alarmIntent = new Intent(this, AlarmReceiver.class);
pendingIntent = PendingIntent.getBroadcast(this, 0, alarmIntent, 0);
public void startAlarm() {
manager = (AlarmManager)getSystemService(Context.ALARM_SERVICE);
int interval = 5000;
manager.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(), interval, pendingIntent);
Toast.makeText(this, "Alarm Set", Toast.LENGTH_SHORT).show();
}
And on the broadcast receiver class I have the following code
public class AlarmReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context arg0, Intent arg1) {
// For our recurring task, we'll just display a message
Toast.makeText(arg0, "I'm running", Toast.LENGTH_SHORT).show();
}
}
Edited answer:
Use setInexactRepeating() instead of setRepeating(). setRepeating only takes set intervals with the shortest being INTERVAL_FIFTEEN_MINUTES. setInexactRepeating() is the only way to set a repeating interval as short as 1000ms, or 5000ms in your case.
Change:
manager.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(), interval, pendingIntent);
to
manager.setInexactRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(), interval, pendingIntent);
If you are not getting the exact 5 second delay that you need, you will need to use a Handler. Any type of alarm with a 5 second delay will not work properly because as of Android 5.x basically all repeating alarms are inexact to save battery life.
I have modified your code to use a Handler:
startAlarm();
public void startAlarm() {
final Handler h = new Handler();
final int delay = 5000; //milliseconds
h.postDelayed(new Runnable(){
public void run(){
//do something
Intent alarmIntent = new Intent(getApplicationContext(), AlarmReceiver.class);
sendBroadcast(alarmIntent);
h.postDelayed(this, delay);
}
}, delay);
}
That alarm method will work with your current BroadcastReceiver and do an actual 5 second delay.
I used AlarmManager to schedule recurring background task. When an alarm is triggered, a Pending Intent is broadcast by the Android system. The receiver class simply displays a toast repeatedly, every 10 sec. I have created the intent in startAlarm method, and cancel in cancelAlarm method.
My problem is: when I close the application after creating the alarm, the toast is getting displayed continuously, and when I reopen the app, I lose control on the object that created the background task, so I cannot cancel it. Help?
Here are the methods that control the alarm :
public void startAlarm(Context context)
{
ser=(AlarmManager)context.getSystemService(context.ALARM_SERVICE);
Intent serviceIntent = new Intent(context, AlarmReceiver.class);
pi=PendingIntent.getBroadcast(context, 0, serviceIntent, PendingIntent.FLAG_CANCEL_CURRENT);
Calendar cal=Calendar.getInstance();
cal.add(Calendar.SECOND, 10);
ser.setInexactRepeating(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), REPEAT_TIME, pi);
}
public void cancelAlarm(Context context)
{
if (ser != null)
{
ser.cancel(pi);
ser=null;
Toast.makeText(context, "Alarm Canceled", Toast.LENGTH_SHORT).show();
}
}
And here is the receiver class for the alarm:
public class AlarmReceiver extends BroadcastReceiver
{
#Override
public void onReceive(Context arg0, Intent arg1)
{
Toast.makeText(arg0, "I'm running", Toast.LENGTH_SHORT).show();
}
}
for control of background service you can use
Process.killProcess(int pid)
ActivityManager.killBackgroundProcesses(String packageName)
or forceclose
Intent intent = new Intent(yourCurrentActivity.this,yourNextActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
android.os.Process.killProcess(android.os.Process.myPid());
or for alarm manager u can blew code to cancel alarm.
Depending on your app, you may want to include the ability to cancel the alarm. To cancel an alarm, call cancel() on the Alarm Manager, passing in the PendingIntent you no longer want to fire. For example:
//If the alarm has been set, cancel it.
if (alarmMgr!= null) {
alarmMgr.cancel(alarmIntent);
}
I am working on an application that should download a file from the network every X seconds to check for any change, I use a service to do that, but its execution is not fixed with the delay time rate, here is my code for the service:
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Toast.makeText(this, "service starting", Toast.LENGTH_SHORT).show();
checkUpdate();
return START_STICKY;
}
private Void checkUpdate() {
timer.scheduleAtFixedRate(new TimerTask() {
public void run() {
Log.i("Service", String.valueOf(++counter));
if(Helper.isNetworkAvailable(getBaseContext())) {
// download file
} else {
Log.e("ServiceHandler", "Couldn't get any data from the url");
}
}else {
Log.e("Connection", "No connection");
}
}
}, 10000, 10000);
return null;
}
The output isn't fixed, it is supposed to run every 10 seconds, while running the service run in a random manner
How about setting up an AlarmManager within an IntentService? Much more accurate.
Intent intent = new Intent(context, YourClass.class);
PendingIntent pi = PendingIntent.getService(context, 0, intent, 0);
AlarmManager am = (AlarmManager) c.getSystemService(Context.ALARM_SERVICE);
am.setRepeating(AlarmManager.RTC, System.currentTimeMillis(), 10*1000, pi);
Make sure within YourClass.class (which is an IntentService), put your logic in the handleIntent(Intent intent), which will be called every 10 seconds by the PendingIntent sent by the AlarmManager.
P.S. Update your manifest
Hope it helps
Instead of Timer Class, use AlarmManager class. It also performs the same repeating tasks you want. AlamrManager is light weight and it runs even if your device is in sleep mode.
Also see this link Android: How to repeat a service with AlarmManager
For repetitive jobs android provides simple api, called Timer please look it. Very simple to use.
Try this :
#Override
public void onStart(Intent intent, int startId) {
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
Log.d("Internet Available: ", ""+flag);
Calendar cal = Calendar.getInstance();
cal.add(Calendar.SECOND, 10);
Intent intent1 = new Intent(this, UpdateWidgetServiceDemo.class);
PendingIntent pintent = PendingIntent.getService(this, 0, intent1, 0);
AlarmManager alarm = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
int i;
i=15;
alarm.set(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), pintent);
super.onStart(intent, startId);
}
REMOVE return START_STICKY;