I need to make an application which alert on the user when the user enters a particular geofenced area. I tried cordova geofencing plugin. But it doesn't work when I enter the area. I don't know what is the problem. Here are my codes.
app.js
// Ionic Starter App
// angular.module is a global place for creating, registering and retrieving Angular modules
// 'starter' is the name of this angular module example (also set in a <body> attribute in index.html)
// the 2nd parameter is an array of 'requires'
angular.module('starter', ['ionic','ngCordova'])
.run(function($ionicPlatform) {
$ionicPlatform.ready(function () {
// $log.log('Ionic ready');
// Hide the accessory bar by default (remove this to show the accessory bar above the keyboard
// for form inputs)
if ($window.cordova && $window.cordova.plugins.Keyboard) {
cordova.plugins.Keyboard.hideKeyboardAccessoryBar(true);
}
if ($window.StatusBar) {
StatusBar.styleDefault();
}
if ($window.geofence) {
$window.geofence.initialize();
$window.geofence.onTransitionReceived = function (geofences) {
// $log.log(geofences);
if (geofences) {
$rootScope.$apply(function () {
geofences.forEach(function (geo) {
geo.notification = geo.notification || {
title: 'Geofence transition',
text: 'Without notification'
};
// toaster.pop('info', geo.notification.title, geo.notification.text);
});
});
}
};
$window.geofence.onNotificationClicked = function (notificationData) {
$log.log(notificationData);
if (notificationData) {
$rootScope.$apply(function () {
// toaster.pop('warning', 'Notification clicked', notificationData.notification.text);
});
}
};
}
});
})
//Entering Zandig
window.geofence.addOrUpdate({
id: "e941166e-2409-4c97-8c80-14ba9e9d71c9",
latitude: 12.958535143383823,
longitude: 77.6381016522646,
radius: 5,
transitionType: 1
}).then(function () {
document.getElementById("notification").innerHTML= "Reached Zandig";
console.log('Geofence successfully added');
}, function (reason) {
console.log('Adding geofence failed', reason);
});
//Leaving Trivandrum
window.geofence.addOrUpdate({
id: "1e473337-4747-4ac3-b921-ccaf572f38ce",
latitude: 8.487695348115592,
longitude: 76.95057034492493,
radius: 3,
transitionType: 2
}).then(function () {
document.getElementById("notification").innerHTML= "Left Trivandrum";
console.log('Geofence successfully added');
}, function (reason) {
console.log('Adding geofence failed', reason);
});
//Entering 61
window.geofence.addOrUpdate({
id: "8f8119ce-b577-4f22-9880-57333fcff5de",
latitude: 12.9593547,
longitude: 77.63604520000001,
radius: 5,
transitionType: 1
}).then(function () {
document.getElementById("notification").innerHTML= "Entered 61";
console.log('Geofence successfully added');
}, function (reason) {
console.log('Adding geofence failed', reason);
});
//Entering Santhi Sagar
window.geofence.addOrUpdate({
id: "d2c08c58-4f31-44e9-8a5c-8baaae3ebee3",
latitude: 12.960690294723518,
longitude: 77.63856634497643,
radius: 15,
transitionType: 1
}).then(function () {
document.getElementById("notification").innerHTML= "Entered Santhi Sagar";
console.log('Geofence successfully added');
}, function (reason) {
console.log('Adding geofence failed', reason);
});
//Leaving Santhi Sagar
window.geofence.addOrUpdate({
id: "6923cf7d-470e-4921-9b54-4516c504cba5",
latitude: 12.960690294723518,
longitude: 77.63856634497643,
radius: 15,
transitionType: 2
}).then(function () {
document.getElementById("notification").innerHTML= "Left Santhi Sagar";
console.log('Geofence successfully added');
}, function (reason) {
console.log('Adding geofence failed', reason);
});
//Getting watched from device
window.geofence.getWatched().then(function (geofencesJson) {
var geofences = JSON.parse(geofencesJson);
});
//Listening for Geofencing transitions
window.geofence.onTransitionReceived = function (geofences) {
geofences.forEach(function (geo) {
alert('Geofence transition detected');
console.log('Geofence transition detected', geo);
});
};
//When click on notification
window.geofence.onNotificationClicked = function (notificationData) {
Alert('Geofencing is Working');
console.log('App opened from Geo Notification!', notificationData);
};
Index.html
<!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">
<!-- IF using Sass (run gulp sass first), then uncomment below and remove the CSS includes above
<link href="css/ionic.app.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="js/ng-cordova.min.js"></script>
<script src="cordova.js"></script>
<!-- your app's js -->
<script src="js/app.js"></script>
</head>
<body ng-app="starter">
<ion-pane>
<ion-header-bar class="bar-stable">
<h1 class="title">Geofencing</h1>
</ion-header-bar>
<ion-content>
<p id="notification"></p>
</ion-content>
</ion-pane>
</body>
</html>
(In the Github page of the plugin, there was an option that 'unique id for geofence'. I added the unique id from UUID generator online page.)
But no alert is displaying. Can anyone help?
When I run using ionic serve, in the console, the following error found. 'Uncaught TypeError: Cannot read property 'addOrUpdate' of undefined'.
Here is my console errors with device.
0 466310 error Uncaught TypeError: Cannot read property'addOrUpdate' of undefined, htttp://192.168.43.148.8100/js/app.js, Line 28
1 466870 error No Content-Security-Policy meta tag found. Please add one when using the cordova-plugin-whitelist plugin.
2 466930 error Uncaught TypeError: object is not a function, http://192.168.43.148:8100/plugins/cordova/plugin-geofence/www.geofence.js, Line 119
Can anyone help me?
Here is a ionic sample project from authors of same plugin : https://github.com/cowbell/ionic-geofence , in it you can see total guide of how to use it in ionic. Your code should also work but you are doing few mistakes.If you want to run some plugin related code at initialization of application, put them into .run() part, you are using plugin calls out of that. Plus no need to use document.addEventListener('deviceready') as you have $ionicPlatform.ready, initialize plugin in that. Your code will be like this
angular.module('starter', ['ionic','ngCordova'])
.run(function($ionicPlatform) {
$ionicPlatform.ready(function() {
//Use your plugin related calls in this area
})
});
You were getting error of undefined because you were making plugin calls before even their object was available to application.Again, any plugin related calls which you want to run at time of initialization, use them in $ionicPlatform.ready(function() {}) .
so I see you said you tested it using ionic server. you cant test plugins via the browser, you have to actually install it on the device in order to test cordova plugins. You can also test most plugins via emulation using the intel xdk. https://software.intel.com/en-us/intel-xdk just import your project and emulate it then move to your geofenced location via the map on the right. Or you can hit the test tab and push it to a phone and test it using the intel app preview app on your iphone or android device. Last but not least you can use the debug tab to push it straight to a device using a usb cable and this will allow you to have a debugging console while you test the plugin on your device.
Related
I am new on Angular and Ionic Framework and want to incorporate the cordova email composer plugin. But failed to complete this. Here is my all code.
I did install the CLI :
ionic cordova plugin add https://github.com/katzer/cordova-plugin-email-composer.git
Index.html
<script src="lib/ionic/js/ionic.bundle.js"></script>
<script src="cordova.js"></script>
<script src="js/openfb.js"></script>
<script src="js/ngopenfb.js"></script>
<script src="js/ngCordovaOauth.js"></script>
<script src="settings.js"></script>
<script src="js/angular-translate.min.js"></script>
<script src="translate.js"></script>
<script src="js/app.js"></script>
<script src="js/services.js"></script>
<script src="js/controllers.js"></script>
<script src="js/directives.js"></script>
<script src="js/ngStorage.js"></script>
<script src="js/ionic-close-popup.js"></script>
<script src="js/angular-base64.js"></script>
App.JS
angular.module('starter', ['ionic', 'starter.services', 'starter.controllers', 'starter.translate', 'ngStorage', 'ionic.closePopup', 'ab-base64', 'ngOpenFB', 'ngCordovaOauth','starter.directive'])
Controller:
.controller('EmailController', function($scope) {
$scope.sendEmail=function(EmailAddr){
var email =
{
to: 'abcd#gmail.com',
subject: 'Test Message',
body: 'This is a test message',
isHtml: true
};
$cordovaEmailComposer.isAvailable().then(function() {
$cordovaEmailComposer.open(email).then(null, function () {
// user cancelled email
});
}, function () {
// not available
});
};
})
HTML:
<div class="list theme-forms" ng-controller="EmailController">
<button class="button button-block button-positive" ng-click="sendEmail()">SEND</button>
</div>
When clicked on SEND Button, following error displayed on chrome console and email is not sent -
ionic.bundle.js:150 ReferenceError: $cordovaEmailComposer is not defined
at b.$scope.sendEmail (controllers.js:746)
at fn (eval at compile (ionic.bundle.js:260), <anonymous>:4:218)
at ionic.bundle.js:472
at b.$eval (ionic.bundle.js:176)
at b.$apply (ionic.bundle.js:177)
at HTMLButtonElement.<anonymous> (ionic.bundle.js:472)
at Pf (ionic.bundle.js:70)
at HTMLButtonElement.d (ionic.bundle.js:70)
at n (ionic.bundle.js:22)
at t (ionic.bundle.js:22)
Could you help to give a hint what I have missed here?
EDIT 1
Now I've added following js file on index.html
js/ng-cordova.min.js
js/email_composer.js // form Plugin files
and getting error console -
require is not defined
When Click on SEND Button -
TypeError: Cannot read property 'isAvailable' of undefined
try to use this plugin:-
http://ngcordova.com/docs/plugins/emailComposer/
module.controller('ThisCtrl', function($cordovaEmailComposer) {
$cordovaEmailComposer.isAvailable().then(function() {
// is available
}, function () {
// not available
});
var email = {
to: 'max#mustermann.de',
cc: 'erika#mustermann.de',
bcc: ['john#doe.com', 'jane#doe.com'],
attachments: [
'file://img/logo.png',
'res://icon.png',
'base64:icon.png//iVBORw0KGgoAAAANSUhEUg...',
'file://README.pdf'
],
subject: 'Cordova Icons',
body: 'How are you? Nice greetings from Leipzig',
isHtml: true
};
$cordovaEmailComposer.open(email).then(null, function () {
// user cancelled email
});
});
In a real-life project, I'm trying to populate an Angular ui-grid using WebAPI to get JSON data has HTML content. So far, the column has HTML is either showing them as plain text or blank content.
Followed this still not getting it work:
How to render html formatted content in ng-grid?
Here are my code:
Index.html (script are downloaded to local)
<script type="text/javascript" src="/scripts/jquery-1.7.2.min.js"></script>
<script src="/scripts/angular-1.5.0.js"></script>
<script src="/scripts/angular-touch-1.5.0.js"></script>
<script src="/scripts/angular-animate-1.5.0.js"></script>
<script src="/scripts/angular-sanitize-1.5.0.min.js"></script>
<script src="/scripts/angular-bind-html-compile.js"></script>
<script src="/scripts/csv.js"></script> <!-- 2013 -->
<script src="/scripts/pdfmake.js"></script>
<script src="/scripts/vfs_fonts.js"></script>
<script src="/scripts/ui-grid.min.js"></script> <!-- v3.2.9-->
<link rel="stylesheet" type="text/css" href="/content/ui-grid.css"/><!-- v3.2.9 - 2016-09-21-->
<script src="/scripts/myAngular.js"></script>
<div ng-controller="getHomeMsg">
<div id="grid1" ui-grid="grdAngHomeMsg" class="Agrid"></div>
</div>
myAngular.js
var myApp = angular.module('app', ['ngTouch', 'ui.grid', 'ngSanitize', 'angular-bind-html-compile']);
myApp.controller('getHomeMsg', function($scope, $http, $sce) // prefix function() with ['$scope', '$http', '$sce', ... got the same result
{
$scope.grdAngHomeMsg = {};
$scope.grdAngHomeMsg.columnDefs = [
{
name: 'Subject',
cellTemplate: '<div class="ui-grid-cell-contents" bind-html-compile="COL_FIELD"></div>' //'<div ng-bind-html="row.entity[col.field]"></div>'
},
{
name: 'Message'
},
];
var msgData;
$http(
{
method: 'GET',
url: '/API/HomeMsg',
responseType: 'json'
}).then(function successCallback(response) {
msgData = $scope.grdAngHomeMsg.data = response.data;
$scope.grdAngHomeMsg.data.forEach(function (d) {
$sce.trustAsHtml(d.Subject); // F12 shows d.Subject has value and valid!
});
}, function errorCallback(response, statusText) {
alert(statusText);
});
// also tried replacing this cellTemplate bind-html-compile="COL_FIELD" with ng-bind-html="AA(COL_FIELD)", F12 shows this function is never called
$scope.AA = function (htm) {
return $sc.trustAsHtml(htm);
};
// it never reach here after actual API call
//msgData.forEach(function (d) {
// $sce.trustAsHtml(d.Subject);
//})
}
);
Browser = FireFox v50.1.
F12 verified data returned are in perfect JSON format.
F12 shows no error during execution, all scripts are loaded, $sce object is instantiated w/ properties including trustAsHtml method.
Other articles/examples tried including:
How do you use $sce.trustAsHtml(string) to replicate ng-bind-html-unsafe in Angular 1.2+
https://github.com/angular-ui/ui-grid/issues/1292
Spent two full days, appreciate any help!
since last week I'm triying to get notifications from FCM, using Phonegap and AngularJS .
I could do it with cordova-fcm-plugin, so now I would like to get the data from the message, they suggest use this code:
FCMPlugin.onNotification(
function(data){
if(data.wasTapped){
//Notification was received on device tray and tapped by the user.
alert( JSON.stringify(data) );
}else{
//Notification was received in foreground. Maybe the user needs to be notified.
alert( JSON.stringify(data) );
}
},
function(msg){
console.log('onNotification callback successfully registered: ' + msg);
},
function(err){
console.log('Error registering onNotification callback: ' + err);
}
);
My problem was that I have no idea how to added that code to an angular controller, so I searched on internet something similar and I found this factory
angular.module('rhoAppApp')
.factory('$FCMPlugin', $FCMPlugin);
$FCMPlugin.$inject = [];
function $FCMPlugin() {
var service = {
getToken: function(successCallback, failCallback) {
FCMPlugin.getToken(successCallback, failCallback);
},
onNotification: function(onNotification, onCallbackSuccesSet, onCallbackFailSet) {
FCMPlugin.onNotification(onNotification,
onCallbackSuccesSet, onCallbackFailSet);
}
};
return service;
}
So now my problem is use that factory in my controller, I know (maybe I'm wrong) that you have to call it from:
.controller('MainCtrl', function ($FCMPlugin) {
$FCMPlugin.something
})
But I'm not sure how to use that factory, I have never used one before.
I could solve this problem with this:
I made a build using phonegap + yeoman angular, one of the problem building with this method is that you have to include cordova.js
My problema was, that i include condorva.js inside this line
<!-- build:js(.) scripts/vendor.js -->
<!-- bower:js -->
<script src="bower_components/jquery/dist/jquery.js"></script>
<script src="bower_components/angular/angular.js"></script>
<script src="bower_components/bootstrap/dist/js/bootstrap.js"></script>
<!-- endbower -->
<!-- endbuild -->
And it is a problem because you dont want to build it in vendor.js, instead I added cordova.js out of that line:
Then I added this code to app.js to indetify when you are inside of a mobile device or web:
angular.element(document).ready(function () {
if (navigator.userAgent.match(/(iOS|iPhone|iPod|iPad|Android|BlackBerry)/)) {
document.addEventListener('deviceready', function () {
console.log('This is mobile app');
angular.bootstrap(document.body, ['moodleAppApp']);
}, false);
} else {
console.log('This is web app');
angular.bootstrap(document.body, ['moodleAppApp']);
}
});
Also I remove ng-app from index.html
All this make my angular app work with cordova.
I'm trying to send local notifications for every day at 7 am. I have placed the below code in controller,
Code
function send_push_notification (){
cordova.plugins.notification.local.schedule({
id: 10,
title: "Report",
text: "Pls send a report :-)",
firstAt: alarm_time,
at: at_8_am,
every: "day"
}).then(function (success) {
return true;
}, function (err) {
return false
});
}
But it shows ReferenceError: cordova is not defined.. I have defined
<script src="cordova.js"></script> at very first in my app's index.html file.
I also tried the example given in this http://ngcordova.com/docs/plugins/localNotification/ link. But donno which one to follow. Both are totally different.
Update:
cordova.plugins.notification.local.schedule method only works inside deviceready event listener but not in the controller. I should make it to work on controller..
ie, I have a task of sending local push notification when there is no database update made for that particular date else no need for notification.
The following sample code should get you started in sending local notifications in Android and iOS device.
index.html
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Security-Policy" content="default-src 'self' data: gap: https://ssl.gstatic.com 'unsafe-eval'; style-src 'self' 'unsafe-inline'; media-src *">
<meta name="format-detection" content="telephone=no">
<meta name="msapplication-tap-highlight" content="no">
<meta name="viewport" content="user-scalable=no, initial-scale=1, maximum-scale=1, minimum-scale=1, width=device-width">
<link rel="stylesheet" type="text/css" href="css/index.css">
<title>Hello World</title>
</head>
<body>
<h3>Local Notification</h3>
<script type="text/javascript" src="js/jquery.js"></script>
<script type="text/javascript" src="cordova.js"></script>
<script type="text/javascript" src="js/index.js"></script>
</body>
</html>
index.js
$(document).ready(function() {
document.addEventListener("deviceready", onDeviceReady, false);
});
function onDeviceReady() {
try {
cordova.plugins.notification.local.schedule({
text: "This is the text.",
at: new Date(new Date().getTime() + 10000)
});
} catch (e) {
alert("Fail " + e);
}
}
The following sample code sends out a test notification on 10th second after launching the app. The code is tested in Android and iOS devices. The above sample code is available in the github page. You can download the sample app, install notification plugin and test the same.
As suggested in my source, the following command could be used to have a forked and modified push plugin to work in your project:
cordova plugin add https://github.com/zxshinxz/PushPlugin.git
The default push plugin needs to be removed and this will be its replacement. If I understood correctly the post below, this solution fixes local notification usage also when the program is turned off.
More info on that linked post.
My source:
Cordova local notification doesn't work while app is in background
Here is a steps for running local notifications on cordova
Step : 1
Type in cmd prompt of your folder
bower install ngCordova
include in your main index.html file before cordova
<script src="lib/ngCordova/dist/ng-cordova.js"></script>
<script src="cordova.js"></script>
Step:2
Inject dependency
angular.module('myApp', ['ngCordova'])
Install this plugin
cordova plugin add https://github.com/katzer/cordova-plugin-local-notifications.git
Step:3
Here is schedule.js local notification file used in your controller
(function(){
'use strict';
angular.module('myApp').controller('Schedule',['$scope','$ionicPlatform','$rootScope','$cordovaLocalNotification','$cordovaSms',Schedule]);
function Schedule($scope,$ionicPlatform,$rootScope,$cordovaLocalNotification,$cordovaSms){
//************************Setting Notification***********************
$ionicPlatform.ready(function() {
var now = new Date().getTime();
var _10SecondsFromNow = new Date(now + 10 * 1000);
$cordovaLocalNotification.schedule({
id: 10,
title: 'Report',
text: 'Text here',
at: _10SecondsFromNow
}).then(function (result) {
// ...
});
};
$cordovaLocalNotification.add({
id: 10,
title: 'Report',
text: 'Pls send a report :-)',
firstAt: at_8_am,
every: 'day'
}).then(function (result) {
// ...
});
$scope.scheduleSingleNotification = function () {
$cordovaLocalNotification.schedule({
id: 1,
title: 'Title here',
text: 'Text here',
}).then(function (result) {
// ...
});
};
});
//*******************Notification Ended***********************
})();
I'm developing an app with backbone.js, require.js and Phonegap. I'm having problems accessing the Phonegap api from the Model. My index.html file looks like this:
<html>
<head>
<meta charset="utf-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
<link href="topcoat/css/topcoat-mobile-light.min.css" rel="stylesheet">
<link href="css/styles.css" rel="stylesheet">
<link href="css/pageslider.css" rel="stylesheet">
<script type="text/javascript" src="cordova.js"></script>
<script data-main="js/app" src="js/require.js"></script>
</head>
<body></body>
</html>
In the initialize function of the router, I'm testing the Phonegap API:
initialize: function() {
window.localStorage.setItem("key", "some bloddy value");
var value = window.localStorage.getItem("key");
console.log('the value is');
console.log(value);
}
This works fine, I can get that the value is set and is retrieved. I also have a logged in status model. This is as follows:
define(function (require) {
"use strict";
var $ = require('jquery'),
Backbone = require('backbone'),
LoginStatus = Backbone.Model.extend({
defaults: {
loggedIn: false,
api_key: null,
user_id: null
},
initialize: function () {
window.localStorage.setItem("key2", "some other value");
var value = window.localStorage.getItem("key2");
console.log('in init, the value is');
console.log(value);
},
});
return {
LoginStatus: LoginStatus
};
});
When I call instantiate model from the initialize function of the router, I get the error:
Uncaught illegal access at file:///android_asset/www/js/app/models/loginstatus.js
How can I access Phonegap api from my models?
You should add an event listener to deviceready event. Inside the listener you should start the backbone router. In that way you start using phonegap API when everything is ready.
document.addEventListener("deviceready", function(){
Backbone.history.start();
}, false);