1

I am currently resuming a project I had been working on, and starting from scratch to recreate it.
However, upon creating a Service class, I noticed something - in my old project, a method inside the Service called onStartCommand contains all of the code that needs to be fired, whereas in my new project when I create a Service class, this method is nowhere to be found.

- Do I need to manually ADD this "onStartCommand" method to contain my service code?

- If not, where exactly would my code go? It seems in my "old" project's code, I completely comment-block public TimerService, and pass null into IBinder, and create onStartCommand etc instead.. and I can't quite figure out why.

- While i'm here, can someone please double-check my CountdownTimer code below? and if it's correct, should I be putting it inside of a Thread?


When I create a new Service Class, it looks like this:

public class TimerService extends Service {

    public TimerService() {

    }

    @Override
    public IBinder onBind(Intent intent) {
        // TODO: Return the communication channel to the service.
        throw new UnsupportedOperationException("Not yet implemented");

    }

}


However in my old Project, my Service class looks like this:

public class TimerService extends Service {

/*
public TimerService() {

}
*/

@Override
public IBinder onBind(Intent arg0) {
    return null;
}

@Override
public int onStartCommand(final Intent intent, int flags, int startId) {

    intent.getStringExtra("TIMER_VALUE");

    String string_timerValue;
    string_timerValue = intent.getStringExtra("TIMER_VALUE");

    long long_timerValue;
    long_timerValue = Long.parseLong(String.valueOf(string_timerValue));

    // I DO NOT WANT ANY TICK VALUE, SO GIVE IT FULL TIMER VALUE
    long long_tickValue;
    long_tickValue = Long.parseLong(String.valueOf(string_timerValue));

    new CountDownTimer(long_timerValue, long_tickValue) {

        public void onTick(long millisUntilFinished) {
            // DO NOTHING
        }

        public void onFinish() {

            Toast.makeText(TimerService.this, "TIMES UP", Toast.LENGTH_LONG).show();

            stopService(intent);

        }
    }.start();

    return START_STICKY;

    // END OF onStartCommand
}

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

    Toast.makeText(this, "Service Destroyed", Toast.LENGTH_LONG).show();
}

// END OF ENTIRE SERVICE CLASS
}


THANK YOU!!

Studio2bDesigns
  • 578
  • 5
  • 12

1 Answers1

0

Do I need to manually ADD this "onStartCommand" method to contain my service code?

Yes.

can someone please double-check my CountdownTimer code below?

Only create a service when one is absolutely necessary. It is unclear why this service is necessary.

Beyond that:

  • Use stopSelf(), not stopService(), to stop a service from inside that service.

  • Examining Intent extras and using START_STICKY is not a good combination. START_STICKY says "if you terminate my process to free up system RAM, please restart my service when possible, but pass null for the Intent". That will cause your service to crash with a NullPointerException.

CommonsWare
  • 986,068
  • 189
  • 2,389
  • 2,491
  • Thank you for the insight.. Well my objective is to have a broadcast listener, which when fired, brings up a dialog box activity, which the user enters a value into a edittext and presses OK.. The activity then disappears, and runs the timer in the background, and when the time expires, a new activity opens/code fires.. I assumed a Service would be needed to do the Timer in the background. If not, how else would I go about it, as not to get killed by the system while it's in the background? Isn't background processes what a Service is used for? Also, if not START_STICKY, then what Flag to use? – Studio2bDesigns Jan 16 '19 at 04:33
  • @Studio2bDesigns: "how else would I go about it" -- `AlarmManager`, most likely. "as not to get killed by the system while it's in the background?" -- you *want* to be "killed by the system". **Only have a service running when it is actively delivering value to the user**. Sitting around watching the clock tick is not actively delivering value to the user. – CommonsWare Jan 16 '19 at 12:07
  • So just to clarify, you're suggesting **instead** of closing the Activity and starting a Service to run the AlarmManager, I should simply put the AlarmManager code within the actual **Activity**, directly prior to closing the Activity? I wasn't sure if the AlarmManager would remain in action if I were to close the Activity, that's why I was starting a Service to do it in the background. **Are you saying the Activity can be closed while still running the AlarmManager code in the background?** Also, for future reference, what FLAG **would I have** used instead of START_STICKY? – Studio2bDesigns Jan 17 '19 at 19:24
  • @Studio2bDesigns: "I wasn't sure if the AlarmManager would remain in action if I were to close the Activity" -- the point of `AlarmManager` is to give your app control at a requested time, whether you have a running process right then or not. Note that the time is not necessarily precise, given limits imposed by Doze mode and app standby on Android 6.0+ devices. "Also, for future reference, what FLAG would I have used instead of START_STICKY?" -- it's not that simple. The closest simple thing is to get rid of the `Intent` extras, in which case `START_STICKY` is user-hostile but would work. – CommonsWare Jan 17 '19 at 19:29
  • You said the AlarmManager isn't precise - but I need it to fire my code after the exact amount of Minutes the user had entered into an EditText.. So is AlarmManager not the best solution then? – Studio2bDesigns Jan 17 '19 at 19:45
  • @Studio2bDesigns: Basically, what you want isn't something that Android offers very well, due to power concerns. If the duration of the delay is under an hour, then `AlarmManager` should be OK. The only thing that is fairly precise for longer delays is `setAlarmClock()` on `AlarmManager`, and that is supposed to be used by alarm clock apps -- I do not know if users will consider your app to be one or not. – CommonsWare Jan 17 '19 at 19:53
  • Thank you so much for the kind and helpful words of advice. My last question would be, should I surround the AlarmManager code within a Thread? Also I posted a separate question this morning, but no replies yet, if you're feeling extra helpful ;) – Studio2bDesigns Jan 18 '19 at 00:31
  • @Studio2bDesigns: "should I surround the AlarmManager code within a Thread?" -- I do not know what "the AlarmManager code" is. If you mean calling APIs on `AlarmManager`, that does not need to be done on a background thread. If you mean the work that is triggered by `AlarmManager`... if it involves any sort of I/O (disk, database, network) or a lot of calculations, then yes. That is not unique to `AlarmManager`, though. – CommonsWare Jan 18 '19 at 00:42