Thursday, January 17, 2019

Ionic - Cordova Geolocation

This plugin is used for adding a geolocation plugin to the Ionic app.

Using Geolocation

There is a simple way to use the geolocation plugin. We need to install this plugin from the command prompt window.
C:\Users\Username\Desktop\MyApp>cordova plugin add cordova-plugin-geolocation
The following controller code is using two methods. The first one is the getCurrentPosition method and it will show us the current latitude and longitude of the user’s device. The second one is the watchCurrentPositionmethod that will return the current position of the device when the position is changed.

Controller Code

.controller('MyCtrl', function($scope, $cordovaGeolocation) {
   var posOptions = {timeout: 10000, enableHighAccuracy: false};
   $cordovaGeolocation
   .getCurrentPosition(posOptions)
 
   .then(function (position) {
      var lat  = position.coords.latitude
      var long = position.coords.longitude
      console.log(lat + '   ' + long)
   }, function(err) {
      console.log(err)
   });

   var watchOptions = {timeout : 3000, enableHighAccuracy: false};
   var watch = $cordovaGeolocation.watchPosition(watchOptions);
 
   watch.then(
      null,
  
      function(err) {
         console.log(err)
      },
    function(position) {
         var lat  = position.coords.latitude
         var long = position.coords.longitude
         console.log(lat + '' + long)
      }
   );

   watch.clearWatch();
})
You might have also noticed the posOptions and watchOptions objects. We are using timeout to adjust maximum length of time that is allowed to pass in milliseconds and enableHighAccuracy is set to false. It can be set to trueto get the best possible results, but sometimes it can lead to some errors. There is also a maximumAge option that can be used to show how an old position is accepted. It is using milliseconds, the same as timeout option.
When we start our app and open the console, it will log the latitude and longitude of the device. When our position is changed, the lat and long values will change.

Ionic - Cordova Native Audio

This plugin is used for adding native audio sounds to the Ionic app.

Using Native Audio

To be able to use this plugin, we first need to install it. Open the command prompt window and add the Cordova plugin.
C:\Users\Username\Desktop\MyApp>cordova plugin add cordova-plugin-nativeaudio
Before we start using this plugin, we will need audio file. For simplicity, we will save our click.mp3 file inside the js folder, but you can place it wherever you want.
The next step is to preload the audio file. There are two options available, which are −
  • preloadSimple − It is used for simple sounds that will be played once.
  • preloadComplex − It is for sounds that will be played as looping sounds or background audio.
Add the following code to your controller to preload an audio file. We need to be sure that the Ionic platform is loaded before we can preload the audio file.

Controller Code

$ionicPlatform.ready(function() {
   $cordovaNativeAudio
   .preloadSimple('click', 'js/click.mp3')
 
   .then(function (msg) {
      console.log(msg);
   }, function (error) {
      console.log(error);
   });

   $cordovaNativeAudio.preloadComplex('click', 'js/click.mp3', 1, 1)
 .then(function (msg) {
      console.log(msg);
   }, function (error) {
      console.error(error);
   });
});
In the same controller, we will add code for playing audio. Our $timeoutfunction will stop and unload looping audio after five seconds.
$scope.playAudio = function () {
   $cordovaNativeAudio.play('click');
};

$scope.loopAudio = function () {
   $cordovaNativeAudio.loop('click');

   $timeout(function () {
      $cordovaNativeAudio.stop('click');
      $cordovaNativeAudio.unload('click');
   }, 5000);
}
The last thing we need is to create buttons for playing and looping audio.

HTML Code

<button class = "button" ng-click = "playAudio()">PLAY</button>

<button class = "button" ng-click = "loopAudio()">LOOP</button>
When we tap on play button, we will hear the sound once and when we tap on the loop button, the sound will loop for five seconds and then stop. This plugin works only on an emulator or a mobile device.

Ionic - Cordova InAppBrowser

The Cordova InAppBrowser plugin is used to open external links from your app inside a web browser view.

Using Browser

It is very easy to start working with this plugin. All you need to do is to open the command prompt window and install the Cordova plugin.
C:\Users\Username\Desktop\MyApp>cordova plugin add org.apache.cordova.inappbrowser
This step allows us to start using the inAppBrowser. We can now create a button that will lead us to some external link, and add a simple function for triggering the plugin.

HTML Code

<button class = "button" ng-click = "openBrowser()">OPEN BROWSER</button>

Controller Code

.controller('MyCtrl', function($scope, $cordovaInAppBrowser) {
   var options = {
      location: 'yes',
      clearcache: 'yes',
      toolbar: 'no'
   };
   
   $scope.openBrowser = function() {
      $cordovaInAppBrowser.open('http://ngcordova.com', '_blank', options)
  
      .then(function(event) {
         // success
      })
  
      .catch(function(event) {
         // error
      });
   }
})
When the user taps the button the InAppBrowser will open the URL we provided.
Ionic Cordova InAppBrowser
Several other methods can be used with this plugin, some of which are in the following table.

Cordova $inAppBrowser Methods

MethodParametersTypeDetails
setDefaultOptions(parameter1)optionsobjectUsed to set global options for all InAppBrowsers.
open(parameter1, parameter2, parameter3)URL, target, optionsstring, string, objectThere are three targets available. _blank will open new inAppBrowser instance. _system will open system browser and _self will use current browser instance.
close//Used to close InAppBrowser.

Cordova InAppBrowser Events

