2

I need to create a service that allow my application to work also when I close it, I’ve tried with STICKY_SERVICE but it doesn’t work... if anyone can decribe me how I can do this please answer this question.

It works with android 7.1 and it doesn’t with other versions

Here is my code...

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!");
    stoptimertask();
    Intent broadcastIntent = new Intent("RestartSensor");
    sendBroadcast(broadcastIntent);
}

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

This is my service Restarter...

public class SensorRestarterBroadcastReceiver extends BroadcastReceiver {

@Override
public void onReceive(Context context, Intent intent) {
    Log.i(SensorRestarterBroadcastReceiver.class.getSimpleName(), "Service Stops");
    context.startService(new Intent(context, SensorService.class));
}
}

And the mainClass

public class MainActivity extends AppCompatActivity {

Intent mServiceIntent;
private SensorService mSensorService;

Context ctx;

public Context getCtx() {
    return ctx;
}


@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    ctx = this;
    setContentView(R.layout.activity_main);
    mSensorService = new SensorService(getCtx());
    mServiceIntent = new Intent(getCtx(), mSensorService.getClass());
    if (!isMyServiceRunning(mSensorService.getClass())) {
        startService(mServiceIntent);
    }
}

private boolean isMyServiceRunning(Class<?> serviceClass) {
    ActivityManager manager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
    for (ActivityManager.RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE)) {
        if (serviceClass.getName().equals(service.service.getClassName())) {
            Log.i ("isMyServiceRunning?", true+"");
            return true;
        }
    }
    Log.i ("isMyServiceRunning?", false+"");
    return false;
}


@Override
protected void onDestroy() {
    stopService(mServiceIntent);

    Log.i("MAINACT", "onDestroy!");
    super.onDestroy();
}
}

This restartthe service correctly but after 3/4 seconds it die.

I've added this to my manifest

<service
        android:name=".SensorService"
        android:enabled="true" >
    </service>

    <receiver
        android:name=".SensorRestarterBroadcastReceiver"
        android:enabled="true"
        android:exported="true"
        android:label="RestartServiceWhenStopped">
        <intent-filter>
            <action android:name="RestartSensor"/>
        </intent-filter>
    </receiver>

1 Answers1

2

Add the following code to your sensor service and edit as per your need. You need to bind the sticky service to a notification to keep the service alive and start in the foreground.

@Override public void onCreate() { super.onCreate();

    Intent notifIntent = new Intent(this, SensorService.class);
    PendingIntent pi = PendingIntent.getActivity(this, 0, notifIntent, 0);

    Notification notification = new NotificationCompat.Builder(this)
            .setSmallIcon(R.drawable.smslogo_100x100)
            .setColor(ContextCompat.getColor(this, R.color.colorAccent))
            .setContentTitle(getResources().getString(R.string.app_name))
            .setContentText("Running")
            .setContentIntent(pi)
            .build();
    startForeground(101010, notification);

}

This will rectify the issue you are facing and the service will run forever.

Tarun Kumar
  • 498
  • 5
  • 16
  • *this will prevent the service die if it is due to Android OS* - no it won't – Tim Feb 15 '18 at 10:22
  • But the notification is must to keep the service alive. – Tarun Kumar Feb 15 '18 at 10:32
  • you claim that adding that permission will prevent the service from getting killed by the OS. That is simply not true – Tim Feb 15 '18 at 10:40
  • Edited my Answer buddy. Thanks for the information @TimCastelijns – Tarun Kumar Feb 15 '18 at 10:49
  • 1
    now the OP wants to create a backgroundservice, and you suggest to make it a foreground service. That's not really an answer – Tim Feb 15 '18 at 10:53
  • "I need to create a service that allow my application to work also when I close it, I’ve tried with STICKY_SERVICE but it doesn’t work.." there's nowhere in the question stating background service and according to me this is the thing what he is looking for. Let's leave the commitment to the OP. – Tarun Kumar Feb 15 '18 at 11:32
  • But it works with android 7.1 and it doesn’t with android 5.0 or 7.0 – Alesandro Giordano Feb 15 '18 at 11:40
  • "there's nowhere in the question stating background service " - yeah ok. It's not like the question is titled "how can I create a background service" or anything – Tim Feb 15 '18 at 11:53
  • @AlesandroGiordano did you checked your code by implementing this oncreate method in your code? Did it work? – Tarun Kumar Feb 15 '18 at 13:22