Code a Real-Time NativeScript App: Geolocation and Google Maps

Code a Real-Time NativeScript App: Geolocation and Google Maps

NativeScript is a framework for building cross-platform native mobile apps using XML, CSS, and JavaScript. In this series, we'll try out some of the cool things you can do with a NativeScript app: geolocation and Google Maps integration, SQLite database, Firebase integration, and push notifications. Along the way, we'll build a fitness app with real-time capabilities that will use each of these features.

In this tutorial, you'll learn how to work with geolocation and Google Maps in NativeScript apps. 

I'm assuming that you already know how to create apps in NativeScript. If you're new to NativeScript, I recommend that you first check out one of the earlier tutorials in NativeScript before trying to follow this tutorial.

What You'll Be Creating

You'll be creating a walking tracker using geolocation and Google Maps. It will show the user how much distance they've covered and the number of steps they've taken to cover that distance. There will also be a map that will show the user's current location.

To give you an idea, here's what the final output will look like:

app final

Setting Up the Project

Start by creating a new NativeScript app:

To make it easier to set up the UI of the app, I've created a GitHub repo which includes both the starter and final version of the project. You can go ahead and copy the contents of the app folder to your project's app folder. We will only be working with two files: main-page.xml and main-page.js file. The rest is just boilerplate from the NativeScript demo project. 

Running the App

We will be using the Android emulator provided by Android Studio to test the app. This will allow us to use the Android GPS Emulator to simulate the changing of locations from the comfort of our own homes. I don't really like aimlessly walking around outside to test geolocation either! But if that's your thing then I won't stop you.

If you execute tns run android, it will automatically call the Android emulator if it's already installed. If it's not yet installed, you can install it by launching Android Studio, clicking configure, and selecting SDK Manager. This will open the SDK Platforms by default. Click on the SDK Tools tab and make sure to select Android Emulator, and click on Apply to install it.

To use the GPS emulator, download it from GitHub and run the executable war file:

Once that's done, you should be able to access http://localhost:8080/gpsemulator/ from your browser and connect to localhost. Make sure that the Android emulator is already running when you do this. Once you're connected, simply zoom in the map and click on any place you want to use as the location. The app will detect this and use it as its current location.

GPS Emulator

Working With Geolocation

Geolocation in NativeScript is similar to the Geolocation API in JavaScript. The only difference in functionality is the addition of a distance() function which is used for calculating the distance between two locations.

Installing the Geolocation Plugin

In order to work with geolocation, you first need to install the geolocation plugin:

Once that's done, you can now include it from your script files:

Getting the User's Current Location

The NativeScript geolocation plugin includes three functions which you can use for working with the user's current location. We will be using each of these in this app:

  • getCurrentLocation
  • watchLocation
  • distance

Open the main-view-model.js file and add the following code inside the createViewModel() function. Here we're initializing the variables that we will be using later on for storing the different values that are needed for keeping track of the user's location. 

I've added some comments in the code so you know what's going on. There are also some lines of code that are commented out; these are for the Google Maps integration. I've commented them out for now to keep things simple. Once we get to the Google Maps integration, you'll need to remove those comments.

Next, add the code for getting the user's current location. This code is executed when the user taps on the button for starting and stopping the location tracking. The geolocation.getCurrentLocation() method is used to get the current location. 

Here we've specified three options: desiredAccuracy, updateDistance, and timeoutdesiredAccuracy allows you to specify the accuracy in meters. It has two possible values: Accuracy.high, which is about 3 meters, and Accuracy.any, which is about 300 meters. updateDistance specifies how much difference (in meters) there must be between the previous location and the current location before it will update. Lastly, timeout specifies how many milliseconds to wait for a location. 

Once a location is received, we set it as the start_location and push it on the locations array. Later on, this location will be used along with the first location that will be fetched from watching the user's current location to determine the distance traveled.

Watching for the User's Current Location

