1
00:00:04,530 --> 00:00:06,510
Alright so at the end of the last

2
00:00:06,510 --> 00:00:08,309
video, well actually the one before, not

3
00:00:08,309 --> 00:00:10,889
including the build update files, well

4
00:00:10,889 --> 00:00:12,599
actually the end of the video prior to

5
00:00:12,599 --> 00:00:14,280
that, because of course the last video I

6
00:00:14,280 --> 00:00:16,340
talked, I showed you how to actually update the

7
00:00:16,340 --> 00:00:19,290
Kotlin Runtime. But in that previous

8
00:00:19,290 --> 00:00:21,270
video we talked about, we were going to

9
00:00:21,270 --> 00:00:23,910
add the getId function to our Tasks

10
00:00:23,910 --> 00:00:25,890
Contract class, and obviously you can see

11
00:00:25,890 --> 00:00:27,269
here we've got an error there because

12
00:00:27,269 --> 00:00:28,740
that function doesn't exist at the

13
00:00:28,740 --> 00:00:30,420
moment. Now there's a few other things we

14
00:00:30,420 --> 00:00:32,369
need to do in there, so I'm going to do

15
00:00:32,369 --> 00:00:34,500
them all together. Now that we understand

16
00:00:34,500 --> 00:00:36,719
how URIs will be used, this should

17
00:00:36,719 --> 00:00:38,430
make more sense for you. So I'm going to

18
00:00:38,430 --> 00:00:41,840
start by opening up my TasksContract

19
00:00:41,840 --> 00:00:44,940
class, and you want to make sure that

20
00:00:44,940 --> 00:00:46,620
your cursor, when we start typing, is

21
00:00:46,620 --> 00:00:48,930
above the object Columns. Don't be typing

22
00:00:48,930 --> 00:00:50,129
in there because you'll get a weird error

23
00:00:50,129 --> 00:00:51,539
if you do that. So I'm going to put a

24
00:00:51,539 --> 00:00:52,920
comment here about what we're doing.

25
00:00:52,920 --> 00:00:55,590
We're creating a public constant here, of

26
00:00:55,590 --> 00:00:57,090
CONTENT_URI so that

27
00:00:57,090 --> 00:00:58,710
other classes will be able to use this

28
00:00:58,710 --> 00:01:02,489
URI for our Tasks table. So this is

29
00:01:02,489 --> 00:01:06,300
going to be "The URI to access the

30
00:01:06,300 --> 00:01:13,290
Tasks table". And in terms of the, what I'm

31
00:01:13,290 --> 00:01:15,869
typing here, we're going to type val and it's

32
00:01:15,869 --> 00:01:21,780
going to be CONTENT_URI: Uri

33
00:01:21,780 --> 00:01:26,330
is equal to Uri.with

34
00:01:26,330 --> 00:01:29,850
AppendedPath, in parentheses - we're going to

35
00:01:29,850 --> 00:01:30,900
ignore that error that appeared up

36
00:01:30,900 --> 00:01:32,460
before there with the IDE in the bottom

37
00:01:32,460 --> 00:01:34,320
right hand corner - CONTENT_

38
00:01:34,320 --> 00:01:36,210
AUTHORITY_URI. There should have been

39
00:01:36,210 --> 00:01:38,130
a comma there, so TABLE_NAME.

40
00:01:38,130 --> 00:01:41,490
Okay, so the CONTENT__AUTHORITY

41
00:01:41,490 --> 00:01:43,950
_URI, that's coming

42
00:01:43,950 --> 00:01:46,439
from the AppProvider file. Now once

43
00:01:46,439 --> 00:01:47,700
again we didn't have to concatenate

44
00:01:47,700 --> 00:01:50,850
strings to create the CONTENT__URI from

45
00:01:50,850 --> 00:01:53,430
the CONTENT__AUTHORITY and our TABLE_NAME.

46
00:01:53,430 --> 00:01:55,860
The Uri class provides several

47
00:01:55,860 --> 00:01:57,720
methods for dealing with URIs. In

48
00:01:57,720 --> 00:02:00,600
here we're creating a new URI with a

49
00:02:00,600 --> 00:02:03,060
path appended, using the withAppended

50
00:02:03,060 --> 00:02:05,850
Path method from the Uri class. Now

51
00:02:05,850 --> 00:02:08,039
CONTENT_URI will be used

