I'm a student new to android, and I have an application which use background service.
I want to start/stop the service by clicking on a button, i'm doing it like this:
case R.id.enablepop:
if (!(pop.runningFlag))
startService(new Intent(mainScreen,PopUpService.class));
return true;
case R.id.disablepop:
if (pop.runningFlag)
stopService(new Intent(mainScreen,PopUpService.class));
return true;
In the onStart() function of the service I have runningFlag which I set to "true", then I create a thread that works while runningFlag is true.
I set the runningFlag to false on onDestroy().
The problem is that the service won't stop. Can someone help me plz?
Try to use Handler, like here you can use Handler like Thread.
here is the example
import android.app.Service;
import android.content.Intent;
import android.os.Handler;
import android.os.IBinder;
public class MyService extends Service{
private Handler handler;
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onCreate() {
super.onCreate();
handler = new Handler();
}
#Override
public void onStart(Intent intent, int startId) {
super.onStart(intent, startId);
handler.post(updateStatus);
}
#Override
public void onDestroy() {
super.onDestroy();
handler.removeCallbacks(updateStatus);
handler = null;
}
#Override
public boolean onUnbind(Intent intent) {
handler.removeCallbacks(updateStatus);
handler = null;
return super.onUnbind(intent);
}
private Runnable updateStatus = new Runnable() {
#Override
public void run() {
// do something here
handler.postDelayed(updateStatus, 1000);
}
};
}
here the handler can was initialized into the oncreate method now after that when onStart method invoked then the updateStatus object will invoked through the handler.post() which will start the run method of this Runnable object.
Now in this, this will invoked the run() at once and execute the statement at once only so for repeating this task call inside this method on specific delay time like here 1000 milliseconds so after complete all the execution it will again call after 1 sec and repeating this task this will continue until you cannot remove the runnable object from the handler, so basically that was call into the onDestroy()
Related
I successfully used a service to do a certain task in the foreground. Now, to do it in the background, I'd remove the handler.removeCallbacks method in onDestroy().
But this would also prevents me from stopping the service using stopService(intent).
I saw on the official docs that I should maybe use JobScheduler (as I target API 28).
Here is a more precise indication of my code :
public class MainActivity {
private Intent intent;
onCreate() {
if (intent == null) {
intent = new Intent(this, MyService.class);
}
}
startService(intent);
... // Then is some code to stop the service if needed with stopService(intent)
}
--------------------------------------------------------------
public class myService {
private Handler handler = null;
private static Runnable runnable = null;
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onCreate() {
handler = new Handler();
runnable = new Runnable() {
#Override
public void run() {
System.out.println("Running service times " + i);
i++;
handler.postDelayed(runnable, 1000);
}
};
handler.post(runnable);
}
#Override
public void onDestroy() {
handler.removeCallbacks(runnable);
super.onDestroy();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
return super.onStartCommand(intent, flags, startId);
}
I would like it to run in the background (even if the device is locked) but still being able to disable the service (or JobScheduler?).
What are your suggestions?
you can use work manager
or job dispatcher
and there is a lot of options like
SyncAdapter, Bound services, Intent Service
you can use one of these options according to your need
Run a service in background continuously. For example, a service has to be kicked off which will display a toast message 20 seconds once even if the app is closed.
public class AppService extends IntentService {
public int onStartCommand(Intent intent, int flags, int startId) {
return START_STICKY;
}
public AppService() {
super("AppService");
}
#Override
protected void onHandleIntent(Intent workIntent) {
Toast.makeText(getApplicationContext(), "hai", Toast.LENGTH_SHORT).show();
SystemClock.sleep(20000);
}
}
Below code works for me...
public class AppService extends Service {
#Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return null;
}
#Override
public void onCreate() {
Toast.makeText(this, " MyService Created ", Toast.LENGTH_LONG).show();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Toast.makeText(this, " MyService Started", Toast.LENGTH_LONG).show();
return START_STICKY;
}
}
Accepted answer will not work on from Android 8.0 (API level 26), see the android's background limitations here
Modification in Accepted Answer:
1: You have to invoke the service's startForeground() method within 5 seconds after starting the service. To do this, you can call startForeground() in onCreate() method of service.
public class AppService extends Service {
....
#Override
public void onCreate() {
startForeground(9999, Notification())
}
....
}
2: You must call startForegroundService() instead of startService() by checking API level from where you want to start the service.
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
context.startForegroundService(intent);
} else {
context.startService(intent);
}
This code work for me..
public class ServiceClass extends Service {
public static final int notify = 300000; //interval between two services(Here Service run every 5 Minute)
private Handler mHandler = new Handler(); //run on another Thread to avoid crash
private Timer mTimer = null; //timer handling
#Override
public IBinder onBind(Intent intent) {
throw new UnsupportedOperationException("Not yet implemented");
}
#Override
public void onCreate() {
if (mTimer != null) // Cancel if already existed
mTimer.cancel();
else
mTimer = new Timer(); //recreate new
mTimer.scheduleAtFixedRate(new TimeDisplay(), 0, notify); //Schedule task
}
#Override
public void onDestroy() {
super.onDestroy();
mTimer.cancel(); //For Cancel Timer
Log.d("service is ","Destroyed");
}
//class TimeDisplay for handling task
class TimeDisplay extends TimerTask {
#Override
public void run() {
// run on another thread
mHandler.post(new Runnable() {
#Override
public void run() {
Log.d("service is ","running");
}
});
}
}
}
In your manifest, where you declare your service, add:
android:process=":processname"
This lets the service run on a separate process and thus it will not be killed with the app.
You can then chose if you want to use foreground. It will show a persistent notification, but reduces the likelihood if the service being killed.
Further, if you want to create a continuously running service, use Service, NOT IntentService. IntentService stops when it is finished doing its action.
I am feeling strange behaviour with service when i close my app or my app is destoyed. Service starts from beggining means onStartCommand() method calls again. If service runs in background it should not be called again please help me why its happening
This is my service code
package gcmtutorial.androidbegin.com.socket;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.util.Log;
import android.widget.Toast;
/**
* Created by shuser on 21-07-2016.
*/
public class Services extends Service {
public static boolean status;
#Override
public IBinder onBind(Intent arg0) {
// TODO Auto-generated method stub
return null;
}
public class Hello implements Runnable{
public void run(){
synchronized (this){
int i=0;
while (i<100){
try {
wait(1000);
Log.e("Status:", "value "+i);
i++;
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
stopSelf();
}
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
// Let it continue running until it is stopped.
status = true;
Toast.makeText(this, "Service Started", Toast.LENGTH_LONG).show();
Thread thread = new Thread(new Hello());
thread.start();
return START_STICKY;
}
#Override
public void onDestroy() {
status = false;
super.onDestroy();
Log.e("Status:","Service Destroyed");
}
}
This is my MainActivity code
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Intent intent = new Intent(this, Services.class);
if (Services.status == true) {
Log.e("Check:","Service is Running");
}else {
Log.e("Check:","Service Will run now");
startService(intent);
}
}
}
Please help me why such thing is happening with service. I get Toast as well Service Started and LogCat also shows value from 0
Per START_STICKY:
if this service's process is killed while it is started (after returning from onStartCommand(Intent, int, int)), then leave it in the started state but don't retain this delivered intent. Later the system will try to re-create the service. Because it is in the started state, it will guarantee to call onStartCommand(Intent, int, int) after creating the new service instance;
If you'd like your Service to not automatically restart when your process is destroyed, return START_NOT_STICKY
I want to stop the service when I come to the activity . This is my activity code :
stopService(new Intent(this, Services_chat.class));
on call this on the mainactivity and in the oncreate method . so I certainly called .
this is my service code:
public class Services_chat extends Service {
#Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return null;
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
new Timer().scheduleAtFixedRate(new TimerTask() {
#Override
public void run() {
Log.v("this","caa");
}
}, 0, 1000);//put here time 1000 milliseconds=1 second
return START_NOT_STICKY;
}
#Override
public void onDestroy() {
super.onDestroy();
}
}
As you can seen I log and run this code every second , so after running my app and it calls for stopping service , it doesn't stop and it still runs .
How can I stop this service ?
thanks
write this method in Services_chat class.
#Override
public boolean stopService(Intent name) {
// TODO Auto-generated method stub
timer.cancel();
task.cancel();
return super.stopService(name);
}
If you are binding service via onBind() from MainActivity then call unBindService() method to stop service
If you are starting service via startService() from MainActivity then call stopService() or stopSelf()
Android system will try to stop service as soon as possible upon stop request from application
UPDATE :
Add code to stop timer in onDestroy() like :
#Override
public void onDestroy() {
super.onDestroy();
mTimer.cancel();
}
Make object of Timer instead of using Annonymous class Timer :
in onStartCommand() :
Timer mTimer = new Timer();
mTimer.scheduleAtFixedRate(new TimerTask() {
#Override
public void run() {
Log.v("this","caa");
}
},0,1000);
I, i have a service and i want that once it started, it performs is work
every 30 seconds. How can i do that?
Tnk
Valerio
Handler usage example for your Service (Bind part of the Service is missing):
import android.app.Service;
import android.os.Handler;
public class PeriodicService extends Service {
private Handler mPeriodicEventHandler;
private final int PERIODIC_EVENT_TIMEOUT = 30000;
#Override
public void onCreate() {
super.onCreate();
mPeriodicEventHandler = new Handler();
mPeriodicEventHandler.postDelayed(doPeriodicTask, PERIODIC_EVENT_TIMEOUT);
}
private Runnable doPeriodicTask = new Runnable()
{
public void run()
{
//your action here
mPeriodicEventHandler.postDelayed(doPeriodicTask, PERIODIC_EVENT_TIMEOUT);
}
};
#Override
public void onDestroy() {
mPeriodicEventHandler.removeCallbacks(doPeriodicTask);
super.onDestroy();
}
}
You can use a Timer.
I also found an example of another class called Handler (that is available for Android) that apparently should work better when using the UI.