This plugin also offers events that can be combined with $rootScope.
ExampleDetails
$rootScope.$on('$cordovaInAppBrowser:loadstart', function(e, event));Called when inAppBrowser start loading the page.
$rootScope.$on('$cordovaInAppBrowser:loadstop', function(e, event));Called when inAppBrowser has finished loading the page.
$rootScope.$on('$cordovaInAppBrowser:loaderror', function(e, event));Called when inAppBrowser has encountered error.
$rootScope.$on('$cordovaInAppBrowser:exit', function(e, event));Called when inAppBrowser window is closed.

Ionic - Cordova Facebook

This plugin is used for connecting to Facebook API. Before you start integrating Facebook, you need to create a Facebook app here. You will create a web app and then skip the quick start screen. Then, you need to add the website platform on the settings page. You can use the following code snippet for the site URL while in development.
http://localhost:8100/
After that, you need to add Valid OAuth redirect URIs on the settings/advanced page. Just copy the following two URLs.
https://www.facebook.com/connect/login_success.html
http://localhost:8100/oauthcallback.html

Installing Facebook Plugin

We did all the steps above to tackle some issues that often appear when using this plugin. This plugin is hard to set up because there are a lot of steps involved and documentation doesn't cover all of them. There are also some known compatibility issues with other Cordova plugins, so we will use Teleric verified plugin version in our app. We will start by installing browser platform to our app from the command prompt.
C:\Users\Username\Desktop\MyApp>ionic platform add browser
Next, what we need to do is to add the root element on top of the body tag in index.html.

index.html

<div id = "fb-root"></div>
Now we will add Cordova Facebook plugin to our app. You need to change APP_ID and APP_NAME to match the Facebook app you created before.
C:\Users\Username\Desktop\MyApp>cordova -d plugin add 
   https://github.com/Telerik-Verified-Plugins/Facebook/ 
   --variable APP_ID = "123456789" --variable APP_NAME = "FbAppName"
Now open index.html and add the following code after your body tag. Again you need to make sure that the appId and version are matching the Facebook app you created. This will ensure that Facebook SDK is loaded asynchronously without blocking the rest of the app.

index.html

<script>
   window.fbAsyncInit = function() {
      FB.init({
         appId      : '123456789',
         xfbml      : true,
         version    : 'v2.4'
      });
   };

   (function(d, s, id) {
      var js, fjs = d.getElementsByTagName(s)[0];
      if (d.getElementById(id)) {return;}
      js = d.createElement(s); js.id = id;
      js.src = "//connect.facebook.net/en_US/sdk.js";
      fjs.parentNode.insertBefore(js, fjs);
   }(document, 'script', 'facebook-jssdk'));
</script>

Angular Service

Since we installed everything, we need to create service that will be our connection to the Facebook. These things can be done with less code inside the controller, but we try to follow the best practices, so we will use Angular service. The following code shows the entire service. We will explain it later.

services.js

.service('Auth', function($q, $ionicLoading) {
   this.getLoginStatus = function() {
      var defer = $q.defer();
      
      FB.getLoginStatus(function(response) {
     if (response.status === "connected") {
            console.log(JSON.stringify(response));
         } else {
            console.log("Not logged in");
         }
      });

      return defer.promise;
   }
   this.loginFacebook = function() {
      var defer = $q.defer();

      FB.login(function(response) {
     if (response.status === "connected") {
            console.log(JSON.stringify(response));
         } else {
            console.log("Not logged in!");
         }
      });

      return defer.promise;
   }
   this.logoutFacebook = function() {
      var defer = $q.defer();

      FB.logout(function(response) {
         console.log('You are logged out!');
      });

      return defer.promise;
   }
   this.getFacebookApi = function() {
      var defer = $q.defer();

      FB.api("me/?fields = id,email", [], function(response) {
  
         if (response.error) {
            console.log(JSON.stringify(response.error));
         } else {
            console.log(JSON.stringify(response));
         }
      });

      return defer.promise;
   }
});
In the above service, we are creating four functions. First three are self-explanatory. The fourth function is used for connecting to Facebook graph API. It will return the id and email from the Facebook user.
We are creating promise objects to handle asynchronic JavaScript functions. Now we need to write our controller that will call those functions. We will call each function separately for better understanding, but you will probably need to mix some of them together to get the desired effect.

Controller Code

.controller('MyCtrl', function($scope, Auth, $ionicLoading) {
   
   $scope.checkLoginStatus = function() {
      getLoginUserStatus();
   }

   $scope.loginFacebook = function(userData) {
      loginFacebookUser();
   };

   $scope.facebookAPI = function() {
      getFacebookUserApi();
   }

   $scope.logoutFacebook = function() {
      logoutFacebookUser();
   };

   function loginFacebookUser() {
      return Auth.loginFacebook();
   }

   function logoutFacebookUser() {
      return Auth.logoutFacebook();
   }

   function getFacebookUserApi() {
      return Auth.getFacebookApi();
   }

   function getLoginUserStatus() {
      return Auth.getLoginStatus();
   }
})
You are probably wondering why didn't we returned Auth service directly from the function expressions (first four functions). The reason for this is that you will probably want to add some more behavior after the Auth function is returned. You might send some data to your database, change the route after login, etc. This can be easily done by using JavaScript then() method to handle all the asynchronous operations instead of callbacks.
Now we need to allow users to interact with the app. Our HTML will contain four buttons for calling the four functions we created.

HTML Code

<button class = "button" ng-click = "loginFacebook()">LOG IN</button>
<button class = "button" ng-click = "logoutFacebook()">LOG OUT</button>
<button class = "button" ng-click = "checkLoginStatus()">CHECK</button>
<button class = "button" ng-click = "facebookAPI()">API</button>
When the user taps the LOG IN button, the Facebook screen will appear. The user will be redirected to the app after the login is successful.
Ionic Cordova Facebook