Android Service doesn't Stop running - android

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!
}

Related

Background service pause and start again automatically on OREO

I have created a background service for registering SCREEN_ON and SCREEN_OFF intent to catch an event using broadcast receiver but some time due to unknown reason my service does not pass intent to my main application. For testing I have generated log file using ten second timer that it is my background service working or not, which I have attached below. I got a issue that my background service pause some time and start it automatically.
It is my background service
public class MyBackgroundService extends Service {
BroadcastReceiver receiver;
private static final String LOG_TAG = "MyBackgroundService";
#Override
public void onCreate() {
super.onCreate();
Timber.i("Foreground Service OnCreate");
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Timber.i("Start Foreground Service");
receiver = new ScreenStateReceiver();
registerReceiver(receiver, new IntentFilter(Intent.ACTION_SCREEN_ON));
registerReceiver(receiver, new IntentFilter(Intent.ACTION_SCREEN_OFF));
if (intent.getAction().equals(Constants.STARTFOREGROUND_ACTION)) {
Intent notificationIntent = new Intent(this, HomeActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0,
notificationIntent, 0);
Notification notification = new NotificationCompat.Builder(this)
.setContentTitle("text")
.setTicker("text")
.setContentText("text")
.setSmallIcon(R.drawable.logo_icon)
.setContentIntent(pendingIntent)
.setOngoing(true).build();
startForeground(Constants.NOTIFICATION_ID.FOREGROUND_SERVICE,
notification);
}
startTimer();
return START_STICKY;
}
#Override
public boolean onUnbind(Intent intent) {
Timber.i("Foreground Service onUnbind");
return super.onUnbind(intent);
}
#Override
public void onTaskRemoved(Intent rootIntent) {
Timber.i("Foreground Service onTaskRemoved");
super.onTaskRemoved(rootIntent);
}
#Override
public void onDestroy() {
stopForeground(true);
Timber.i("Foreground Service onDestroy");
stoptimertask();
super.onDestroy();
}
#Override
public IBinder onBind(Intent intent) {
// Used only in case of bound services.
return null;
}
private Timer timer;
private TimerTask timerTask;
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, 10000, 10000); //
}
/**
* it sets the timer to print the counter every x seconds
*/
public void initializeTimerTask() {
timerTask = new TimerTask() {
public void run() {
Timber.i("Timer");
}
};
}
/**
* not needed
*/
public void stoptimertask() {
//stop the timer, if it's not already null
if (timer != null) {
timer.cancel();
timer = null;
}
}
}
It is my broadcast Receiver
public class ScreenStateReceiver extends BroadcastReceiver {
public ScreenStateReceiver(){
}
#Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if(action.equals(Intent.ACTION_SCREEN_OFF)){
Timber.i("Screen OFF");
}
else if (intent.getAction().equals(Intent.ACTION_SCREEN_ON)) {
Timber.i("Screen ON");
}
}
}
Menifest,xml file declaration
<uses-permission android:name="android.permission.WAKE_LOCK"/>
<service android:name=".service.MyBackgroundService"/>
<receiver android:name=".receiver.ScreenStateReceiver" android:enabled="true" android:exported="true">
<intent-filter >
<action android:name="android.intent.action.SCREEN_OFF" />
<action android:name="android.intent.action.SCREEN_ON" />
</intent-filter>
</receiver>
I am starting Service using intent
Intent service = new Intent(getContext().getApplicationContext(), MyBackgroundService.class);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
service.setAction(Constants.STARTFOREGROUND_ACTION);
getContext().getApplicationContext().startForegroundService(service);
}
else{
service.setAction(Constants.MAIN_ACTION);
getContext().getApplicationContext().startService(service);
}
Here this picture of my log file
LOG FILE
using this log file you can see background service is stop and start automatically.
please help me resolve this issue.
There is a restriction for service in Oreo onward, We can start a service by calling startService() only when the application is in foreground. When you exit from the app (app is in background), then it has a window of several minute, in that app can run the service. At the end of window, app considered to be idle,that time system stop the background service. In order to achieve run a service even in background, either we have to implement foreground service or we have to use job scheduler etc.

Stop service and close app

My app use a background music service.
I have a button to quit my app but I can't find anything to close my app and my service.
I bind my service to my activity.
I tried:
unbindService(serviceConnection);
myService().stopSelf();
stopService(new Intent(this, MediaPlayer.class));
and absolutely nothing works !!! The service continues.
How can I do to destroy my service and how can I do to close my app ??
Tx
EDIT:
I use this in the onCreate method
Intent intent = new Intent(this, serviceClass);
bindService(intent, serviceConnection, BIND_AUTO_CREATE);
And in the MediaPlayer class
public class LocalBinder extends Binder {
public MediaPlayer getService() {
return MediaPlayer.this;
}
}
public IBinder onBind(Intent intent) {
Log.i(TAG, "service bound");
init();
return mBinder;
}
And that...
But I dont know if I really need to start the service. Bind the service already starts it
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
return START_NOT_STICKY;
}
Now I did this
#Override
public void onDestroy() {
player.stop();
super.onDestroy();
}
The onDestroy method works only if i unbind the service !
This doesnt work at all:
getService().stopSelf();
this.stopService(new Intent(this, MediaPlayer.class));
So, how can I stop the service and how can I close the app ?
This is what I do in my app. onDestroy() method from the activity will be called when you close your app.
private ServiceConnection musicServiceConnection = new ServiceConnection() {
#Override
public void onServiceConnected(ComponentName name, IBinder service) {
MusicService.LocalBinder binder = (MusicService.LocalBinder) service;
musicService = binder.getService();
musicService.setCallbacks(MainActivity.this);
musicServiceBound = true;
}
#Override
public void onServiceDisconnected(ComponentName name) {
Log.i(TAG, "MusicService service disconnected (unbinded)");
musicServiceBound = false;
}
};
#Override
protected void onStart() {
super.onStart();
Intent intent1 = new Intent(this, MusicService.class);
bindService(intent1, musicServiceConnection, Context.BIND_AUTO_CREATE);
}
#Override
protected void onDestroy() {
super.onDestroy()
if(musicServiceBound){
musicService.stopSelf();
unbindService(musicServiceConnection);
}
}
You wrote myService(), where you are creating another service using ().
For closing your app programmatically you can refer to this question.

