I am trying to run a service, whem i stop my app that service still run means it's continuing its task. What is the way to stop service when we stop our app? Plese help me how can i stop this service. One more thing is also there if i use intent in this class to move back to that class from where service is calling i moved back but when i press back button on emulator to go back then it display that service screen also.
I am showing the code of service class
public class SetMovableBG_Inbuilt_SetImage extends Service
{
Timer mytimer;
int interval = 2000;
int interval1 = 4000;
Drawable drawable;
WallpaperManager wpm;
int prev = 0;
int numImage;
private ArrayList<Integer> imgId;
#Override
public void onCreate()
{
super.onCreate();
mytimer = new Timer();
wpm = WallpaperManager.getInstance(this);
}
// here i am geting intent from the class from where i am calling this class.
//everything works fine but service not stops even after stop the app
#Override
public int onStartCommand(Intent intent, int flags, int startId)
{
imgId = intent.getIntegerArrayListExtra("ImgId");
numImage = imgId.size();
mytimer.schedule(new TimerTask()
{
#Override
public void run()
{
// TODO Auto-generated method stub
if ( prev >= numImage )
{
prev = 0;
}
try
{
wpm.setResource(imgId.get(prev));
}
catch ( IOException e )
{
e.printStackTrace();
}
prev++;
}
}, interval, interval1);
return super.onStartCommand(intent, flags, startId);
}
#Override
public IBinder onBind(Intent arg0)
{
return null;
}
}
you can use Service.stopService method to stop the service from other component like activities. You can use Service.stopSelf method to stop the service from the service itself. according to doc
A started service must manage its own lifecycle. That is, the system
does not stop or destroy the service unless it must recover system
memory and the service continues to run after onStartCommand()
returns. So, the service must stop itself by calling stopSelf() or
another component can stop it by calling stopService().
To know more about Services see here
Related
I am trying to learn service in android.My goal is like that i will pass a LatLng Object to the service then service will do something with that and when the work will be finished then it will buzz the phone for sometime and stop.Finally the service will be finished.Now I have some query on that:
I will call the service from my app and user can close my app though
service is not finished.will service do the job initiated by my app or
it will also finish??
What i studied take me here that service will continue to execute and one thing i don't have to return anything back to activity who has initiated the service.I have written some code.Can anyone help me out??
public class MapService extends Service {
private boolean isRunning = false;
#Override
public void onCreate() {
Log.i(TAG, "Service onCreate");
isRunning = true;
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.i(TAG, "Service onStartCommand");
//Creating new thread for my service
//Always write your long running tasks in a separate thread, to avoid ANR
new Thread(new Runnable() {
#Override
public void run() {
//here i will do my work
if(isRunning){
Log.i(TAG, "Service running");
}
}
//Stop service once it finishes its task
stopSelf();
}
}).start();
return Service.START_STICKY;
}
#Override
public IBinder onBind(Intent arg0) {
Log.i(TAG, "Service onBind");
return null;
}
#Override
public void onDestroy() {
isRunning = false;
Log.i(TAG, "Service onDestroy");
}
}
Will it work if user closes the app??
Yes this service will run even if user will close app.It is also possible if android system demands memory service will be stopped but it will restart again
as you have set your flag START_STICKY in your onStartCommand.
On Android KitKat and above(4.4+), the service will be stopped if user swipe kills the application and it won't be restarted by the system. See this discussion(1). If the application was stopped by Android system itself (for low resources), the service will be restarted after a while(use START_STICKY flag).
On Android 4.3 and below, service will be restarted irrespective of whether application was stopped by system or user(use START_STICKY flag).
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
// We want this service to continue running until it is explicitly stopped, so return sticky.
return START_STICKY;
}
I am building an app which has a background service for continuously communicating with a Raspberry Pi.
I am making the service sticky(Service.START_STICKY) so that is will restart when it's killed by user or OS.
This works well for the first 30-40 minuten. After 30-40 minutes the services seems to be stopped.
Isn't there any way to avoid this problem? I know it's bad for the batterylife if there is service continiously runnnig in the background. The app is used in my own project to automate my room and is only used by me. So the batterylife isn't a problem.
public class RaspberryPiCommunication extends Service {
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
//Do continuouswork here in a seperate thread
return Service.START_STICKY;
}
}
I also have another quetions about service:
If the service is started twice in the following example, will there be two instances of SomeObject() and is doSomWork() running twice in background?
public class RaspberryPiCommunication extends Service {
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
SomeObject obj = new SomeObject();
obj.doSomeWork();
return Service.START_STICKY;
}
}
Are you running the service on its own thread ? By default, A service runs on the main thread. For a long running task like this run it in a separate thread
Note that services, like other application objects, run in the main thread of their hosting process. This means that, if your service is going to do any CPU intensive (such as MP3 playback) or blocking (such as networking) operations, it should spawn its own thread in which to do that work.
Service will run only in one Instance. onStartCommand() is called every time you start the service.
http://developer.android.com/guide/components/services.html#StartingAService
Here is required piece of code.
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
// TODO Auto-generated method stub
handler.postDelayed(runnable, 1000 );// 1000 - Milliseconds
if (appContext == null) {
appContext = getBaseContext();
}
Toast.makeText(appContext, "Services Started", Toast.LENGTH_SHORT).show();
return START_STICKY;
}
Runnable runnable = new Runnable(){
#Override
public void run() {
// TODO Auto-generated method stub
DoBackgroundTasks();
handler.postDelayed(this, 1000 ); // 1000 - Milliseconds
}
};
void DoBackgroundTasks()
{
//write code here.
}
In your manifest where you have declared your service, add this
android:process="remote"
I intended to work like this:
user switches on a feature: let say weather.
now weather data will come from server every 6 hours and will be shown to widget(remoteview), Now user switches off the feature. then widget should not show the weather or even refresh the data every 6 hours.
there are also 3-4 more features like that.
Now i had created a service to get all required data and than i have passed them to remoteview. For starting service i had used this in TimeOut Activity:
i = new Intent(TimeOut.this, TimeService.class);
i.setAction("com.example.Weather.Idle");
startService(i);
same for stopping service in switch off code:
stopService(i)
This code was working fine in API <=19. But in Lollipop it crashes at starting or stoping service.
I searched a lot in SO and also tried code for Binding or unbinding service but didn't help any.
Please help me with some code rather than just links...
Thanks in advance :)
Starting a service from any activity class
Intent intent = new Intent(MainActivity.this, BackgroundService.class);
startService(intent);
Here is service class code
public class BackgroundService extends Service{
public static Context appContext = null;
#Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return null;
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
// TODO Auto-generated method stub
if (appContext == null) {
appContext = getBaseContext();
}
Toast.makeText(appContext, "Services Started", Toast.LENGTH_SHORT).show();
return START_STICKY;
}
Add your logic here. You can do some work here using a thread. You can stop service whenever you want and i hope you will not find any crash.
I have faced similar issue with Service in 5.0. This is probably not the correct answer, but it works. You could try. I use EventBus to communicate with my services. So when I want to stop the service I'd send,
EventBus.getDefault().post(new ServiceEvent(ServiceEvent.STOP_SERVICE));
In the service,
public void onEvent(ServiceEvent event) {
if (event.getEvent() == ServiceEvent.STOP_SERVICE) {
methodToStopService();
}
}
private void methodToStopService() {
// do some stuff
stopSelf();
}
Make sure you register your service for events.
private void registerEventBus() {
EventBus eventBus = EventBus.getDefault();
if (!eventBus.isRegistered(this)) {
eventBus.register(this);
}
}
ServiceEvent class - It's my own class which I use with EventBus.
public class ServiceEvent {
private int event;
public static final int STOP_SERVICE = -1;
public ServiceEvent(int event) {
this.event = event;
}
public int getEvent() {
return event;
}
}
In my android app i have one service which calls some webservices after a fix interval.
App is running perfectly in foreground and refresh data,but when user exit from app and use some other app then my app force close after many times.
Why this app force close while running in background.
Code that i was using for start service -
msgIntent = new Intent(mContext, MyBackgroundService.class);
startService(msgIntent);
and inside onDestroy() of my main activity i have following code to stop service-
if(msgIntent!=null){
stopService(msgIntent);
}
background service call some async task and each aync task onPostExecute() method execute some insert statement in database.
i am not geting why this force close occure.
Please give your comments.
Thanks in advance.
My Service Code
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
callAsynchronousTask();
return Service.START_NOT_STICKY;
}
#Override
public void onCreate() {
mContext = this;
super.onCreate();
}
#Override
public IBinder onBind(Intent intent) {
return null;
}
public void callAsynchronousTask() {
final Handler handler = new Handler();
Timer timer = new Timer();
TimerTask doAsynchronousTask = new TimerTask() {
#Override
public void run() {
handler.post(new Runnable() {
public void run() {
try {
callWebservice();
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
};
timer.schedule(doAsynchronousTask, START_DELAY, DELAY);
}
Actually the problem is here
if(msgIntent!=null){
stopService(msgIntent);
}
in your onDestroy(). Because when you close your application so this above code gets called which is closing your service.
And after closing service again you are trying to insert data by calling service + web service. Hence, there is no service object thats why it gets crashed.
To handle this scenario, you need to comment above code which is in onDestroy() & then check/run it, will solve your problem. & there you need to stop your service by other ways. Go step by step.
you stop the service at onDestroy() method. but services are not depend the activity. So try to neglect the stop service.
(or)
try
{
//stop service code
}
catch(Exception e)
{
}
try this.
I'm trying to call a service class to update the value of a variable from my widget but it doesn't ever seem to get to the service class. I've had a look at some examples and I can't figure out what I'm doing wrong, and I don't really know very much about services yet. All help appreciated.
Service class
public class toggleMonitoringService extends Service{
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onCreate()
{
Log.d("Me","creating service");
super.onCreate();
}
#Override
public int onStartCommand(Intent intent, int startId, int something) {
// TODO Auto-generated method stub
String toggle = intent.getExtras().getString("Toggle");
Log.d("Me","Toggle : " + toggle);
if (toggle.equals("app1"))
{
UpdateWidgetService.monitorApp1 = !UpdateWidgetService.monitorApp1;
}
else if (toggle.equals("app2"))
{
UpdateWidgetService.monitorApp2 = !UpdateWidgetService.monitorApp2;
}
super.onStartCommand(intent, startId, something);
return 0;
}
}
Where I set up the intent and pending intent to handle the button click from the widget
Intent monitor1toggle = new Intent(this.getApplicationContext(),toggleMonitoringService.class);
monitor1toggle.setAction(AppWidgetManager.ACTION_APPWIDGET_UPDATE);
monitor1toggle.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS,allWidgetIds);
monitor1toggle.putExtra("Toggle","app1");
PendingIntent monitor1 = PendingIntent.getService(getApplicationContext(), 0 , monitor1toggle,0);
remoteViews.setOnClickPendingIntent(R.id.firstappstatus, monitor1);
Try start service manually, wihtout using PendingIntent.
Better way is not to start service each time you need to do something, but to start it once, bind to it and use common method calls when you need something from the service.
For your example even a simple Thread would be more appropriate.