I want to check the location and store the required data in the internal storage of the mobile. To stop this task, use has to tap stop button in the main ui. As this task started, no matter the state of the app, that task should do its work.
I can implement this using native android command. But I want to implement this using cordova and I can't figure out a way to do this..
If this task cannot be done using cordova, can I do it using native android and inject to the cordova app..??
Please help..
You can do this using the ng-cordova geolocation watcher, it watches geolocation properties such as lat, lon, and speed.
first intall ng-cordova and inject it
bower install ngCordova
angular.module('myApp', ['ngCordova'])
then install the geolocation plugin
cordova plugin add org.apache.cordova.geolocation
then you want to create a watcher, make sure to fire it after a device ready event or it will cause problems
This is what device ready function looks like
document.addEventListener("deviceready", function () {
$cordovaPlugin.someFunction().then(success, error);
}, false);
here is the watcher controller:
module.controller('GeoCtrl', function($cordovaGeolocation) {
var watchOptions = {
frequency : 1000,
timeout : 3000,
enableHighAccuracy: false // may cause errors if true
};
var watch = $cordovaGeolocation.watchPosition(watchOptions);
watch.then(
null,
function(err) {
// error
},
function(position) {
var lat = position.coords.latitude
var long = position.coords.longitude
});
watch.clearWatch();
// OR
$cordovaGeolocation.clearWatch(watch)
.then(function(result) {
// success
}, function (error) {
// error
});
});
As you watch their geolocation info you can push it into a local database like http://pouchdb.com/ or couch db or a server database. If you want to use this in any state of the app you can make it into a service,
here is an example in a app i built
service.watchSpeed = function () {
console.log('watcher');
ionic.Platform.ready(function () {
var watchOptions = {
frequency: 15 * 60 * 1000,
timeout: 1 * 60 * 1000,
enableHighAccuracy: true // may cause errors if true
};
service.watch = $cordovaGeolocation.watchPosition(watchOptions);
service.watch.then(
null,
function (err) {
service.watchSpeed();
},
function (position) {
if (service.maxspeed.ToUseApp !== 0) {
var lat = position.coords.latitude;
var long = position.coords.longitude;
var speed = position.coords.speed;
service.speed = speed;
if (speed > service.maxspeed.ToUseApp) {
$state.go('overspeed');
}
if ($ionicHistory.currentStateName() === 'overspeed' && speed < service.maxspeed.ToUseApp) {
$ionicHistory.goBack();
}
} else {
console.log('speed watcher has been killed, why master??');
}
});
});
};
then in my home controller i call the watcher
ionic.Platform.ready(function () {
ffService.getMaxSpeed();
});
Related
I am creating a log file, and then saving the coordinates when app run in background through backgroundGeolocation. The problem is when app runs in background mode then it's not saving the coords in log file, actually I am doing this for testing purposes that does this plugin working fine or not.
document.addEventListener("deviceready",onDeviceReady,false);
// PhoneGap is ready to be used!
//
function onDeviceReady() {
window.logToFile.setLogfilePath('/myapp/log.txt', function () {
backgroundGeolocation.configure(callbackFn, failureFn, {
desiredAccuracy: 10,
stationaryRadius: 20,
distanceFilter: 30,
interval: 60000
});
backgroundGeolocation.start();
}, function (err) {
// logfile could not be written
// handle error
});
var callbackFn = function(location) {
window.logToFile.debug('[js] BackgroundGeolocation callback: ' + location.latitude + ',' + location.longitude);
backgroundGeolocation.finish();
};
var failureFn = function(error) {
console.log('BackgroundGeolocation error');
};
}
I'm trying to get current geolocation in Ionic 2 to work on Android devices. In the browser it works well, but when I run the ionic cordova run android command to deploy on device the geolocation doesn't execute at all, and I get the following errors:
Angular 2 is running in the development mode. Call enableProdMode() to enable the production mode. main.js:48746
Native: deviceready did not fire within 2000ms. This can happen when plugins are in an inconsistent state. Try removing plugins from plugins/ and reinstalling them. cordova.js:1223 (anonymous) # main.js:48746
deviceready has not fired after 5 seconds. main.js:48741
DEVICE READY FIRED AFTER 3656 ms main.js:119892
Ionic Native: deviceready event fired after 3519 ms main.js:122839
Ionic Storage driver: asyncStorage main.js:50230
navigator.geolocation works well main.js:8291
PlacesPage ionViewDidLoad error: this.getGeolocation is not a function
Mainly, what I don't understand is that I get the this.getGeolocation is not a function because how did that change from browser to device?
import { Geolocation } from '#ionic-native/geolocation';
...
constructor(private geolocation: Geolocation) {}
...
ionViewDidLoad() {
if(this.platform.is('cordova') === true){
document.addEventListener("deviceready", onDeviceReady, false);
}else{
console.log('Browser geolocation')
this.getGeolocation();
}
function onDeviceReady() {
console.log("navigator.geolocation works well");
this.getGeolocation();
}
}
getGeolocation(){
console.log('Starting Geolocation');
var options = {
enableHighAccuracy: true
};
this.geolocation.getCurrentPosition(options)
.then((position) => {
console.log('Geolocation successful');
this.currentLocation = {
lat: position.coords.latitude,
lng: position.coords.longitude
};
let query = '?lat=' + position.coords.latitude + '&lng=' + position.coords.longitude;
this.updatePlaces(query);
}).catch((error) => {
console.log('Error getting location', error);
});
}
I have tried removing all plugins and reinstalling them. I have added a Content-Security-Policy to index.html.
Can anybody tell me what's wrong or guide me in a right direction? Thanks.
your code doesn't seems correct to me. Change your code to below:
import { Geolocation } from '#ionic-native/geolocation';
...
constructor(private geolocation: Geolocation) {}
...
ionViewDidLoad() {
if(this.platform.is('cordova') === true){
document.addEventListener("deviceready", onDeviceReady, false);
}else{
console.log('Browser geolocation')
this.getGeolocation();
}
}
function onDeviceReady() {
console.log("navigator.geolocation works well");
this.getGeolocation();
}
getGeolocation(){
console.log('Starting Geolocation');
var options = {
enableHighAccuracy: true
};
this.geolocation.getCurrentPosition(options)
.then((position) => {
console.log('Geolocation successful');
this.currentLocation = {
lat: position.coords.latitude,
lng: position.coords.longitude
};
let query = '?lat=' + position.coords.latitude + '&lng=' + position.coords.longitude;
this.updatePlaces(query);
}).catch((error) => {
console.log('Error getting location', error);
});
}
I seem to have solved the issue. The problem was that I have been mixing the implementation of Cordova's geolocation and the implementation for Ionic. In Ionic it's not needed to add the event listener (I guess it handles that under the hood) as seen in the docs, so the proper implementation should be like this:
import { Geolocation } from '#ionic-native/geolocation';
...
constructor(private geolocation: Geolocation) {}
...
ionViewDidLoad() {
this.getGeolocation();
}
getGeolocation(){
console.log('Starting Geolocation');
var options = {
enableHighAccuracy: true
};
this.geolocation.getCurrentPosition(options)
.then((position) => {
console.log('Geolocation successful');
this.currentLocation = {
lat: position.coords.latitude,
lng: position.coords.longitude
};
let query = '?lat=' + position.coords.latitude + '&lng=' + position.coords.longitude;
this.updatePlaces(query);
}).catch((error) => {
console.log('Error getting location', error);
});
}
I already had this code before I implemented the event listener, but at that time the plugins were failing, so it was an attempt to fix that, which got to implement the event listener. Thanks to #Prerak Tiwari for making me think in the right direction.
We are customizing the DirectUpdate process as in the documentation (https://www-01.ibm.com/support/knowledgecenter/SSHS8R_7.1.0/com.ibm.worklight.dev.doc/dev/c_customizing_direct_update_ui_android_wp8_ios.html - with a directUpdateCustomListener) but in the onFinish callback the status is FAILURE_UNZIPPING.
I am testing on an Android (5.1.1) emulator.
function wlCommonInit(){
WL.Client.connect({
onSuccess: function() {
console.log("Successfully connected to Worklight Server.");
}, onFailure: function() {
console.log("Failed connecting to Worklight Server.");
}
});
}
var busyInd = new WL.BusyIndicator('content');
var savedDirectUpdateContext = null;
var restartDirectUpdate = function () {
if (savedDirectUpdateContext != null) {
savedDirectUpdateContext.start(directUpdateCustomListener); // use saved direct update context to restart direct update
}
};
var directUpdateCustomListener = {
onStart: function(totalSize) {
busyInd.show();
},
onProgress: function(status, totalSize, completeSize) {},
onFinish: function(status) {
busyInd.hide();
console.log("[MFP - DirectUpdate] Finish status: " + status);
var posSuccess = status.indexOf("SUCCESS");
if (posSuccess > -1) {
WL.Client.reloadApp();
} else {
WL.SimpleDialog.show('Update Failed', 'Press try again button', [{
text: "Try Again",
handler: restartDirectUpdate // restart direct update
}]);
wl_directUpdateChallengeHandler.submitFailure();
}
}
};
wl_directUpdateChallengeHandler.handleDirectUpdate = function(directUpdateData, directUpdateContext) {
savedDirectUpdateContext = directUpdateContext
WL.SimpleDialog.show('Update Avalible', 'Press Update button to download the new version!', [{
text : 'Update',
handler : function() {
directUpdateContext.start(directUpdateCustomListener);
}
}, {
text : 'Cancel',
handler : function() {
wl_directUpdateChallengeHandler.submitFailure();
}
}]);
};
How can we fix this?
The custom code is working fine without zxing installed. I suggest that you will try the same without this library. If it works, I suspect that it may be initializing or otherwise interfering with the Direct Update process once an update has been received.
Considering loading the library later in the app life cycle and see if this helps.
I have created an ionic angularjs ngCordova mobile app, wherein I have used ngCorodova geolocation plugin in order to get user location. when I am testing this on browser it works fine. but when same I [android-app.apk] I install on mobile app [obviously after checking "unknown sources" option]; I am not able to get the location. I see in app setting, permission is there to access location on mobile. Also, When event is trigerred it shows GPS symbol on top bar but it disappears.
Can anybody help me with this?
Below is the code for location in my controller.js
.directive('reverseGeocode', function ($cordovaGeolocation, $rootScope) {
return {
restrict: 'E',
template: '<div></div>',
link: function (scope, element, attrs) {
var geocoder = new google.maps.Geocoder();
var posOptions = {timeout: 10000, enableHighAccuracy: true};
$cordovaGeolocation
.getCurrentPosition(posOptions)
.then(function (position) {
var lati = position.coords.latitude;
var longi = position.coords.longitude;
// console.log(angular.toJson($rootScope.lati) + " - " );
var request = new XMLHttpRequest();
var method = 'GET';
//var url = 'http://maps.googleapis.com/maps/api/geocode/json?latlng='+lat+','+long+'&sensor=true';
var async = true;
//alert(url);
//request.open(method, url, async);
//alert(angular.toJson(request.open(method, url, async)));
// var data = JSON.stringify(request.responseText);
// alert(JSON.stringify(request.responseText));
var latlng = new google.maps.LatLng(lati, longi);
geocoder.geocode({ 'latLng': latlng }, function (results, status) {
if (status == google.maps.GeocoderStatus.OK) {
if (results[1]) {
//alert(results[1].address_components[1].long_name);
$rootScope.colony = results[1].address_components[1].long_name;
//alert(results[1].address_components[1].long_name);
//alert(results[1].address_components[1].long_name);
//alert(angular.toJson(results[1].address_components[1].long_name));
element.text(results[1].formatted_address);
} else {
element.text('Location not found');
}
} else {
element.text('Geocoder failed due to: ' + status);
}
});
}, function(err) {
// error
});
var watchOptions = {
frequency : 1000,
timeout : 3000,
enableHighAccuracy: false // may cause errors if true
};
var watch = $cordovaGeolocation.watchPosition(watchOptions);
watch.then(
null,
function(err) {
// error
},
function(position) {
var lat = position.coords.latitude
alert("abc >>" + lat);
var long = position.coords.longitude
});
watch.clearWatch();
// OR
$cordovaGeolocation.clearWatch(watch)
.then(function(result) {
// success
}, function (error) {
// error
});
},
replace: true
}
})
In html file I am using it as :
<h6>
User Colony: {{ colony }}
<reverse-geocode lat={{lati}} lng={{longi}}></reverse-geocode>
</h6>
<a href="#" ng-click="showStores(colony)" class="button button-block button-positive">
Browse Store
</a>
which triggeres the directive and find lat and long of user.
When testing on browser, it works perfectly but not on mobile itself.
In android it is super complicated to work with the GPS user, remember that often the geolocation we get is from the browser and not the GPS itself, and this varies a lot in the devices. For your help, I recommend installing cordova.plugins.diagnostic
function onDeviceReady() {
cordova.plugins.diagnostic.isLocationAuthorized(function(enabled){
//alert("gps es : " + (enabled ? "enabled" : "disabled"));
}, function(error){
//alert("error: "+error);
});
cordova.plugins.diagnostic.isLocationEnabled(function(enabled){
if(!enabled){
alert("gps not actived");
}else{
navigator.geolocation.getCurrentPosition(onSuccess, onError, {enableHighAccuracy: true,timeout: 5000,maximumAge: 5000});
}
}, function(error){
console.log("The following error occurred: "+error);
});
}
Always trying to see if I can get a latitude and longitude and if that is not activated or not you can get, it sends a message to the user. I hope it helps you.
I have a Sencha Touch 2 project and everything works great in the web browser. No errors in the console, and everything looks good. Once I package it with Phonegap and run it on a mobile device, however, things don't work as well.
I am using ext.device.notification.show in two places in my application. At first, I was doing requires: 'Ext.device.*' and while it worked in web, the app wouldn't run on mobile and eclipse would give me the error message Uncaught TypeError: Cannot read property 'name' of undefined. I switched over to requires: Ext.device.Notification (exact spelling and capitalization) and now the app runs but when I click a button that should create a message box, I get the error Uncaught TypeError: Cannot call method 'confirm' of undefined. The problem is I have no method called confirm. In one case I have a method called confirmItem, but for the second button that should be invoking a message box I have no method remotely close to "confirm."
I'll post one of the controllers below (this one has the confirmItem method):
Ext.define('MyApp.controller.MainController',
{
extend: 'Ext.app.Controller',
requires: ['Ext.device.Notification'],
config:
{
refs:
{
mainView: 'mainview',
btnConfirm: 'mainview button[action=confirmItem]',
},
control:
{
'btnConfirm':
{
tap: 'confirmItem'
},
mainView:
{
onSignOffCommand: 'onSignOffCommand'
}
}
},
// Transitions
getSlideLeftTransition: function ()
{
return {
type: 'slide',
direction: 'left'
};
},
getSlideRightTransition: function ()
{
return {
type: 'slide',
direction: 'right'
};
},
onSignOffCommand: function ()
{
var me = this;
console.log('Signed out.');
loginView = this.getLoginView();
//MainView.setMasked(false);
Ext.Viewport.animateActiveItem(loginView, this.getSlideRightTransition());
},
confirmItem: function ()
{
Ext.device.Notification.show(
{
title: 'Confirm',
message: 'Would you like to Confirm?',
buttons: ['No', 'Yes'],
callback: function (button)
{
if (button == "Yes")
{
MyApp.app.getController('MainController')
.confirmPickup();
}
else
{
console.log('Nope.');
}
}
});
},
confirmPickup: function ()
{
var me = this;
var loginStore = Ext.getStore('LoginStore');
mainView = this.getMainView();
mainView.setMasked(
{
xtype: 'loadmask',
message: ' '
});
if (null != loginStore.getAt(0))
{
var user_id = loginStore.getAt(0).get('id');
var name = loginStore.getAt(0).get('name');
var winner = loginStore.getAt(0).get('winner');
}
if (winner === 1)
{
console.log('success');
}
else
{
console.log('fail');
}
}
});
I only assume this is a problem because whenever I push the button that should be calling confirmItem I get the error. Am I using Ext.device.Notification correctly, or Have I missed something needed to make it work in Phonegap?
I found the solution! Everything was fine from a Sencha Touch point of view in terms of using requires: Ext.device.Notification but some things were missing on the Phonegap side. Specifically, I needed to install the appropriate plugins.
Open a terminal and type: Phonegap local plugin list to see your currently installed plugins. I had none. I went ahead and installed:
org.apache.cordova.device
org.apache.cordova.dialogs
org.apache.cordova.vibration
by using the following reference: http://docs.phonegap.com/en/3.0.0/cordova_device_device.md.html and selecting options from the menu on the left.