Service will close if i close my application

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..

Foreground Service killed and not restarted

I have developed an app with Android BLE (bluetooth low enbergy)
It is working fine but when Android require more memory, my service is killed.
I am using a foreground service with a separate process.
< receiver android:name=".BluetoothLeService$MyReceiver"/>
< service android:name=".BluetoothLeService"
android:enabled="true"
android:exported="true"
android:process=":myservice"/>
I start my service from activity as:
startService(new Intent(this, BluetoothLeService.class));
and in my service:
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
SetNotification(0);
return START_STICKY;
}
but when my service got killed by OS, it doesn't restart.
I have tried closing all recent app but not getting any solution....
Is there any solution for this? Please help me. Any help will be appreciated. Thank you in advance.
--- Poweramp app isn't never killed --- why?
EDIT:
MainActivity in OnCreate:
...
startService(new Intent(this, BluetoothLeService.class));
In BluetoothLeService:
#Override
public void onDestroy() {
unregisterReceiver(mReceiver); // receiver for bt on and bt off
super.onDestroy();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
SetNotification(0);
return START_STICKY;
}
#Override
public IBinder onBind(Intent intent) {
return null;
}
public void SetNotification(int VerdeRosso){
if (VerdeRosso == 1) { // connected
remoteViews = new RemoteViews(getPackageName(), R.layout.notification_connesso);
}else {
remoteViews = new RemoteViews(getPackageName(), R.layout.notification_disconnesso);
}
mBuilder = new NotificationCompat.Builder(getApplicationContext());
mBuilder.setContent(remoteViews);
mBuilder.setSmallIcon(R.mipmap.ic_launcher);
startForeground(123, mBuilder.build()); // 123 รจ l'id a caso
}
#Override
public void onCreate() {
mBluetoothManager = (BluetoothManager) getSystemService(BLUETOOTH_SERVICE);
mBluetoothAdapter = mBluetoothManager.getAdapter();
//broadcaster = LocalBroadcastManager.getInstance(this);
IntentFilter filter = new IntentFilter(BluetoothAdapter.ACTION_STATE_CHANGED);
mReceiver = new MyReceiver();
registerReceiver(mReceiver, filter);
scanLeDevice(true);
}
--- EDIT 2
private final IBinder myBinder = new LocalBinder();
public class LocalBinder extends Binder {
BluetoothLeService getService() {
return BluetoothLeService.this;
}
}
....
#Override
public IBinder onBind(Intent intent) {
return myBinder;
}
You can check when the service is killed and restart it again by this way:
#Override
public void onLowMemory() {
//Send broadcast to the Activity to kill this service and restart it.
super.onLowMemory();
}
#Override
public void onTaskRemoved(Intent rootIntent)
{
//Send broadcast to the Activity to restart the service
super.onDestroy();
}
You can make 2 broadcast or only one of these above.

Keep alive Service in background?

For a demo I print a Toast after Evert 10 sec. using Service class.
It works fine, I'm getting the Toast after every 10 sec if I am on the Activity when I leave the app, Service is not giving the o/p.
But I want to that toast either I'll kill the App or back press Here is code snippet :
ServiceDemo.java
public class ServiceDemo extends Activity {
private Handler myHandler = new Handler();
private Runnable drawRunnable = new Runnable() {
#Override
public void run() {
as();
myHandler.postDelayed(this, 10000);
}
};
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_service_demo);
myHandler.postDelayed(drawRunnable, 10000);
startService(new Intent(this, MyService.class));
}
public void as(){
startService(new Intent(this, MyService.class));
}
#Override
protected void onPause() {
// TODO Auto-generated method stub
super.onPause();
}
}
Service.java
public class MyService extends Service {
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onCreate() {
Toast.makeText(this, "HOHO Service Created...", Toast.LENGTH_LONG).show();
}
#Override
public void onDestroy() {
}
#Override
public void onStart(Intent intent, int startid) {
Toast.makeText(this, "Service Started...", Toast.LENGTH_LONG).show();
}
}
Edit 1
moveTaskToBack(true);
I put this into the onBackPressed method I Service give the o/p if I am not on the screen but When I kill the App, Service not responding
I think you need to override onStartCommand instead of onStart()
like:
public int onStartCommand(Intent intent, int flags, int startid)
{
Toast.makeText(this, "Service Started...", Toast.LENGTH_LONG).show();
return Service.START_STICKY;
}
i think AlarmManager is what you want.
You have to user AlarmManager, here's an example : Alarm Manager Example
Your task will be executed even if the application is terminated.
But if the application is killed by the user, the Alarm will be canceled. See this discussion How to create a persistent AlarmManager

Categories

Resources