I am calling service from the application class, If I close the app or remove from currently running apps, then the service will destroy automatically,I didn't written any code in on Destroy() method
to call service here is code :
Intent syncIntent = new Intent(this, ScanBLE_Service.class);
this.startService(syncIntent);
here is the code of service class
public class ScanBLE_Service extends IntentService {
public ScanBLE_Service() {
super(ScanBLE_Service.class.getName());
// TODO Auto-generated constructor stub
mHandler = new Handler();
}
#Override
protected void onHandleIntent(Intent intent) {
// TODO Auto-generated method stub
demo();
}}
private void demo() {
mHandler.removeCallbacksAndMessages(null);
mHandler.postDelayed(new Runnable() {
#Override
public void run() {
Toast.makeText(getApplicationContext(), "Demoooo", Toast.LENGTH_SHORT).show();
demo();
}
}, 5000
);
}
You should use Service, not IntentService. Extend the Service class and override onStartCommand method, then do the calculations in this method
To run your service even after the application is destroyed you need to do the following.
extend your service with Service classs
return START_STICKY in onStartCommand()
override onTaskRemoved(refer the following example code).
public class MyIntentService extends Service
{
Timer mTimer;
#Override
public void onCreate()
{
super.onCreate();
mTimer = new Timer();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId)
{
mTimer.schedule(mTimerTask, 1000, 5000);
return START_STICKY;
}
#Nullable
#Override
public IBinder onBind(Intent intent)
{
return null;
}
TimerTask mTimerTask = new TimerTask()
{
#Override
public void run()
{
System.out.println("timer task run");
}
};
#Override
public void onTaskRemoved(Intent rootIntent)
{
System.out.println("onTaskRemoved");
Intent restartServiceIntent = new Intent(getApplicationContext(), this.getClass());
restartServiceIntent.setPackage(getPackageName());
PendingIntent restartServicePendingIntent = PendingIntent.getService(getApplicationContext(), 1, restartServiceIntent, PendingIntent.FLAG_ONE_SHOT);
AlarmManager alarmService = (AlarmManager) getApplicationContext().getSystemService(Context.ALARM_SERVICE);
alarmService.set(AlarmManager.ELAPSED_REALTIME, SystemClock.elapsedRealtime() + 1000, restartServicePendingIntent);
super.onTaskRemoved(rootIntent);
}
}
Yes, the service will be closed if application is closed. One situation, when the service will not be closed in to have a constant Notification on notifications screen.
More here
The normal behavior is that the service will keep running even if the application is closed, because it's separated from the application and runs in background, unless you call stopSelf() or stopService(x,x) it should keep running..
PS: there's another type of service which is IntentService (extends IntentService rather then Service) and this will stop automatically once the code in onHandleIntent() is executed..
Related
I am using Background service in our application:
public class BackgroundService extends Service {
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
handler.postDelayed(r, 5000);
return START_STICKY;
}
Handler handler = new Handler();
Runnable r = new Runnable() {
#Override
public void run() {
handler.postDelayed(r, 5000);
Log.d("arpit", "connected");
}
};
#Override
public void onDestroy() {
super.onDestroy();
}
#Override
public void onTaskRemoved(Intent rootIntent) {
super.onTaskRemoved(rootIntent);
Intent restartServiceIntent = new Intent(Appclass.getInstance().getApplicationContext(), this.getClass());
restartServiceIntent.setPackage(getPackageName());
PendingIntent restartServicePendingIntent = PendingIntent.getService(Appclass.getInstance()
.getApplicationContext(), 1, restartServiceIntent, PendingIntent.FLAG_ONE_SHOT);
AlarmManager alarmService = (AlarmManager) getApplicationContext().getSystemService(Context.ALARM_SERVICE);
alarmService.set(AlarmManager.ELAPSED_REALTIME, SystemClock.elapsedRealtime() + 1000, restartServicePendingIntent);
}
}
It's working fine, and also works if I close or kill the application.
but on some devices like oppo A33F , Lenovo Vibe K5 etc push notification is not getting through, and also the service class is destroyed after killing the application. I checked in running application section of device but my application is not showing by which means service class is destroyed, after killed the application. How can I resolved this and keep my service continuously running even after the app is killed.
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 create a service and put it in the foreground with a notification. In the service I have a timer that just prints "SERVICE STILL RUNNING" to let me know the service is still alive. When I close the app, the OnDestroy() of the service is called but the timmer keeps printing "SERVICE STILL RUNNING" why is that? I put the service in the foreground by calling showNotification(). If I don't call showNotification() and close the app the service gets destroyed and the timmer stops printing "SERVICE STILL RUNNING". How can I have the service in the foreground and kill it correctly when the app is closed. The memory monitor continues to show the memory usage even after the app is closed. If I dont put the service in the foreground and close the app, the memory monitor stops.This problem only happens and android 6.0.
MainActivity:
public class MainActivity extends Activity {
Intent service;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
service = new Intent(MainActivity.this, MyService.class);
// starting Client service
service.setAction("START");
startService(service);
}
#Override
protected void onDestroy() {
super.onDestroy();
service.setAction("STOP");
stopService(service);
}
}
Service:
public class MyService extends Service {
Timer timer;
public MyService() {
}
#Override
public IBinder onBind(Intent intent) {
// TODO: Return the communication channel to the service.
throw new UnsupportedOperationException("Not yet implemented");
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
//return super.onStartCommand(intent, flags, startId);
if(intent !=null)
{
if(intent.getAction().equals("START"))
{
showNotification();
} else if(intent.getAction().equals("STOP"))
{
stopForeground(true);
stopSelf();
}
}else
{
//stopForeground(true);
//stopSelf();
}
return START_STICKY;
}
#Override
public void onCreate() {
super.onCreate();
timer = new Timer();
timer.scheduleAtFixedRate(new TimerTask() {
#Override
public void run()
{
Log.d("","SERVICE STILL RUNNING");
}
},1*1000,5*1000);
}
private void showNotification() {
Intent notificationIntent = new Intent(this, MainActivity.class);
notificationIntent.setAction("new");
notificationIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
| Intent.FLAG_ACTIVITY_CLEAR_TASK);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0,
notificationIntent, 0);
Bitmap icon = BitmapFactory.decodeResource(getResources(),
R.drawable.ic_launcher);
Notification notification = new NotificationCompat.Builder(this)
.setContentTitle("Title")
.setTicker("Test")
.setContentText("testing")
.setSmallIcon(R.drawable.ic_launcher)
.setLargeIcon(Bitmap.createScaledBitmap(icon, 128, 128, false))
.setContentIntent(pendingIntent)
.setOngoing(true).build();
startForeground(101, notification);
}
#Override
public void onDestroy() {
super.onDestroy();
Log.d("","SERVICE HAS BEEN DESTROYED!!!");
}
}
Try adding this on you Service's onDestroy
#Override
public void onDestroy() {
super.onDestroy();
timer.cancel();
timer = null;
stopForeground(true);//Add this. Since stopping a service in started in foreground is different from normal services.
Log.d("","SERVICE HAS BEEN DESTROYED!!!");
}
EDIT
On your Activity's onDestroy method
#Override
protected void onDestroy() {
super.onDestroy();
service.setAction("STOP");
service.executeStopForeground();
stopService(service);
}
Then add this method on your service:
public void executeStopForeground()
{
stopForeground(true);
}
Use inside your service code:
#Override
public void onDestroy() {
stopForeground(true);
super.onDestroy();
System.exit(0); //We terminate the app!
}
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 am building an android app and when it is running I need to make a call to the my web server at each minute if the user is connected to a certain network.
I plan to use a service to make that call but how do I call it at each minute?.
I think i need to use alaarm manager but where do I initalize it? in my start activity? I only need to execute the service when my app is running.
Thanks for your help.
If you want to call server only if app is running then no need to use alarm manager. there are other options like
CoundDownTimer
Thread
I prefer CoundownTimer in that scenario and you can use like this
CountDownTimer countDownTimer = new CountDownTimer(1000000, 60 * 1000) {
#Override
public void onTick(long millisUntilFinished) {
// Do something on a tick.
}
#Override
public void onFinish() {
// Do something, maybe?
this.start();
}
};
countDownTimer.start();
Try this ::
You can call this timer in your activity where you want it
private Timer autoUpdate;
#Override
public void onResume() {
super.onResume();
autoUpdate = new Timer();
autoUpdate.schedule(new TimerTask() {
#Override
public void run() {
runOnUiThread(new Runnable() {
public void run() {
//call your service from here
}
});
}
}, 0, 60000);//set time interval according to your requirement
}
Feel free to ask if you have any query :)
in Activity:
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
TestAlarmMessageReceiver almesr = new TestAlarmMessageReceiver(this, time);
}
BroadcastReceiver:
public class TestAlarmMessageReceiver extends BroadcastReceiver {
public TestAlarmMessageReceiver() {
}
public TestAlarmMessageReceiver(Context context, int timeout) { //timeout in seconds
AlarmManager alarmMgr = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(context, TestAlarmMessageReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, intent,
PendingIntent.FLAG_CANCEL_CURRENT);
Calendar time = Calendar.getInstance();
time.setTimeInMillis(System.currentTimeMillis());
alarmMgr.setRepeating(AlarmManager.RTC_WAKEUP, time.getTimeInMillis(),
timeout*60*1000, pendingIntent);
}
#Override
public void onReceive(Context arg0, Intent arg1) {
arg0.startService(new Intent(arg0, TestMessageService.class));
}
}
Service:
public class TestMessageService extends Service {
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
messageUpdateTask();
return super.onStartCommand(intent, flags, startId);
}
private void messageUpdateTask(){
GetMessagesUpdateAsyncTak getMessUpd = new GetMessagesUpdateAsyncTak();
getMessUpd.execute(this);
}
}
Call your web server using AsynTask http://developer.android.com/reference/android/os/AsyncTask.html
In onPost method in AsynTask class wait for one minute and call AsynTask.
You can call AsynTask by using below code :
BLSyncingProcedure objSyncingProcedure=new BLSyncingProcedure();
objSyncingProcedure.execute(HomeScreen.this);
BLSyncingProcedure is your AsynTask class name.