52
00:02:08,039 --> 00:02:11,008
by external classes, including different

53
00:02:11,008 --> 00:02:13,230
apps that use our content provider to

54
00:02:13,230 --> 00:02:16,440
refer to our Tasks table. Alright, so the

55
00:02:16,440 --> 00:02:17,819
other thing we decided to put in this

56
00:02:17,819 --> 00:02:18,300
class

57
00:02:18,300 --> 00:02:20,910
is the getId method. Now that will be

58
00:02:20,910 --> 00:02:24,330
used to extract the ID from a URI, and it

59
00:02:24,330 --> 00:02:25,620
also makes sense to include the

60
00:02:25,620 --> 00:02:28,230
complimentary method, buildUriFrom

61
00:02:28,230 --> 00:02:29,730
Id, to do the opposite.

62
00:02:29,730 --> 00:02:32,610
It'll add an ID to a CONTENT_

63
00:02:32,610 --> 00:02:33,990
URI. So I'm going to add these

64
00:02:33,990 --> 00:02:36,090
functions we're about to write, below the

65
00:02:36,090 --> 00:02:37,800
definitions for the Columns object at

66
00:02:37,800 --> 00:02:41,490
the end of the class. So I'll start by fun get

67
00:02:41,490 --> 00:02:44,940
Id parentheses uri :

68
00:02:44,940 --> 00:02:46,830
Uri. Then a right parentheses

69
00:02:46,830 --> 00:02:52,050
then a : Long, and we'll add our left

70
00:02:52,050 --> 00:02:53,460
and right curly braces, and we want a

71
00:02:53,460 --> 00:02:59,370
return ContentUris.parseId, in

72
00:02:59,370 --> 00:03:02,010
parentheses uri, which of course was

73
00:03:02,010 --> 00:03:04,590
the argument passed in this method. Then

74
00:03:04,590 --> 00:03:05,550
the second one was that other

75
00:03:05,550 --> 00:03:08,000
complimentary method I talked about: fun

76
00:03:08,000 --> 00:03:12,420
buildUriFromId. The argument for

77
00:03:12,420 --> 00:03:15,030
that one is an ID of type long, id :

78
00:03:15,030 --> 00:03:17,700
Long, and that returns a Uri. So

79
00:03:17,700 --> 00:03:21,030
: Uri left and right curly braces, and

80
00:03:21,030 --> 00:03:24,170
we're going to return ContentUris

81
00:03:24,170 --> 00:03:27,930
dot withAppendedId, in lower case with,

82
00:03:27,930 --> 00:03:30,090
and in parentheses it's going to be

83
00:03:30,090 --> 00:03:33,950
CONTENT_URI comma id.

84
00:03:33,950 --> 00:03:35,850
So I've done something slightly

85
00:03:35,850 --> 00:03:38,100
different with the buildUriFrom

86
00:03:38,100 --> 00:03:40,470
Id function. Now I could have used the

87
00:03:40,470 --> 00:03:42,480
withAppendedPath function of the Uri

88
00:03:42,480 --> 00:03:44,940
class, like we did to create the CONTENT

89
00:03:44,940 --> 00:03:46,920
_URI, but that would

90
00:03:46,920 --> 00:03:49,860
involve converting the TaskId, which is

91
00:03:49,860 --> 00:03:52,620
a Long, into a string. Now the function

92
00:03:52,620 --> 00:03:54,450
call would also be slightly confusing

93
00:03:54,450 --> 00:03:56,430
because we're not actually appending a

94
00:03:56,430 --> 00:03:58,650
path in that case. The Uri class

95
00:03:58,650 --> 00:04:00,330
doesn't have a function to 

96
00:04:00,330 --> 00:04:02,220
append an ID and there's no reason why it

97
00:04:02,220 --> 00:04:04,530
should. IDs mean something in our

98
00:04:04,530 --> 00:04:06,660
content scheme but aren't part of the

99
00:04:06,660 --> 00:04:09,900
basic URI specification. Now you've

100
00:04:09,900 --> 00:04:11,370
probably already called up the

101
00:04:11,370 --> 00:04:13,110
documentation for the withAppendedId

102
00:04:13,110 --> 00:04:15,090
function, but if you haven't, open that

103
00:04:15,090 --> 00:04:20,250
now and take a quick look. You'll see that

