hello and welcome to another android studio and kotlin tutorial my name is cal and in today's
tutorial we're going to be building a simple timer our timer we're going to put onto a service so
that means that it can run in the background so it's not running on the main ui thread and that
has a lot of advantages mainly being number one if you rotate the screen then the time will continue
to count number two if you put the app to the background and you do something else and you
come back the timer should continue to count as expected so that's what we're going to be looking
at today we're going to be looking at timers as well as services but yeah let's jump into it
cool so creating a new android studio project empty activity i'm going to call this timer
on service tutorial our programming language is kotlin and just hit finish to create the android
studio project firstly we're going to head into our main activity and just work on a simple layout
so i'm going to change the parent layout to a linear layout setting its orientation to vertical
and then with our textview we're going to remove the constraint layout stuff we're going to change
the text to three sets of zeros and then we're just going to give our textview a little bit of
padding we're going to set the text color to black as well as setting the text size to 60sp we're
going to set the text alignment to center and the width we're going to give it match parent and then
we're just going to give it an id just calling this one time text view below our text view
we're going to create a constraint layout width match parent height wrap content padding 1080p
and then inside our constraint layout we're going to add in a material button width and height of
wrap content i'm going to give it a text of start so it's going to be our start stop button and then
for its constraints i actually find it easier to do this in the design view with constraint layout
so i'm just clicking to the side because i want to make it sit to the left of our parent and then i'm
just going to copy and paste down that material button rename the text of this one to reset i'm
going to set that one to sit in the right of our container and then we're just going to give both
of those buttons an id so reset button and start stop button and then just making sure that they
both take up an even amount of space so we just got one button to the left that's our start stop
button and our reset button to the right and for whatever reason i had to type in the constraint
end to start of our reset button but yeah that's looking good we've got two evenly spaced buttons
cool so next we're going to add in some icons for our buttons i'm just going to right click and say
new vector asset and then select this play button so we want to have a play button a pause button
and a restart button to right click a new vector asset and that should just create a new vector
asset inside our drawable folder and you can see if we open up this folder here and open up the
pause it's just created this xml file for us and now we can go into our material button and just
say app icon is equal to our play arrow and for our reset we're going to assign it to our replay
cool so that wraps up our layout next we're going to head into our build gradle and enable view
bindings so we just need to type build features and then view binding is equal to true in previous
kotlin tutorials i've been using synthetics even though they're depreciated so i thought i'd have
a go today at using view bindings anyway getting back on track now we're just going to right click
and create a new kotlin file i'm going to call this timer service our timer service class is
going to extend service i'm just going to hit alt enter to import the service class if we click on
this error message it's saying we need to override the on bind function but we don't actually want to
do anything here so we're just going to return null and below that i'm just going to declare a
timer variable just calling it timer we're going to create a companion object this is just to store
a couple of strings that we want to reuse the first one i'm calling timer updated and this
can really be whatever you like so need a second string so i'm just going to duplicate that line
i'm just going to call this one time extra then we're going to override the on start command
function we're just going to say value time is equal to intent get double extra we're going to
use our time extra string and a default value of zero and i realize now the timing of this might
be confusing but essentially later in the tutorial we're going to be passing from our main activity
the time variable via an intent to our timer service cool but anyway next we're going to say
timer schedule at fixed rate we're going to create a new time task which we're going to pass our time
our delay is going to be 0 and our period is going to be a thousand and that's in milliseconds so
that's one second we're going to return the flag start not sticky also we're going to remove the
question mark from intent to make it non-optional so next we need to create our time task i'm going
to create a private inner class calling it time task and it takes a private variable called time
which is of type double and our time task extends timer task we're going to override the function
run inside here we're going to create a new intent we're going to pass it our timer updated string
we're going to say time plus plus so adding one to time intent dot put extra we're going to give it
our time extra as well as our time double variable and then we're going to say send broadcast
giving it our intent and so the final thing we need to do in our timer service is just override
the on destroy function and just say timer cancel so when the service is destroyed we want to stop
our timer from counting cool so we're going to head back into our main activity kotlin we're
going to declare a private later net variable calling it binding which is of type activity main
binding and then below our on create we're going to say our binding is equal to our activity main
binding inflate giving it layout inflator and then we're going to set our content view to our binding
dot root and now we can call our binding and just referencing our start stop button we're going to
set an on click listener which is just going to call a function we're going to call it start stop
timer and we're going to create that just below now i'm going to duplicate that line referencing
our reset button creating another function calling it reset timer then at the top we're going to
declare a variable calling it timer started which is equal to false we're going to create
another variable which is a later net variable calling it service intent which is of type intent
and then one more variable just calling it time initialized to 0.0 inside our create we're going
to initialize our service intent so it's equal to an intent just giving an application context
and our timer service class and then below that we're going to register a receiver a receiver
requires a broadcast receiver which we haven't created yet so i'm just calling that update time
and an intent filter which we're just going to say intent filter and giving it our timer service
timer updated so that's just our timer updated string from our timer service class so we need
to create our update time broadcast receiver so i just said private val update time which is of
type broadcast receiver is equal to object of broadcast receiver and that's just automatically
over in the on receive function our intent rename that to intent and our context to context and
then i'm going to say time is equal to our intent get double extra giving it our timer service time
extra string and a default value of 0.0 we're going to say our time text view text is equal
to our get time string from double so we haven't created this function yet either but we're just
going to pass it through our double click on the error message and create that function just below
and it's going to return a string we're going to say our result int is equal to time rounded to an
int and then we're going to say our hours is equal to our results in percentage sign 86 400 divided
by 3600 basically what we're doing here is we're taking our time double and we're turning it into
the hours minutes and seconds components which we can then pass to another function which we're
going to call make time string and this function is just going to format our hours minutes
and seconds into a readable string that we can then put into our time text view so i'm just going
to rename this to min and seconds just to make it a little bit shorter pull to string format giving
it a percentage sign 0 to d so to two decimal places and then the little semicolon and then 0
2 d three times and then we just need to pass it in our hours minutes and seconds then i'm
going to copy and paste our reset timer and start stop timer and just put them a little bit higher
inside our start stop timer we're going to say if our timer is started we're going to stop the timer
otherwise we're going to start our timer and we're just going to create two more functions so
a stop timer function and a start timer function and then in our start timer we're just going to
say service intent put extra giving it our time extra string from our timer service as well as
our time and then we're going to say start service giving it our service intent now we need to make
our start stop button look like a stop button that stop button text is equal to stop and just
changing the icon to pause and then we're just going to say timer started is equal to true cool
so we can copy everything from our start timer into our stop timer and we want to do the opposite
for each of those things so we're going to say stop service giving it our service intent we're
going to change the text to start and the icon to the play arrow and timer started is equal to false
now inside our reset timer we're just going to call our stop timer function set time back to 0.0
and we're going to set our time textview text equal to our get from time string from double
and just giving it our time cool and then last and most importantly we just need to head into
our android manifest and we need to declare our service and so inside our application tag we're
just going to say service giving it a name of our timer service nice so let's build and run this
now you can see that we can start the timer and it starts counting up from zero you can
pause or stop the timer can reset it but yeah the main thing about this is that it is running on a
service so it's independent from the ui thread so i don't think the emulator quite does it justice
but you could rotate your screen if this was on a real device and the timer will continue to count
i hope you enjoyed this kotlin and android studio tutorial and i'll catch you guys in the next one