YouTube2Text

Tracking User Location in the Background - MVVM Running Tracker App - Part 13 — Transcript

by Philipp Lackner · 3,695 words · 505 segments · language en · Watch on YouTube

Full transcript

  1. 0:01[Music]
  2. 0:10hey guys welcome back to new video so in
  3. 0:13this video we will implement the full
  4. 0:15functionality of our user tracking that
  5. 0:17means we will get the users location on
  6. 0:19a consistent basis and then simply save
  7. 0:21those locations to be able to later
  8. 0:24observe on changes on those locations so
  9. 0:27whenever we get a new location by the
  10. 0:29user then we can simply react to those
  11. 0:31changes in our tracking fragment and to
  12. 0:34be able to observe on those changes we
  13. 0:36will have live data objects here inside
  14. 0:39of a companion object in our tracking
  15. 0:41service so we can easily observe on
  16. 0:44those from the outside first of all I
  17. 0:46want to have a live data object with our
  18. 0:48current tracking States so just a
  19. 0:49boolean if we are currently tracking the
  20. 0:51user location or not that will be a well
  21. 0:54is tracking and we're going to set that
  22. 0:58to immutable live data of type boolean
  23. 1:05so we will just whenever the tracking
  24. 1:08state changes post the new value instead
  25. 1:10of this is tracking live data and then
  26. 1:12we can observe on those changes from the
  27. 1:14outside and we will also have another
  28. 1:16life data here for this video which is a
  29. 1:18little more complex than this boolean
  30. 1:21life data because this life data I want
  31. 1:23to create here will hold all the tracked
  32. 1:25locations from a specific run and the
  33. 1:28intuitive answer here is to just save
  34. 1:31that as live data of list of coordinates
  35. 1:34so we just have a list of several
  36. 1:36coordinates and then we will simply draw
  37. 1:39a line later on after those coordinates
  38. 1:41inside of that list but this intuitive
  39. 1:43answer won't help us much here because
  40. 1:45it will produce a bug later on if we
  41. 1:47implement it like that and why that
  42. 1:49happens or why we why that is not enough
  43. 1:51I want to show you in my emulator in the
  44. 1:54actual final app here you can see I can
  45. 1:57simulate a route that the emulator will
  46. 1:59run let's click on play route and start
  47. 2:03a new run then you can see that the
  48. 2:07tracking stars it's working perfectly
  49. 2:09fine and a single line here consists of
  50. 2:12several coordinate
  51. 2:13so that is basically just a list of
  52. 2:15coordinates and that is pretty clear I
  53. 2:17guess but if we now click on stop
  54. 2:20then the emulator is still continuing on
  55. 2:23that route but we don't track right now
  56. 2:25because if we now click on start again
  57. 2:28so we continue that route then of course
  58. 2:31a new line needs to start and it
  59. 2:33shouldn't connect this line with the new
  60. 2:37line instead during that time inside of
  61. 2:40this window where we didn't track we
  62. 2:44also don't have any coordinates and we
  63. 2:46don't want to display them in our map
  64. 2:47because let's say the user run and then
  65. 2:51he stopped the service then he walked a
  66. 2:52little bit and then he clicked on start
  67. 2:54again so he wants to continue running in
  68. 2:57that case we of course don't want to
  69. 3:00connect the old run with the new run so
  70. 3:03in the end we can say that each single
  71. 3:07line we have here is a list of
  72. 3:10coordinates but since we have several of
  73. 3:12those lines that live data that we want
  74. 3:15to create now must be a live data of
  75. 3:18list of lists of coordinates so we have
  76. 3:20a list of several lists that hold
  77. 3:23coordinates and that sounds pretty
  78. 3:26complex right now let's actually stop
  79. 3:28that tracking here and it will actually
  80. 3:30get clearer when we implement that
  81. 3:32so let's actually implement that that
  82. 3:34will be a well called path points so
  83. 3:38just the points on our run path and that
  84. 3:41will be immutable live data of type
  85. 3:44mutable lists of type mutable lists of
  86. 3:51type let long if you don't know what let
  87. 3:55long is that is just the coordinate
  88. 3:58format of maps since the earth is not
  89. 4:01flat and rectangular well who knows but
  90. 4:04you cannot simply have an x and y
  91. 4:06coordinate format for describing
  92. 4:09coordinates on the earth and that's why
  93. 4:11we have that special lat/long
  94. 4:13coordinates format here so again because
  95. 4:15this is really a complex type here first
  96. 4:18of all we have our mutable life data
  97. 4:19that just allows us to observe on
  98. 4:22changes of this type later on so
  99. 4:25whenever we get a new coordinate in
  100. 4:27of our polyline list then we can observe
  101. 4:30on that change we can see that there is
  102. 4:32actually a change in our tracking
  103. 4:34fragment and draw the actual line on our
  104. 4:37map view then we have that mutable list
  105. 4:40of mutable list of lat/long one mutable
  106. 4:44list of let long here is just a simple
  107. 4:46polyline just a line of coordinates on
  108. 4:50our map and since we can stop our
  109. 4:53service and resume it we simply have
  110. 4:55several polylines or we can have several
  111. 4:57polylines in our map so we have a list
  112. 5:00of polylines I think if we describe it
  113. 5:04like that that immutable list of that
  114. 5:06long is actually a polyline then it's
  115. 5:08much clearer so what we could do here is
  116. 5:10actually define a type alias for that
  117. 5:12that is just a different name for that
  118. 5:14complex type and we can do that by
  119. 5:16writing type alias and let's do that for
  120. 5:20a polyline and define that as a mutable
  121. 5:23list of lat/long and then we can also
  122. 5:29have a type alias for several polylines
  123. 5:31so polylines is equal to a mutable list
  124. 5:35and now we can say a mutable list of
  125. 5:37Tolley line and if we now take that
  126. 5:40whole block here and replace it with
  127. 5:43polylines it's actually much clearer so
  128. 5:47I hope that is clear now and since we
  129. 5:49just created that life that are here and
  130. 5:52here that life data just doesn't hold
  131. 5:55any value right now and that's why I
  132. 5:57want to create a function here that just
  133. 5:59posts initial values inside of those
  134. 6:01live data objects so private function
  135. 6:03post initial values and inside of this
  136. 6:07function we just want to use our is
  137. 6:09tracking live data and call post value
  138. 6:12and initially we are not tracking so we
  139. 6:15post the value false and we want to use
  140. 6:18our path point live data and post the
  141. 6:21value mutable list off so just an empty
  142. 6:25list because we don't have any
  143. 6:26coordinates in the beginning the next
  144. 6:28function we want to implement here is a
  145. 6:29function that adds an empty polyline so
  146. 6:32an empty list of lat/long coordinates at
  147. 6:34the end of our polylines list because
  148. 6:37when we post our tracking and then we
  149. 6:40zoom it again then we simply need to add
  150. 6:42that empty list first before we can add
  151. 6:45coordinates in it and let's actually do
  152. 6:48that down here that will be a private
  153. 6:51function add empty polyline and we are
  154. 6:56going to set it to path points dot value
  155. 6:59so the value of that life data that is
  156. 7:02in this case our whole polylines list so
  157. 7:05all of our polylines and we call that
  158. 7:08apply on that and here we can just call
  159. 7:12add so we want to add a list to that
  160. 7:14path points and we want to add an empty
  161. 7:17list so just mutable list off and then
  162. 7:20afterwards we want to use half points
  163. 7:23dot host value and use this because
  164. 7:27we're instead of this applied log here
  165. 7:29this refers to this current polylines
  166. 7:32object and because we added that new
  167. 7:35polyline there is a change so we want to
  168. 7:38post the new value of that so our
  169. 7:40fragment will be notified about that
  170. 7:42change later on but what could also
  171. 7:44happen is that this value is null and in
  172. 7:47that case we won't execute that block so
  173. 7:49we won't add an empty polyline in that
  174. 7:51case we also need to take care of this
  175. 7:54case in case it is now because then we
  176. 7:56simply want to post the initial polyline
  177. 7:58so just the first empty polyline let's
  178. 8:01use path points dot post value mutable
  179. 8:05list of type mutable lists off so here
  180. 8:09we just initialize our polylines list
  181. 8:12and we also add the first empty polyline
  182. 8:16inside of that list so we can easily add
  183. 8:19coordinates to that and start the
  184. 8:21tracking and then we can simply call
  185. 8:23that at empty polyline function inside
  186. 8:25of our star fragment service function
  187. 8:27because when we start our service we of
  188. 8:28course want to I'm at that first
  189. 8:30polyline that first empty polyline so
  190. 8:33simply call that function at the start
  191. 8:35of that start program service function
  192. 8:36and now that we have that function that
  193. 8:38adds an empty polyline at our polyline
  194. 8:41list we also need a function that adds a
  195. 8:44coordinate to the last polyline of our
  196. 8:46polyline list and for that I will create
  197. 8:49another function a private function at
  198. 8:53half-point and that will take a location
  199. 8:56as a parameter which is of type location
  200. 8:59that is just very similar to a lat/long
  201. 9:02coordinate but it holds more information
  202. 9:05about a specific location but we only
  203. 9:07need the latitude and longitude
  204. 9:09coordinates of that location parameter
  205. 9:11here but that's just the type that we
  206. 9:13get later on when we get the user's
  207. 9:15location so instead of this at power
  208. 9:19point function we want to check if that
  209. 9:21location that we got here is actually
  210. 9:23not equal to null and I forgot to make
  211. 9:25it a nullable type here that is
  212. 9:26important because the locations we get
  213. 9:28later on will be nullable too so we
  214. 9:31simply use location and check with let
  215. 9:35if that is not equal to null so if we go
  216. 9:37inside of this lab block and that means
  217. 9:39that location is not equal to not and
  218. 9:41now as I said we have that long
  219. 9:43coordinates inside of our polyline
  220. 9:45instead of a single polyline and here we
  221. 9:48have a location and that is not a
  222. 9:50lat/long coordinate right now
  223. 9:51so we someone need to convert that but
  224. 9:53that is very easy to do we just have a
  225. 9:55well position and set it to new led long
  226. 9:58and that consists of two parameters the
  227. 10:01latitude and the longitude we can get
  228. 10:04the latitude by writing location dot
  229. 10:08latitude and location dot longitude and
  230. 10:12now what we want to do is we want to add
  231. 10:15this position to the last polyline of
  232. 10:18our polylines list so we will use our
  233. 10:21path points live data again dot value
  234. 10:24question mark apply so we make that null
  235. 10:28check here and here we want to get the
  236. 10:31last polyline of that and since that is
  237. 10:33a mutable list here we can simply use
  238. 10:35last year to refer to the last index of
  239. 10:38that list and since that last index is
  240. 10:41also list the list of let long
  241. 10:44coordinates we can add a new coordinate
  242. 10:47here and simply pass our position and
  243. 10:49since we changed something in our path
  244. 10:52points like that we also want to post a
  245. 10:55new value so path points dot post value
  246. 10:58and simply write this and that's already
  247. 11:01it for this ad path point function the
  248. 11:03next step is to define a location
  249. 11:05callback because 2 X
  250. 11:07get those location updates what we will
  251. 11:09use here is a so called fused location
  252. 11:11provider client that is just something
  253. 11:14that we can use to request location
  254. 11:16updates so it will basically deliver us
  255. 11:19on consistent basis with new location
  256. 11:21updates whenever the location changes or
  257. 11:23we can set an interval for that when we
  258. 11:25want to get a new location update and
  259. 11:27then simply deliver them to us and for
  260. 11:30that we will just need that callback to
  261. 11:32get the actual location results let's
  262. 11:35define that up here Val location
  263. 11:38callback which is an anonymous class so
  264. 11:41of type object : location callback call
  265. 11:45the constructor here and here we press
  266. 11:48ctrl + o and we want to implement that
  267. 11:52function on location result then we want
  268. 11:56to rename that p0 parameter here
  269. 11:58pressing Shift + f6 to result because
  270. 12:03that's a little bit more clear of course
  271. 12:05and in here we want to check if is
  272. 12:08tracking that value and also assume that
  273. 12:12this is not equal to now because at this
  274. 12:13point there is no way this can be now so
  275. 12:16this line just means we want to check if
  276. 12:19we are currently tracking because only
  277. 12:21then we want to add coordinates of
  278. 12:23course and then use that result
  279. 12:25parameter here so the location result to
  280. 12:30make an object here and use locations
  281. 12:34because that will hold the locations of
  282. 12:36that result which will usually only hold
  283. 12:38a single location but that is still a
  284. 12:40list so we want to make a null check
  285. 12:42here again in case those locations are
  286. 12:45now if they are not now let's actually
  287. 12:48call that locations if they are not now
  288. 12:53we just want to loop over them so for
  289. 12:56each location in locations and simply
  290. 13:00call our function at path point and past
  291. 13:03that location
  292. 13:04so all that callback does now is
  293. 13:06whenever we retrieve a new location
  294. 13:08which is saved in that result variable
  295. 13:10we just add that location to the end of
  296. 13:13our last polyline and now the last real
  297. 13:16function we need to do for this video is
  298. 13:18a function that will up
  299. 13:20location-tracking so whenever that is
  300. 13:23tracking value here instead of our life
  301. 13:25data changes we also want to update the
  302. 13:27location tracking because if it changes
  303. 13:29from false to true so if we want to
  304. 13:31start a location tracking we need to
  305. 13:33explicitly request those location
  306. 13:35updates and if it switches from true to
  307. 13:38false so if we stop the location
  308. 13:40tracking we don't want those update
  309. 13:42anymore and for that I will define a
  310. 13:44function that will be a private function
  311. 13:47update location tracking which will take
  312. 13:51the is tracking parameter as a boolean
  313. 13:53in the parameter list here and inside of
  314. 13:57this function we want to check if we are
  315. 13:59currently tracking so if is tracking is
  316. 14:02equal to true if it is we also want to
  317. 14:05check if we actually have the location
  318. 14:07permissions so if we are allowed to
  319. 14:09track so let's make another if check
  320. 14:12here if tracking utility that's why we
  321. 14:15have that function that has location
  322. 14:17permissions and context is just this
  323. 14:19year since we're instead of a service
  324. 14:21class there is no problem so if we have
  325. 14:24the location permissions then we want to
  326. 14:26request location updates and for that we
  327. 14:28need a location request which will just
  328. 14:31hold some parameters regarding our
  329. 14:33location updates I will call this well
  330. 14:35request and that will be a location
  331. 14:38request dot apply and here we can make
  332. 14:43some changes on that location request
  333. 14:45first of all we want to set the interval
  334. 14:47of that location request so how often
  335. 14:49will we actually get our location
  336. 14:52updates and for that I want to set a
  337. 14:54constant in our constants file and now
  338. 14:57we kinda have to set it the average
  339. 14:59interval at which we will get location
  340. 15:01updates that's not super accurate but
  341. 15:04let's set that by writing a consul
  342. 15:07location update interval and I will set
  343. 15:11that to 5,000 milliseconds so every 5
  344. 15:15seconds we will get a location update
  345. 15:16but what this location request also
  346. 15:19takes is the fastest update interval so
  347. 15:22the interval which is basically the
  348. 15:25lowest interval possible so we will
  349. 15:29never actually get more updates than
  350. 15:32this fastest location
  351. 15:33interval let's call this fastest
  352. 15:36location interval and I'll set that to
  353. 15:392,000 milliseconds so two two seconds so
  354. 15:42it will never happen for example that we
  355. 15:44get location updates each second at
  356. 15:46minimum we will have that two seconds
  357. 15:48interval which is just to save memory
  358. 15:51resources but as I said that really
  359. 15:53differs it could be that we receive a
  360. 15:55location update after 3 seconds after 6
  361. 15:57seconds and that is just a value that is
  362. 16:02approximately to the interval that we
  363. 16:04set here then we can go back to our
  364. 16:06tracking service and assign the interval
  365. 16:09here to location update interval then we
  366. 16:14want to assign the fastest interval to
  367. 16:17fastest location interval and what is
  368. 16:21also very important here is the priority
  369. 16:25which we will set to priority priority
  370. 16:31high accuracy import that here which
  371. 16:35just means we want to get accurate
  372. 16:37location results here and as I said to
  373. 16:40actually be able to request those
  374. 16:41location updates we need a so called
  375. 16:43fused location provider client let's
  376. 16:46actually scroll up and create it up here
  377. 16:48which is Lady Navarre fused location
  378. 16:51provider client and instead of our on
  379. 16:55create function from our service we want
  380. 16:57to initialize that fused location
  381. 16:58provider client so let's overwrite on
  382. 17:01create here and set that fused location
  383. 17:05provider client to new fused location
  384. 17:08provider client which takes the context
  385. 17:11so we just passed this year and then we
  386. 17:13can scroll down again to our update
  387. 17:15location tracking function and after
  388. 17:18that applied lock we want to use that
  389. 17:20fused location provider client and call
  390. 17:22that week rest location updates and that
  391. 17:26now takes our location week rest as a
  392. 17:28parameter so we just passed that request
  393. 17:30here it will take the callback we
  394. 17:34defined down there so our location
  395. 17:37callback and we need to pass the looper
  396. 17:39which is just blooper dot get main
  397. 17:42looper and as you can see it throws us
  398. 17:45an error here because
  399. 17:47it wants a permission check by us but we
  400. 17:49actually did that permission check here
  401. 17:51but since we do it with that easy
  402. 17:53permissions library it doesn't recognize
  403. 17:54that so let's click on that press alt' +
  404. 17:57enter' and suppress this warning with
  405. 18:01this suppress linda annotation here and
  406. 18:03then this error will go away and now in
  407. 18:05case that is tracking variable is false
  408. 18:08so we stop the tracking then we want to
  409. 18:10remove those location updates again so
  410. 18:12let's add an else block here and simply
  411. 18:15use our fused location provider client
  412. 18:17dot remove location updates and you can
  413. 18:20see we simply need to pass the location
  414. 18:22callback here so let's do that and that
  415. 18:24is everything you need to do and now we
  416. 18:26only need to scroll up to our on create
  417. 18:28function here first of all I want to
  418. 18:30call that post initial values function
  419. 18:31here before we forget that and at the
  420. 18:35end of uncreate we want to use our is
  421. 18:38tracking live data and call that observe
  422. 18:40on that has this as a life cycle ona and
  423. 18:43that is only possible because we
  424. 18:45declared that service as a life cycle
  425. 18:48service otherwise we couldn't pass a
  426. 18:50service as a life cycle
  427. 18:51owner and as a second parameter we will
  428. 18:53pass an observer here and here we just
  429. 18:57get updates whenever our is tracking
  430. 18:59state changes and whenever that changes
  431. 19:01we want to call our update location
  432. 19:03tracking function and simply pass it
  433. 19:05here and when we start our service now
  434. 19:08then the only thing we need to do is to
  435. 19:10post the value true in our is tracking
  436. 19:12live data so that observed block here
  437. 19:14will actually be caught with the value
  438. 19:16true as a boolean then we will call up
  439. 19:18the location tracking with true and then
  440. 19:21we will simply request those location
  441. 19:23updates so let's scroll down to our
  442. 19:25start foreign service function and here
  443. 19:27we just want to call is tracking the
  444. 19:29post value true and to test that
  445. 19:31functionality I just want to scroll up
  446. 19:33to our location callback or on location
  447. 19:35result function because that's the
  448. 19:37function where we get a new location and
  449. 19:39here I just want to add a lock statement
  450. 19:42with timber timber D new location and
  451. 19:46simply pass of a location that longitude
  452. 19:49no latitude first latitude and then
  453. 19:54location dot longitude
  454. 19:58and if we now run our app and take a
  455. 20:03look in our emulator then you can see
  456. 20:05that emulate a menu here or the options
  457. 20:08for that emulator on those three little
  458. 20:10dots here let's click on those and then
  459. 20:12you can see we have a location tab and
  460. 20:14instead of this location tab we have a
  461. 20:16routes tab and instead of this routes
  462. 20:19tab we can now set up our custom routes
  463. 20:21that the emulator will simulate so if we
  464. 20:25want to do that we need to go into this
  465. 20:26text field here and type the destination
  466. 20:31where we want to simulate that route too
  467. 20:33so in my case I will just choose Hamburg
  468. 20:36here in Germany choose that one and now
  469. 20:40I can see we can start that route let's
  470. 20:42click on that icon and now we have to
  471. 20:45set up the start point and in my case
  472. 20:48that is my hometown Hannover choose that
  473. 20:52one and if we now click on safe route
  474. 20:55then we can give it a name I will just
  475. 20:57click on save here you can see that
  476. 21:00route is saved in our safe routes tab
  477. 21:02here and now we can choose a playback
  478. 21:05speed so how fast that emulator will
  479. 21:07simulate that route I will choose four
  480. 21:09times here and click on play route and
  481. 21:12now if we zoom in you can see that the
  482. 21:17position is actually walking that route
  483. 21:20or driving that route or whatever and if
  484. 21:22we now go into our emulator we will
  485. 21:25actually receive those location updates
  486. 21:28let's open lock it here and choose the
  487. 21:33correct emulator of course open the
  488. 21:35emulator here click on the floating
  489. 21:37action button and if we now click on
  490. 21:41start the tracking will start and you
  491. 21:44can see we receive location updates with
  492. 21:46the latitude and the longitude exactly
  493. 21:49as we want it so everything is working
  494. 21:52perfectly fine I hope this video was
  495. 21:54helpful for you even though this was
  496. 21:56very long but I just wanted to set up
  497. 21:59that hole location stuff in a single
  498. 22:01video because that kind of belongs
  499. 22:04together and I just wanted to have that
  500. 22:06in a single part and yeah if this video
  501. 22:08helped you please leave a like and
  502. 22:09subscribe to my channel if you haven't
  503. 22:11already have
  504. 22:12stay tuned the next video bye-bye
  505. 22:19[Music]

About this transcript

This page contains the full transcript of Tracking User Location in the Background - MVVM Running Tracker App - Part 13 by Philipp Lackner, generated from the public captions YouTube serves with the video. The transcript has 3,695 words across 505 segments, with the original timestamps preserved so you can click any line to jump to that moment in the embedded player.

What you can do with it

Use the transcript to take notes, quote the speaker, build a study guide, generate a summary with ChatGPT or Claude via the YouTube Summary tool, or export it as a timed subtitle file with YouTube to SRT. You can also re-open it in the transcriber to translate the transcript into 100+ languages.

Free YouTube transcript tool

YouTube2Text is a free YouTube transcript generator — no signup, no daily limit. Paste any YouTube link and get the full transcript instantly, with timestamps, click-to-jump, translation to 100+ languages, AI prompts for ChatGPT, Claude, and Gemini, and exports to TXT, SRT, VTT, or Markdown.