104
00:04:20,250 --> 00:04:23,580
it says it appends the given ID to the

105
00:04:23,580 --> 00:04:24,960
end of the path, so that's pretty

106
00:04:24,960 --> 00:04:26,940
straightforward. The documentation for

107
00:04:26,940 --> 00:04:28,680
the ContentUris class also is

108
00:04:28,680 --> 00:04:30,990
really interesting if we have a quick

109
00:04:30,990 --> 00:04:31,980
look at that,

110
00:04:31,980 --> 00:04:33,930
because it reviews what we've already

111
00:04:33,930 --> 00:04:36,420
discussed about Uris and applies it

112
00:04:36,420 --> 00:04:38,670
to the CONTENT_URIs that we're

113
00:04:38,670 --> 00:04:40,710
using with our content provider. Al

114
00:04:40,710 --> 00:04:44,130
right. So the getId function performs

115
00:04:44,130 --> 00:04:45,900
the opposite function, so it returns the

116
00:04:45,900 --> 00:04:49,530
ID from a URI using the parseId function

117
00:04:49,530 --> 00:04:52,020
of CONTENT_URIs to do the job. Al

118
00:04:52,020 --> 00:04:53,460
right so there's just two more constants

119
00:04:53,460 --> 00:04:55,950
now we need to add, to complete our Tasks

120
00:04:55,950 --> 00:04:57,960
contract class. So I'm going to go up to the

121
00:04:57,960 --> 00:05:00,240
top and add those just after the CONTENT

122
00:05:00,240 --> 00:05:03,090
_URI. So the first one, 

123
00:05:03,090 --> 00:05:05,970
we'll do const Val and the CONTENT

124
00:05:05,970 --> 00:05:09,240
_TYPE is equal to, in double

125
00:05:09,240 --> 00:05:16,230
quotes, vnd.android.cursor dot

126
00:05:16,230 --> 00:05:21,480
dir, then a slash, a forward slash, vnd dot then a

127
00:05:21,480 --> 00:05:24,090
dollar sign CONTENT_

128
00:05:24,090 --> 00:05:30,090
AUTHORITY. So that's CONTENT__AUTHORITY dot

129
00:05:30,090 --> 00:05:34,280
then a dollar sign TABLE_NAME.

130
00:05:34,280 --> 00:05:36,570
And there shouldn't be a dot there,

131
00:05:36,570 --> 00:05:37,950
after the dir there should be slash

132
00:05:37,950 --> 00:05:40,980
actually. So it's vnd.android.cursor dot

133
00:05:40,980 --> 00:05:45,300
dir, slash, a forward slash, vnd dot then the dollar sign

134
00:05:45,300 --> 00:05:47,670
CONTENT__AUTHORITY, then a dot

135
00:05:47,670 --> 00:05:49,680
then a dollar TABLE_NAME. Now we're

136
00:05:49,680 --> 00:05:51,390
actually getting an error here, and it looks

137
00:05:51,390 --> 00:05:52,530
like I might have made a mistake with

138
00:05:52,530 --> 00:05:54,720
the CONTENT__AUTHORITY definition. So

139
00:05:54,720 --> 00:05:55,590
let's just have a quick look at that -

140
00:05:55,590 --> 00:05:58,380
we'll go to the definition for that. And in

141
00:05:58,380 --> 00:05:59,850
fact I did make a an error there,

142
00:05:59,850 --> 00:06:01,740
so I've made it a private and it

143
00:06:01,740 --> 00:06:03,480
should have actually been a const. So I'm

144
00:06:03,480 --> 00:06:04,950
going to delete the word private there

145
00:06:04,950 --> 00:06:07,950
and make that a const, and if we go back

146
00:06:07,950 --> 00:06:11,370
to our TasksContract, that error then

147
00:06:11,370 --> 00:06:14,130
disappears. Alright let's add the second

148
00:06:14,130 --> 00:06:17,430
one now. So it's const val, this is

149
00:06:17,430 --> 00:06:20,010
CONTENT_ITEM_

150
00:06:20,010 --> 00:06:23,010
TYPE. Set that equal vnd dot

151
00:06:23,010 --> 00:06:27,240
android.cursor dot, this time it's dot item

152
00:06:27,240 --> 00:06:31,470
instead of dot dir, then /vnd dot, a dollar

