Would you like to inspect the original subtitles? These are the user uploaded subtitles that are being translated:
0
1
00:00:00,300 --> 00:00:06,210
To get started with the weather app go to the GitHub repository listed in the course resources. Then
1
2
00:00:06,210 --> 00:00:10,860
clone the repository and open the project from Android Studio,
2
3
00:00:10,860 --> 00:00:13,140
just as we've done with the previous apps.
3
4
00:00:13,140 --> 00:00:15,930
Finally remember to click on get dependencies
4
5
00:00:15,930 --> 00:00:21,310
after the project is open so that all your errors go away and your project builds successfully.
5
6
00:00:21,420 --> 00:00:28,260
Then we should see that we have a number of folders inside our lib folder. So I've classified all of
6
7
00:00:28,260 --> 00:00:31,920
our different files into different sections.
7
8
00:00:31,920 --> 00:00:35,190
We've got our different screens and we've got three of those:
8
9
00:00:35,610 --> 00:00:42,780
a loading screen, a location screen and a screen for getting the weather based on the city name.
9
10
00:00:42,780 --> 00:00:48,660
And then we've got some services such as the location.dart or the networking part or the weather
10
11
00:00:48,660 --> 00:00:55,380
part. And we finally got some utilities which currently just have a constants file. And everything starts
11
12
00:00:55,380 --> 00:00:58,010
out from the main.dart file.
12
13
00:00:58,110 --> 00:01:03,600
So go ahead and have a look at the designs that we've already created for you.
13
14
00:01:03,780 --> 00:01:09,150
But essentially the UI is kept pretty simple because we're going to be doing a lot of backend stuff
14
15
00:01:09,240 --> 00:01:10,360
and networking.
15
16
00:01:10,380 --> 00:01:16,710
So we've kept the user interface relatively easy to understand, even the most complex screen which is
16
17
00:01:16,710 --> 00:01:20,160
the location screen is pretty simple if you just read through it.
17
18
00:01:20,250 --> 00:01:28,560
It's simply a container with a background image with a column inside that contains a number of buttons
18
19
00:01:28,980 --> 00:01:30,410
as well as some text widgets.
19
20
00:01:30,420 --> 00:01:32,380
So it's pretty simple stuff
20
21
00:01:32,460 --> 00:01:39,630
so far. Now the first thing that happens when our app loads is it will load up the loading screen as the
21
22
00:01:39,630 --> 00:01:40,910
first route.
22
23
00:01:40,920 --> 00:01:46,950
So inside our loading screen, you can see that there's pretty much nothing in here other than a state-
23
24
00:01:46,950 --> 00:01:52,080
ful widget that contains a single raised button which says get location.
24
25
00:01:52,620 --> 00:01:58,540
So if you run this as it is, there's nothing terribly exciting going on right now,
25
26
00:01:58,680 --> 00:02:05,910
it's just a black screen with a single button. But this is where our app is going to start from and the
26
27
00:02:05,910 --> 00:02:12,560
first thing that we want to do is to be able to grab the user's location when we tap on this button
27
28
00:02:12,600 --> 00:02:14,160
get location.
28
29
00:02:14,400 --> 00:02:20,130
Now in order to do this, we're going to leverage the power of Flutter packages. And there's a package
29
30
00:02:20,160 --> 00:02:27,860
called geolocator that we're going to be using to be able to get location services both from iOS
30
31
00:02:28,230 --> 00:02:36,070
and Android. So we'll have to call a single line of code like this that they've described in the documentation
31
32
00:02:36,520 --> 00:02:42,730
and the package will go behind the scenes and do all the necessary things to be able to get us the location
32
33
00:02:43,000 --> 00:02:47,100
whether if our code is being run on iOS or Android.
33
34
00:02:47,140 --> 00:02:51,060
So let's get started by adding this as a dependency.
34
35
00:02:51,130 --> 00:02:55,510
So I'm just going to copy this and go into my pubspec.yaml
35
36
00:02:55,660 --> 00:02:58,800
and right over here just below our cupertino_icons,
36
37
00:02:58,990 --> 00:03:05,890
I'm going to add our geolocator and make sure that it's formatted to be at the same level as cupertino
37
38
00:03:05,920 --> 00:03:06,950
icons.
38
39
00:03:07,000 --> 00:03:10,620
And at the moment it's coming in as a string, I'm just going to delete it.
39
40
00:03:10,660 --> 00:03:13,030
It doesn't really matter if you keep it or not.
40
41
00:03:13,060 --> 00:03:15,200
It will be interpreted in the same way.
41
42
00:03:15,220 --> 00:03:17,740
But I like to have things consistent.
42
43
00:03:17,740 --> 00:03:24,160
So now that we've added that dependency, let's click on packages get to actually imported into our project.
43
44
00:03:24,460 --> 00:03:30,660
And once that's complete, we should be able to see it inside our external libraries and Flutter plugins.
44
45
00:03:30,840 --> 00:03:33,340
So you can see geolocator right there.
45
46
00:03:34,330 --> 00:03:40,420
So now we can actually use it and we're going to be using it inside our loading screen for now.
46
47
00:03:40,750 --> 00:03:45,580
So the first step towards using any of these packages is of course importing it.
47
48
00:03:45,610 --> 00:03:50,450
So right at the top, we're going to import our geolocator.
48
49
00:03:50,500 --> 00:03:52,750
There it is, geolocator.dart.
49
50
00:03:52,750 --> 00:03:58,380
And now we're going to create a new method which is not going to return anything, but all it's going
50
51
00:03:58,370 --> 00:04:06,520
to do is it's going to get the location, so get location. And inside the curly braces of this method,
51
52
00:04:06,670 --> 00:04:11,500
it's going to do everything that's necessary to be able to bring us the current user location.
52
53
00:04:11,920 --> 00:04:17,780
So if we take a look at the docs, it tells us to query the current location of the device.
53
54
00:04:17,920 --> 00:04:22,090
Simply make a call to the getCurrentPosition method.
54
55
00:04:22,090 --> 00:04:23,890
And it shows us how we do this.
55
56
00:04:24,580 --> 00:04:30,940
So it's data type position and this is something called position. And then we have a keyword called a
56
57
00:04:30,960 --> 00:04:35,060
await, and we use the geolocator to get the current position.
57
58
00:04:35,200 --> 00:04:40,980
And as an input we specify how accurate we want that location to be.
58
59
00:04:41,080 --> 00:04:48,730
So let's go ahead and copy this line of code into our project and I'm going to paste it right inside
59
60
00:04:48,730 --> 00:04:52,480
this new method I created called getLocation.
60
61
00:04:52,480 --> 00:05:00,250
Now the first thing that we have to do in order to make this actually work is to add a modifier keyword
61
62
00:05:00,280 --> 00:05:04,520
to this function and it's going to be the word async.
62
63
00:05:04,540 --> 00:05:08,710
Now what exactly is this async and await?
63
64
00:05:08,710 --> 00:05:15,580
Well this is a way for us to be able to carry out time consuming tasks such as getting the GPS location
64
65
00:05:15,580 --> 00:05:21,850
from the phone. You can imagine that asking the phone for the current location, getting it back then processing
65
66
00:05:21,850 --> 00:05:25,860
it and finally being able to have access to it takes a little bit of time.
66
67
00:05:26,110 --> 00:05:32,140
And there's also other things such as trying to get data downloaded from the Internet or trying to read
67
68
00:05:32,140 --> 00:05:33,530
something from file.
68
69
00:05:33,580 --> 00:05:39,370
These are all things that can take an unpredictable amount of time but also it can take quite a long
69
70
00:05:39,370 --> 00:05:42,610
time. By using asynchronous programming
70
71
00:05:42,730 --> 00:05:47,950
we can get these time consuming tasks to happen in the background instead of happening in the foreground
71
72
00:05:48,040 --> 00:05:51,290
and blocking up our UI and freezing up our app.
72
73
00:05:51,400 --> 00:05:57,640
Now the entire next lesson is dedicated to asynchronous programming in Dart and we'll talk about async
73
74
00:05:57,730 --> 00:06:01,760
await futures and all that in a lot of detail.
74
75
00:06:01,930 --> 00:06:05,620
But for now let's try and get the current location first.
75
76
00:06:05,830 --> 00:06:12,040
So we've got this object called Geolocator which comes from the geolocator package and we're going
76
77
00:06:12,040 --> 00:06:18,230
to use it to get the current position by providing a desired amount of accuracy.
77
78
00:06:18,400 --> 00:06:24,400
And I'm going to change that from high to low. And you can see that there's a whole bunch of different
78
79
00:06:24,400 --> 00:06:31,450
options you have, lowest, medium, low, high best for navigation and the thing to remember is that the more
79
80
00:06:31,510 --> 00:06:36,330
accurate the location you're trying to get, the more battery intensive it will be.
80
81
00:06:36,340 --> 00:06:42,550
So if you want to be kind to your users and their phones battery, only use as much accuracy as you need.
81
82
00:06:42,550 --> 00:06:45,940
So if you're making a navigation app where people actually need
82
83
00:06:45,940 --> 00:06:51,790
turn by turn directions, then you probably do need to choose something that is quite accurate like best
83
84
00:06:51,790 --> 00:06:52,960
for navigation.
84
85
00:06:52,960 --> 00:06:58,600
But if we're only trying to get the weather, then something like low which gives us the accuracy to the
85
86
00:06:58,600 --> 00:07:05,170
nearest kilometer on iOA and nearest 500 meters on Android, is probably good enough. And even the lowest
86
87
00:07:05,380 --> 00:07:11,410
one is probably fine, but either way choose one of these accuracy levels.
87
88
00:07:11,410 --> 00:07:18,340
And now we should hopefully be able to get our position back and once we do get our position back, I'm
88
89
00:07:18,340 --> 00:07:23,430
simply going to print it into the console to see where we currently are
89
90
00:07:23,470 --> 00:07:30,640
according to the GPS. Now there's just one more step that you have to do for this to work and that
90
91
00:07:30,640 --> 00:07:37,240
is to ask the user for permission to get their current location because you don't want apps that just
91
92
00:07:37,240 --> 00:07:43,960
happens at the user's location without them knowing cause that's kind of dangerous. And both on iOS and
92
93
00:07:43,990 --> 00:07:44,710
Android,
93
94
00:07:44,710 --> 00:07:48,960
you have to explicitly request positional data.
94
95
00:07:49,150 --> 00:07:56,170
So let's see how we can do that. In the documentation for geolocator, if you scroll down a little bit
95
96
00:07:56,500 --> 00:08:03,430
they'll tell you that in order to get permissions on Android you need to add either the access coarse
96
97
00:08:03,430 --> 00:08:08,860
location or the access fine location into the Android manifest,
97
98
00:08:08,860 --> 00:08:17,360
so where we're only using a low level accuracy positional data, so we only need permission to get coarse location.
98
99
00:08:17,410 --> 00:08:25,510
So let's go ahead and hit copy on this particular tag and let's go into our Android project folder right
99
100
00:08:25,510 --> 00:08:31,780
here and then go into our app folder, our source, main
100
101
00:08:31,870 --> 00:08:36,340
and here we should find our AndroidManifest.xml file.
101
102
00:08:36,430 --> 00:08:41,590
So if you double click on this to open it up you can see that these are various settings we have set
102
103
00:08:41,890 --> 00:08:43,880
for our Android project.
103
104
00:08:44,080 --> 00:08:50,550
And it tells us that we have to add one of the following two lines as direct children of the manifest
104
105
00:08:50,550 --> 00:08:51,120
tag.
105
106
00:08:51,130 --> 00:08:51,940
So what does that mean?
106
107
00:08:52,060 --> 00:08:58,110
Well this is the manifest tag and it's the highest level tag in this particular file.
107
108
00:08:58,210 --> 00:09:04,510
Everything in it are its children but there's also lower hierarchy such as the application tag or the
108
109
00:09:04,510 --> 00:09:08,150
activity tag or the meta data tag.
109
110
00:09:08,230 --> 00:09:14,050
And if you've ever worked with HTML, then this formatting will be very familiar to you because it's
110
111
00:09:14,050 --> 00:09:18,920
styled in XML which stands for extensible markup language.
111
112
00:09:19,060 --> 00:09:26,080
And essentially it's kind of the same as our key value pairs where the key are in these tags and the
112
113
00:09:26,080 --> 00:09:28,970
values are held inside the tags.
113
114
00:09:29,560 --> 00:09:32,500
So inside the manifest tag,
114
115
00:09:32,530 --> 00:09:40,010
so right here just after the closing angle bracket, we're going to paste in our user's permission tag.
115
116
00:09:40,210 --> 00:09:46,570
And this one tells our Android app that we need to access the coarse location and it should request
116
117
00:09:46,570 --> 00:09:48,400
it from the user.
117
118
00:09:48,400 --> 00:09:53,680
So that's our Android part done, so we can close up our Android folder.
118
119
00:09:53,680 --> 00:09:57,090
And now we have to ask for permission on iOS,
119
120
00:09:57,100 --> 00:10:04,960
so when an iOS user uses our app. And what we have to do is we're going to copy these two lines, a key
120
121
00:10:05,320 --> 00:10:11,260
and a string, which tells the user why we need to use their location.
121
122
00:10:11,350 --> 00:10:14,620
So you can change this text if you wish to,
122
123
00:10:14,830 --> 00:10:19,330
if you want to make it more descriptive for the user when you're actually requesting for their data.
123
124
00:10:19,810 --> 00:10:25,480
But let's copy these two lines and we're going to add it to our info.plist file.
124
125
00:10:26,200 --> 00:10:33,700
So now we have to go into our iOS folder and inside our runner folder are all the files that are specifically
125
126
00:10:33,700 --> 00:10:35,560
related to our iOS app.
126
127
00:10:35,560 --> 00:10:38,670
And here you should find a file called info.plist.
127
128
00:10:38,680 --> 00:10:45,430
So if you double click on that you can see again this is an XML file and we're going to add the key
128
129
00:10:45,520 --> 00:10:51,340
and the string to this file just below where it says dict or dictionary.
129
130
00:10:51,340 --> 00:10:57,850
So we're going to pay those two lines in and now we have a dictionary of a key and a value pair.
130
131
00:10:57,880 --> 00:11:04,600
So this tells our iOS app that when we request for the user location, this is the description that we're
131
132
00:11:04,600 --> 00:11:09,320
going to give the user to tell them why we need their location.
132
133
00:11:09,430 --> 00:11:11,190
Now let's hit save.
133
134
00:11:11,200 --> 00:11:13,620
Let's close down those two files.
134
135
00:11:13,870 --> 00:11:19,660
And the last thing we have to do is to actually call this method, get location. And we're going to call
135
136
00:11:19,660 --> 00:11:24,170
it when the user presses on that button that says get location,
136
137
00:11:24,220 --> 00:11:31,330
so right here in the onPressed. And in here I'm going to call get location and now we're ready to test
137
138
00:11:31,330 --> 00:11:31,900
our app.
138
139
00:11:31,990 --> 00:11:38,380
And before you test it, I recommend just stopping the current app from running and then starting it from
139
140
00:11:38,380 --> 00:11:45,460
cold because we added in our dependencies and we messed around with the Android manifest and the iOS
140
141
00:11:45,460 --> 00:11:46,310
plist.
141
142
00:11:46,540 --> 00:11:47,920
It's usually a good idea
142
143
00:11:47,920 --> 00:11:53,290
once you've done that to just start it from scratch. It takes a little bit longer but there's a lot of
143
144
00:11:53,290 --> 00:11:55,720
things that has to link up behind the scenes.
144
145
00:11:55,720 --> 00:12:02,770
So now that our app is up and running when I click on this button get location, it should call that get
145
146
00:12:02,770 --> 00:12:03,660
location method
146
147
00:12:03,700 --> 00:12:08,970
I created this now and it should fetch our current position and print it out into the console.
147
148
00:12:09,370 --> 00:12:15,580
But the first thing it will do when I click on the button is to ask me for permission to give it my
148
149
00:12:15,580 --> 00:12:16,700
current location.
149
150
00:12:16,900 --> 00:12:25,090
So make sure that you click allow at this step. And now it should print out my latitude and longitude
150
151
00:12:25,420 --> 00:12:30,780
into the console. Now where does that location come from?
151
152
00:12:30,780 --> 00:12:37,890
Well if you're using a simulator, it usually comes from a default location that set to the Apple headquarters,
152
153
00:12:37,890 --> 00:12:44,460
so somewhere in cupertino. If you're running your app on Android then you can click on these three dots
153
154
00:12:44,460 --> 00:12:45,510
right at the bottom here.
154
155
00:12:46,050 --> 00:12:53,490
And this gets you into the extended controls and you can select on the location tab to set the latitude
155
156
00:12:53,490 --> 00:12:54,320
and longitude
156
157
00:12:54,450 --> 00:12:56,960
you want this phone to report from.
157
158
00:12:56,970 --> 00:13:02,340
You can manually set and send the location data to your app.
158
159
00:13:02,340 --> 00:13:08,310
Now at this point, it's worth mentioning that if you are running your phone on Android and you're seeing
159
160
00:13:08,310 --> 00:13:14,610
some errors in the console relating to something about Android X, then be sure to head into the course
160
161
00:13:14,610 --> 00:13:21,570
resources where there's a link to this resource on the Flutter documentation talking about how to make
161
162
00:13:21,570 --> 00:13:24,020
your app AndroidX compatible.
162
163
00:13:24,030 --> 00:13:26,570
Now this issue won't affect everybody.
163
164
00:13:26,610 --> 00:13:32,040
It's only if your app actually crashes and it refuses to build.
164
165
00:13:32,250 --> 00:13:37,620
So that was how easy it is to actually get the current GPS location.
165
166
00:13:37,830 --> 00:13:41,650
And if you think about it, behind the scenes a lot of things had to happen.
166
167
00:13:41,760 --> 00:13:49,170
The iOS counterpart had to talk to the iOS operating system to be able to get the location from that
167
168
00:13:49,170 --> 00:13:56,400
device and the Android part had to talk to the Android OS and get the location in a completely different
168
169
00:13:56,400 --> 00:13:56,730
way.
169
170
00:13:57,030 --> 00:14:03,660
But we were able to do that by simply using the geolocator package which has taken care of all of that
170
171
00:14:03,660 --> 00:14:10,660
for us. And we didn't really have to do anything other than simply add it into our project.
171
172
00:14:10,770 --> 00:14:16,710
And if you're curious how geolocator manages to do this then you can head into the external libraries
172
173
00:14:16,710 --> 00:14:22,670
folder and go into your Flutter plugins and expand the geolocator library.
173
174
00:14:22,680 --> 00:14:26,260
Now here you'll see an iOS and an Android project.
174
175
00:14:26,460 --> 00:14:33,030
If you expand the iOS project and go into the classes, you can see that there's a whole bunch of files
175
176
00:14:33,030 --> 00:14:41,130
in here that are written in Swift to work with the iOS location API to be able to grab the location
176
177
00:14:41,130 --> 00:14:44,350
data and to be able to return it to you.
177
178
00:14:44,490 --> 00:14:50,190
Now similarly if you have a look inside the Android folder and you go into src.main and then
178
179
00:14:50,190 --> 00:14:56,730
go into the Java folder, there's both a data folder and a task and a utils folder.
179
180
00:14:56,730 --> 00:15:02,040
And it's here where there's all this Java code that's been written to be it to deal with the Android
180
181
00:15:02,040 --> 00:15:06,720
location manager and to be able to fetch that location data for you.
181
182
00:15:06,780 --> 00:15:12,780
Now you can imagine writing all of this Java code and all of this Swift code not only takes a lot of
182
183
00:15:12,780 --> 00:15:20,550
expertise but also takes a lot of time. But because the author of this plugin has very kindly packaged
183
184
00:15:20,550 --> 00:15:28,800
it into a really simple to use plugin, we're able to piggyback on all of that hard work simply by importing
184
185
00:15:28,800 --> 00:15:32,000
it and calling just one line of code.
185
186
00:15:32,340 --> 00:15:37,590
And hopefully when you build some custom functionality that you think other people might find helpful
186
187
00:15:37,830 --> 00:15:43,140
you'll also create a package around it so that you can share it with other Flutter developers and pay
187
188
00:15:43,140 --> 00:15:44,330
it forward.
188
189
00:15:44,490 --> 00:15:52,530
But for now, I want to focus on these two keywords that we've never seen before, async and await. In order
189
190
00:15:52,530 --> 00:15:57,860
to understand this we have to learn all about synchronous and asynchronous programming.
190
191
00:15:57,930 --> 00:16:02,210
So we have to understand what's actually going on here in this code.
191
192
00:16:02,430 --> 00:16:06,930
head over to the next lesson and let's learn all about asynchronous programming.
22405
Can't find what you're looking for?
Get subtitles in any language from opensubtitles.com, and translate them here.