To get the current location, we use the geolocation.watchLocation() function. This function is similar to the setInterval() function in JavaScript, because it also executes the callback function repeatedly until you stop it with the geolocation.clearWatch() function. The callback function is automatically called based on the updateDistance and minimumUpdateTime

In the code below, the location will be updated if it is at least 5 meters different from the previous location that was fetched. But this update will only happen every 5 seconds. This means that if the user hasn't walked 5 meters or more within 5 seconds, the location won't update. 

Once the user indicates that they want to stop tracking, you need to call the geolocation.clearWatch() function. You also need to reset the rest of the values that are being updated every time the location is changed. 

Getting the Distance Between Two Locations

Now we're ready to get the distance. This can be done by calling the geolocation.distance() function. This function accepts two location objects as its arguments, so we'll use the last two locations that were pushed to the locations array to determine the distance (in meters) traveled by the user from a previously recorded location to the current one. From there, we can use an approximate conversion from meters to the number of steps—I say approximate because not all people will travel the same distance in a single step. 

After that, we can just add the resulting distance and steps to the total_distance and total_steps so we can keep track of the total distance and steps they have taken since they started tracking their location.

At this point, you can now start testing the app using the GPS emulator that I mentioned earlier. Do note that you need to hit save on the main-view-model.js file to trigger an app reload. 

Then pick a location in the GPS emulator so that a fresh location will be fetched by the app once it loads. If you don't do this, it will default to the Googleplex location in Mountain View, California. This means that the next time you pick a location on the emulator, it will jump from this location to the location that you picked. If it's far away then you'll get a really large number for the distance and steps. 

Alternately, you could test on a real device with internet and GPS enabled. Only GPS is required at this point, but once we add Google Maps, the app will need an internet connection.

Working With Google Maps

We will now use Google Maps to add a map that shows the user's current location.

Installing the Google Maps Plugin

Once installed, you need to copy the template string resource files for Android:

Next, open the app/App_Resources/Android/values/nativescript_google_maps_api.xml file and add your own Google Maps API key (server key):

Make sure that you have enabled the Google Maps Android API from the Google Console before you try to use it.

Adding the Map

For the map, open the main-page.xml file and you should see the following:

Here we've specified three options (longitudelatitude, and zoom) and a function to execute once the map is ready. longitude and latitude specify the location you want to render in the map. The zoom specifies the zoom level of the map. mapReady is where we specify the function for adding the marker on the map. This marker represents the user's current location, so it will be rendered at the center of the map.

By default, this won't work as you haven't added the schema definition for the maps yet. So in your Page element, add the definition for the maps element:

Once that's done, a Google map instance should be rendered right below the button for tracking location. It won't have any maps yet since the latitude and longitude haven't been specified yet. To do that, go back to the main-view-model.js file and remove the comments for the lines of code for working with Google Maps:

Adding the Marker

Since we've already declared default coordinates for the marker, we can actually plot a marker once the map is ready:

Next, we need to update the marker position once the user starts tracking their location. You can do that inside the success callback function for the getCurrentLocation() function:

We also need update it when the user's location is updated (inside the success callback function for watchLocation):

Once that's done, a map which renders the default location should show in the app.

Conclusion

In this tutorial, you've created a NativeScript app that allows the user to track how much distance they have covered and the approximate number of steps they've taken to cover that distance. You've also used Google Maps to let the user view their current location. By doing so, you've learned how to use the geolocation and Google Maps plugins for NativeScript.

This is just the start! In the next posts of this series, we'll add a local database, push notifications and other cool features to our app.

In the meantime, check out some of our other posts on NativeScript and cross-platform mobile coding.

For a comprehensive introduction to NativeScript, try our video course Code a Mobile App With NativeScript. In this course, Keyvan Kasaei will show you step by step how to build a simple application. Along the way, you'll learn how to implement a simple app workflow with network requests, an MVVM architecture, and some of the most important NativeScript UI components. By the end, you'll understand why you should consider NativeScript for your next mobile app project.

 

Source: Tuts Plus

About the Author