153
00:06:31,470 --> 00:06:33,690
sign CONTENT__AUTHORITY, noticing that

154
00:06:33,690 --> 00:06:36,090
that is now coming up correctly because

155
00:06:36,090 --> 00:06:38,280
I've corrected the definition there. So

156
00:06:38,280 --> 00:06:40,140
CONTENT__AUTHORITY dot and a dollar

157
00:06:40,140 --> 00:06:43,860
TABLE_NAME. Now I'll come back

158
00:06:43,860 --> 00:06:45,870
to these constants shortly, but

159
00:06:45,870 --> 00:06:47,760
before we switched to the TasksContract

160
00:06:47,760 --> 00:06:49,560
class to finish it off, we were looking

161
00:06:49,560 --> 00:06:51,570
at the query method in AppProvider.

162
00:06:51,570 --> 00:06:55,360
So let's just go back to AppProvider again,

163
00:06:55,360 --> 00:06:57,220
noting that we've no longer got an error

164
00:06:57,220 --> 00:07:00,310
on line 78. Now if the URI doesn't have

165
00:07:00,310 --> 00:07:02,560
an ID the matcher will return the value

166
00:07:02,560 --> 00:07:05,379
Tasks - line 74, effectively, is where it's

167
00:07:05,379 --> 00:07:07,180
testing for that - and we just call in the

168
00:07:07,180 --> 00:07:09,849
queryBuilder setTables method here, to

169
00:07:09,849 --> 00:07:11,650
add our Tasks table, or we're actually

170
00:07:11,650 --> 00:07:13,150
setting the property. Now I'm

171
00:07:13,150 --> 00:07:15,220
referring to the Java method

172
00:07:15,220 --> 00:07:17,020
here, and that's because queryBuilder's

173
00:07:17,020 --> 00:07:18,789
written in Java. Because we're

174
00:07:18,789 --> 00:07:20,680
programming in Kotlin we can assign the

175
00:07:20,680 --> 00:07:22,389
value directly to the tables property,

176
00:07:22,389 --> 00:07:23,530
which is effectively what we're doing -

177
00:07:23,530 --> 00:07:26,979
again on line 74. Now if there is an ID,

178
00:07:26,979 --> 00:07:29,530
the matcher returns TASKS_ID,

179
00:07:29,530 --> 00:07:32,349
and that's the code for that is line 76,

180
00:07:32,349 --> 00:07:34,599
starts on line 76, and we're using the

181
00:07:34,599 --> 00:07:37,090
appendWhereEscapeString method to add

182
00:07:37,090 --> 00:07:40,270
a where clause to specify the ID. Now the

183
00:07:40,270 --> 00:07:41,860
same thing will ultimately happen for

184
00:07:41,860 --> 00:07:43,330
the other tables once we've written

185
00:07:43,330 --> 00:07:46,060
their Contract classes and uncommented

186
00:07:46,060 --> 00:07:47,949
this code. Now if the URI isn't

187
00:07:47,949 --> 00:07:49,840
matched, down the bottom here, we'll throw

188
00:07:49,840 --> 00:07:51,789
an illegal argument exception and the

189
00:07:51,789 --> 00:07:54,039
rest of the code won't be executed. But

190
00:07:54,039 --> 00:07:56,379
assuming the URI is valid and matches

191
00:07:56,379 --> 00:07:58,330
one of our values, we can use the App

192
00:07:58,330 --> 00:07:59,949
Database instance to get a readable

193
00:07:59,949 --> 00:08:02,949
database object. Now we're only querying

194
00:08:02,949 --> 00:08:04,479
the database so we don't need to call

195
00:08:04,479 --> 00:08:06,729
the getWritableDatabase, so I'm using

196
00:08:06,729 --> 00:08:09,279
this, referring to this code here now, on

197
00:08:09,279 --> 00:08:11,620
line 101. So we don't need to call get

198
00:08:11,620 --> 00:08:13,090
WritableDatabase because it's a query,

199
00:08:13,090 --> 00:08:14,949
but we'll be doing that shortly when we

200
00:08:14,949 --> 00:08:16,900
come to insert rows into the database.

201
00:08:16,900 --> 00:08:18,550
But at this point we've now got

202
00:08:18,550 --> 00:08:20,710
everything we need to finish building

