Good everyone, and welcome to the new section.
Our app's coming along.
We can save the timing data for the tasks.
But at the moment, we've got no way to view that data.
We need to add reports to the app,
then we'll need to test them and make sure they're accurate.
To do that, we're going to need far more data than we've got at the moment.
Rather than spending a lot of time tapping on our tasks
to create timings for them,
I'm going to create a class to generate timings for us.
That will let us create timings in the past,
so we'll end up with a lot of data for testing our reports.
We're going to create a new class,
but we don't want to distribute it with the release version of our app.
This class is only for our use, while we're testing the app.
One way to create classes for debug use only
is to put them in a debug package.
We can't create that when the project panes in android view though.
You'll have to switch the project view.
Expand app,
then src, and all our files so far
have been created inside the main folder.
If we put classes in a folder called debug,
they won't be compiled into the release version of our app.
Right click on src, and choose new directory.
Call it debug.
The name is important.
It has to match the name of our debug build.
You can also create a release directory
to include files only in the release build.
Everything in the main directory will be included in all builds,
and that's normally where we create all our java and Kotlin files.
Okay. Right click debug, and choose new directory again.
This one will be called java.
Everything else can now be done back in the android view.
We could do it here but the android view lets us see our package name
which we'll need in a minute. So I'll switch back to the android view.
Notice that we don't see main or debug now.
They're still there.
This view just doesn't show them.
Expand the java folder if it isn't already,
and right click.
We want to create a new package.
In the dialog that appears, we get a chance to choose main or debug.
So they are there. They just don't show up normally.
Choose the debug directory,
and click okay.
The reason I expanded the java folder a minute ago
is so that I can see my package name,
learnprogramming.academy.tasktimer.
I'm going to call this new package the same with
.debug at the end.
So the new package becomes
learnprogramming
.academy
.tasktimer.debug.
Right click the new debug package,
and choose new
Kotlin file class.
The name will be TestData
and change the kind to object before you click okay.
What we're going to do in this object
is loop through all the tasks in the database
and create random timing data for each one.
We'll create a random number of timing instances
and give each one a random start date and duration.
Unfortunately, a timing class doesn't allow the duration to be set.
The duration is calculated automatically.
I'll create a TestTiming class at the start of this file.
It's very simple.
The only code is to convert a date in milliseconds to seconds,
and we'll do that in the init block.
In the TestData object,
we'll create a generate test data function.
The only thing we'll need to pass to it is a content resolver
from the activity that uses this class.
We're going to use the random number generator from the math class
to generate random dates and durations.
All but one of the values we need will be ints,
and we can keep the code tidier by creating a
GetRandomInt function to generate our ints,
add it just after the generate test data function.
The math random function returns a random value from 0 to 1.
It can return 0 but the value will be less than 1.
You can check what the random function does
use,ctrl Q on a PC
or ctrl J On a mac to get the documentation.
Multiplying the result by 59, for example,
will give us a value from 0 to 58
point something.
If we round 58.9, we get 59.
So rounding the random number will give us a long
from 0 to 59.
That's exactly what we need when generating a random number of seconds.
We just have to cast the result to an int.
To generate the random timings,
I'll create a function called random date time.
We use that to create our test timing objects,
just add it after the GetRandomInt function.
We use our GetRandomInt function to generate a number from 0
to 59.
We can do the same for the minutes, hours and months.
Copy that line three more times, and change the variable name
and the multiplier.
That's just more of the same. The year's only a bit more complicated.
We want to produce values between our start year and end year.
To generate a random number between a range,
generate one between the difference.
NDM minus start year in our example
and then add it to the lower value in the range.
Okay. That's most of the date values.
The only thing missing is the day.
We had to generate a random month first
because we need to know how many days are in the month we're using.
As we need a calendar object anyway,
we can just create it now and ask it how many days there are.
If you're prompted for which package to import
choose the java.util package.
Check the documentation for the
get actual maximum function
if it's not obvious what it does.
It takes into account leap years
giving February 29 days when appropriate.
All right. We initialized a Gregorian calendar instance
for the first day of the month.
Now we need to set it to the correct date and time,
then return the time.
When we need a random start date for our data,
we can call this function to provide one.
The other thing we'll need to do is store our timing records in the database.
I'll create a function for that next after
random date time.
The code isn't very long,
and you may decide not to use a separate function for it,
but it keeps our main code a bit cleaner.
We've seen code like that before.
It just sets up the content values
then uses the content resolvers insert function
to store the record in the timings table.
You might need to import the TimingsContract class from your main project
if android studio doesn't import it automatically.
Okay. The main code goes in the GenerateTestData function.
I'll start by declaring some constants to avoid having
magic numbers in the code.
If values like 86400
and 500 suddenly appeared in the code,
anyone else reading it will wonder where they're from.
By making them named constants like this
it's much easier to see what they represent.
Next, we query the database for our tasks.
Once again that's code that we've seen before.
After calling the query function of the content resolver,
we'll loop over each of the rows in the cursor
and generate random timings records for each one.
Accept the import of our tasks contract class if you're prompted.
We don't want every task to have the same number of timings,
but we've got a random integer function that we can use.
It should be pretty obvious what we're doing here.
A few comments and our constant names
means we don't have to struggle to remember what the code's doing.
It's also easy to change it to create a different number of records if we wanted to.
Well, that's the class finished. In the next video, we'll test it.
We'll also look at what happens in the release build of our app.
I'll see you there.