Chapter 9. Accessing Native Phone Features

The main thing that sets hybrid apps apart from ordinary, mobile-friendly web apps is the ability to interact with the operating system and hardware of the underlying mobile device. Modern devices offer a plethora of services to app developers, from GPS and database functionality to Bluetooth, NFC, and other communication technologies. Making good use of these services allows us to build apps that meet the needs of mobile users in the best way possible.

In this chapter, we will continue building on the brief introduction to mobile services that we saw in the last chapter, and we'll do some refreshing as necessary. Our goal is to use the GPS receiver, which is one of the most ubiquitous smartphone features, in order to build a simple navigation app. In doing so, we will also get familiar with a new, fundamental AngularJS component called the directive.

Creating the project

We will start off by setting up the basic structure of our app. As before, we will go for a blank project and build our app from scratch to make sure that we understand how everything works:

  1. Create a new project folder for your app. Next, enter into the folder and execute the following from your terminal or command line:
    ionic start superNav blank
    
  2. Ionic will now download and configure everything you need in order to deploy a basic app (albeit not a very interesting one). You can see what it looks like by going into your project folder and executing the following command:
    ionic serve -l
    

    The output of this command is shown in the following screenshot:

    Creating the project

Now that we have the basics in place, let's start adding some basic functionality.

Creating the basic app structure

We want to keep our app as simple as possible—a single screen with a map, together with a toolbar where we can place buttons for various utilities, such as finding the user's current location.

Let's create a basic view that meets this requirement.

Open your app's index.html file and make sure that it looks like the following:

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no, width=device-width">
    <title></title>

    <link href="lib/ionic/css/ionic.css" rel="stylesheet">
    <link href="css/style.css" rel="stylesheet">

    <!-- ionic/angularjs js -->
    <script src="lib/ionic/js/ionic.bundle.js"></script>

    <!-- cordova script (this will be a 404 during development) -->
    <script src="cordova.js"></script>

    <script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyB16sGmIekuGIvYOfNoW9T44377IU2d2Es&sensor=true"></script>

    <!-- your app's js -->
    <script src="js/app.js"></script>
  </head>

  <body ng-app="supernav" ng-controller="MapCtrl">
    <ion-header-bar class="bar-stable">
      <h1 class="title">SuperNav</h1>
    </ion-header-bar>

    <ion-content scroll="false">
      <div id="map"></div>
    </ion-content>

    <ion-footer-bar class="bar-stable">
    </ion-footer-bar>
  </body>
</html>

The browser preview should now look like this (if you closed the server after the previous step, feel free to start it up again and leave it running; it will automatically load any changes made to the underlying sources):

Creating the basic app structure

A little bit more content, but nothing exciting as of yet. Have patience; we are getting there.

Integrating Google Maps into the app

Next, we want to integrate the most essential feature of our UI—the map. To do so, we will use Google Maps, one of the most popular map services.

If you have ever used the Google Maps application on a mobile device or checked directions to a location on Google, you are already familiar with what Google Maps looks like and some of what it can do. In essence, Google Maps is a complete package that offers everything—scalable maps, satellite imagery, geocoding, and much more. For our purposes here, it is perfect.

To integrate Google Maps into the app , we need to import the Google Maps JavaScript SDK, which is freely available. To do so, add the following import to the index.html file:

<script src="https://maps.googleapis.com/maps/api/js?sensor=true"></script>

Next, we will need to designate an area of the UI where the app should be drawn. Change the existing div id tag to the following:

<div id="map" ng-controller="MapCtrl"></div>

In order to render the map properly, we will need to add some custom CSS to force the map to fill its parent container. Open the www/css/style.css file and add the following to it:

#map {
  display: block;
  width: 100%;
  height: 100%;
}

.scroll {
  height: 100%;
}

Also note that we added a binding for a controller for our map. We will use this in order to perform the initial configuration needed in order to render and work with the map. So, let's go ahead and add it! Create the www/js/controllers.js file in your project and make sure that it contains the following:

angular.module('supernav.controllers', [])
.controller('MapCtrl', function ($scope) {
  $scope.mapCreated = function (map) {
    $scope.map = map;
  };

  function initialize() {
    var mapOptions = {
      center: new google.maps.LatLng(57.661577, 11.914768),
      zoom: 16,
      mapTypeId: google.maps.MapTypeId.TERRAIN
    };

    $scope.map = new google.maps.Map(
      document.getElementById('map'), mapOptions
    );

    $scope.onCreate({map: map});

    }

    if (document.readyState === "complete") {
      initialize();
    } else {
    google.maps.event.addDomListener(window, 'load', initialize);
    }
});

Here, we defined a new supernav.controllers module, which will contain the controllers of our app. For now, it only has one such controller—MapCtrl. Let's go through it and consider what it does:

  1. We first defined the map scope variable, which will be used to simply refer to the map that we are working with. We also defined a scope function in order to bind a value to this variable.
  2. We defined the initialize local function, which will be used in order to set up and configure a Google Maps instance as follows:
    • Here, we defined the mapOptions object, which provides the initial settings for the map to be created. It has the following properties:

      center: This property includes latitude and longitude coordinates for the point on the Earth's surface on which the map will initially be centered on. The coordinate pair is passed as an instance of Google Maps' own LatLng object.

      zoom: This is the degree of zooming the location that needs to be applied to the map.

      mapTypeId: This is the kind of map that we want to show. Google Maps supports several different view modes, ranging from raw satellite imagery to detailed views of roads, businesses, and more.

    • We then created the actual Map object. We pass the following to its constructor:

      This is the part of the Document Object Model (DOM) where we want to bind the map. In our case, it is the div with the map ID, which was earlier defined in our view. We used the standard getElementById DOM function in order to retrieve a reference.

      Then we have mapOptions that we defined earlier.

      Finally, after the map has been created, we bind it to the map scope object that we defined earlier.

  3. Finally, if the DOM is fully loaded, we attempt to execute the initialize function that we just defined. If the DOM is not ready yet, we instead register it as a callback that needs to be run once it is.
  4. All we need to do now is make sure that the controller is properly loaded and put in charge of the map. To do so, first make sure that the JavaScript file is imported by adding the following to your index.html file:
    <script src="js/controllers.js"></script>
  5. Next, modify the app.js file in order to make sure that the module is listed as a dependency, as follows:
    angular.module('supernav', ['ionic', 'supernav.controllers'])

That's it! The browser preview should now look like this:

Integrating Google Maps into the app

We have come pretty far already. While we do not have any advanced navigation capabilities yet, we have successfully built a basic app that people can use just for the purpose of browsing the maps of the world. Not bad for work that took just 10 minutes!

Before we move on though, it is worth pausing and considering the architectural road that we have travelled so far. Everything we have done here is standard AngularJS practice—create a view for the element that we want to display (in this case, a map), create a controller for it and some logic, and activate the controller by integrating the map into the app. However, you may recall that we mentioned earlier in the book that the the greatest advantage of AngularJS is the creation of enhanced HTML. We have already seen how this works through data binding, live DOM updates, and other things. However, AngularJS also offers us the ability to define custom HTML tags in order to define elements, which can be reused in several parts of the application. Our map, which we created here, is a good candidate. What if we could just encapsulate it in a <map> tag? We can, and to get there, we need to talk about directives.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.225.57.126