203
00:08:20,710 --> 00:08:23,139
the query to retrieve the data. And now

204
00:08:23,139 --> 00:08:24,580
it's time to use some of these those

205
00:08:24,580 --> 00:08:27,129
other parameters that the query method

206
00:08:27,129 --> 00:08:28,990
defines, so we'll just go back up and we'll

207
00:08:28,990 --> 00:08:31,659
look at that again. You can see line 66

208
00:08:31,659 --> 00:08:33,130
there, we've got quite a few arguments

209
00:08:33,130 --> 00:08:36,490
showing there, and what I might do is just going to

210
00:08:36,490 --> 00:08:38,289
press ENTER there, just so we can more

211
00:08:38,289 --> 00:08:40,510
clearly see what those arguments are.

212
00:08:40,510 --> 00:08:42,458
Alright, so looking at them, we'll start out

213
00:08:42,458 --> 00:08:44,949
with the first one, and we'll take the

214
00:08:44,949 --> 00:08:47,070
opportunity to open up the

215
00:08:47,070 --> 00:08:48,970
documentation for the query method. Let's

216
00:08:48,970 --> 00:08:52,329
do that. Alright that'll do, we can see, I'll put this down here

217
00:08:52,329 --> 00:08:53,589
a little bit further so you can still

218
00:08:53,589 --> 00:08:55,360
see the original parameters because we can't

219
00:08:55,360 --> 00:08:56,620
quite see them onto the right of the screen

220
00:08:56,620 --> 00:08:58,779
there. But in terms of the actual

221
00:08:58,779 --> 00:09:01,510
arguments, the first parameter's a URI

222
00:09:01,510 --> 00:09:03,430
and we've discussed that already. The

223
00:09:03,430 --> 00:09:05,740
next one is a projection. Well what is

224
00:09:05,740 --> 00:09:07,630
projection? And what that is is a

225
00:09:07,630 --> 00:09:08,330
string array

226
00:09:08,330 --> 00:09:10,580
containing the names of the columns that

227
00:09:10,580 --> 00:09:13,160
we want to be returned by the query. So

228
00:09:13,160 --> 00:09:15,170
this method effectively provides a great

229
00:09:15,170 --> 00:09:18,470
deal of flexibility in specifying what

230
00:09:18,470 --> 00:09:20,690
we'll get back from the database. Now the

231
00:09:20,690 --> 00:09:23,240
final parameter is a sortOrder. It's

232
00:09:23,240 --> 00:09:25,240
just the name of a row, or several rows,

233
00:09:25,240 --> 00:09:28,220
separated by commas that the data will

234
00:09:28,220 --> 00:09:30,650
be returned sorted by. so whatever's

235
00:09:30,650 --> 00:09:32,300
passed for the sortOrder will

236
00:09:32,300 --> 00:09:34,880
effectively appear in the SQL ORDER BY

237
00:09:34,880 --> 00:09:36,920
clause. Now I've deliberately skipped

238
00:09:36,920 --> 00:09:38,690
over the selection and selectionArgs

239
00:09:38,690 --> 00:09:40,880
parameters. I'll come back to them, as

240
00:09:40,880 --> 00:09:42,740
it's much easier to see how they work with

241
00:09:42,740 --> 00:09:44,810
an example, rather than just talking

242
00:09:44,810 --> 00:09:47,320
about them. But outside the when, our

243
00:09:47,320 --> 00:09:50,000
content providers query method calls the

244
00:09:50,000 --> 00:09:53,120
queryBuilders query method, and you can see

245
00:09:53,120 --> 00:09:55,850
that here on line 103. So that's the one

246
00:09:55,850 --> 00:09:57,200
we're writing, not the queryBuilders

247
00:09:57,200 --> 00:09:59,180
query method. So it's passing it the

248
00:09:59,180 --> 00:10:01,040
database object that we get by calling

249
00:10:01,040 --> 00:10:03,920
the AppDatabase getInstance function.

250
00:10:03,920 --> 00:10:06,110
You can see that db being called there,

251
00:10:06,110 --> 00:10:08,390
being passed I should say, to the query

252
00:10:08,390 --> 00:10:10,070
Builder.query function, or method,

253
00:10:10,070 --> 00:10:12,590
because again the query builder is

254
00:10:12,590 --> 00:10:14,330
written in Java. Now most of the

255
00:10:14,330 --> 00:10:15,890
parameters of our query method are

256
00:10:15,890 --> 00:10:17,510
passed straight into the queryBuilders

257
00:10:17,510 --> 00:10:20,300
query method, but it also includes two

258
00:10:20,300 --> 00:10:21,680
other parameters that we've just passed

259
00:10:21,680 --> 00:10:23,660
null for. And you can see they're grouped

260
00:10:23,660 --> 00:10:27,200
by, and having, both null currently. Now if we

261
00:10:27,200 --> 00:10:28,460
check out the documentation this time

262
00:10:28,460 --> 00:10:36,350
for the queryBuilder.query method, you

263
00:10:36,350 --> 00:10:37,820
can see that looks very similar to our

264
00:10:37,820 --> 00:10:40,580
content providers query method. So one's

265
00:10:40,580 --> 00:10:42,110
your projection to specify which columns

266
00:10:42,110 --> 00:10:44,120
should appear in the result, the

267
00:10:44,120 --> 00:10:45,800
selection and selectionArgs

268
00:10:45,800 --> 00:10:47,390
parameters that we'll look at shortly,

269
00:10:47,390 --> 00:10:49,880
and a sortOrder. But it also allows

270
00:10:49,880 --> 00:10:51,880
groupBy and having clauses to be used.

271
00:10:51,880 --> 00:10:54,440
Now we looked at groupBy in a SQL

272
00:10:54,440 --> 00:10:56,690
tutorial earlier in a previous section

273
00:10:56,690 --> 00:10:59,000
in this course. having is like a where

274
00:10:59,000 --> 00:11:01,100
clause but it also applies to the

275
00:11:01,100 --> 00:11:03,110
grouping, so I'm not going to use having.

276
00:11:03,110 --> 00:11:05,120
But if you did something like, for

277
00:11:05,120 --> 00:11:07,640
example, group by month to get the total

278
00:11:07,640 --> 00:11:09,230
of some value for each month, then you

279
00:11:09,230 --> 00:11:11,120
could do something like; adding having

280
00:11:11,120 --> 00:11:14,150
days equals 31, to only total the data

281
00:11:14,150 --> 00:11:16,430
for months that have got 31 days. So it's

282
00:11:16,430 --> 00:11:18,350
useful to know how you can do that, and

283
00:11:18,350 --> 00:11:20,060
there's quite a lot more to SQL than

284
00:11:20,060 --> 00:11:21,940
we've covered in the tutorials,

285
00:11:21,940 --> 00:11:23,620
but we won't be using the having clause in

286
00:11:23,620 --> 00:11:25,710
this app. So go back to our code now and

287
00:11:25,710 --> 00:11:29,050
the function finally finishes - down here

288
00:11:29,050 --> 00:11:31,450
is the last line returning a cursor. So

289
00:11:31,450 --> 00:11:33,070
it's returning the cursor that it's

290
00:11:33,070 --> 00:11:34,630
got back from the queryBuilder dot

291
00:11:34,630 --> 00:11:37,210
query method. Now to make it obvious that

292
00:11:37,210 --> 00:11:39,460
we get a cursor, I've used two lines of

293
00:11:39,460 --> 00:11:41,800
code and also logged the number of rows

294
00:11:41,800 --> 00:11:44,110
in the cursor. When we're happy that it

295
00:11:44,110 --> 00:11:46,210
works we can directly return the result

296
00:11:46,210 --> 00:11:47,920
of calling queryBuilder.query,

297
00:11:47,920 --> 00:11:50,260
instead of storing the cursor in a local

298
00:11:50,260 --> 00:11:52,780
variable first. Okay, and we haven't

299
00:11:52,780 --> 00:11:55,390
created a user interface yet, but we can

300
00:11:55,390 --> 00:11:57,760
test the content provider by logging the

301
00:11:57,760 --> 00:11:59,650
values in the logcat. But there's

302
00:11:59,650 --> 00:12:01,330
something else we need to do first, and

303
00:12:01,330 --> 00:12:03,840
that's to register our content provider

304
00:12:03,840 --> 00:12:06,370
so that the content resolver knows

305
00:12:06,370 --> 00:12:08,140
about it. So we'll do that and then test

306
00:12:08,140 --> 00:12:12,150
the content provider in the next video.

