InAppBrowser not closing? - android

I'm using the InAppBrowser plugin (v1.1.1) with Cordova for an OAuth login process. Unfortunately, the InAppBrowser doesn't appear to be closing the browser. My "closeBrowser" function instead continually triggers the interval, and the browser remains on-screen on the Android (I have not tried other devices at this time.)
Is there a way to forcibly close the InAppBrowser other than .close(), or hide it? Or maybe there's a flaw in my code somewhere that is locking the browser.
LogInPage.prototype.handleExternalLogin = function (externalLogin) {
var _this = this;
var ref = window.open(Environment_1.settings.baseUrl + externalLogin.route.url, "_blank", "location=no");
ref.addEventListener('loadstart', function (event) {
if (_.startsWith(event.url, Environment_1.settings.baseUrl + "/api/Account/account/ExternalLoginCallback")) {
// Now we want to load a different url that will give us the mobile access token
console.log('get external-mobile-token');
_this.closeBrowser(ref);
var ref2 = window.open(Environment_1.settings.baseUrl + "/api/Account/external-mobile-token", "_blank" /*, "location=no"*/);
ref2.addEventListener('loadstop', function (event) {
console.log('loadstop ' + event.url);
if (event.url == Environment_1.settings.baseUrl + "/api/Account/external-mobile-token") {
ref2.executeScript({ code: 'window.document.documentElement.innerText' }, function (contents) {
_this.login(contents);
_this.closeBrowser(ref2);
});
}
});
ref2.addEventListener('loaderror', function (event) {
console.log(event);
_this.closeBrowser(ref2);
// TODO - do something?
});
}
});
ref.addEventListener('loaderror', function (event) {
console.log(event);
_this.closeBrowser(ref);
// TODO - do something?
});
};
LogInPage.prototype.closeBrowser = function (browser) {
var interval = setInterval(function () {
console.log('closing');
browser.close();
}, 10);
browser.addEventListener('exit', function () {
console.log('closed');
clearInterval(interval);
});
};
LogInPage.prototype.login = function (token) {
console.log(token);
};
The above code is actually generated from TypeScript, but I figured I wouldn't confuse the issue.

It appears that closing an InAppBrowser and opening another at the same time was causing the issue; rewriting the process to only need one window solved my issue.

Related

Why doesn't the cordova-plugin-background-mode plugin work on android?

I'm trying to send the geolocation by ajax in intervals of 30 seconds in the background, since this application is being used to know the "real time" location of the deliverers at all times. The problem is that when you enable the plugin in the android version when generating the apk and installing it on the cell phone it doesn't work, even when you put the application in the background and put it back in the foreground it restarts completely.
These are the versions that I am using for the development of the application:
Cordova 10
Nodejs 14.16
JQuery 3.5
Structure:
js
login.js
home.js
index.html -- this is the login page where the login.js file is located
home.html -- this is the home page where the home.js file is located
login.js
document.addEventListener('deviceready', function () {
cordova.plugins.backgroundMode.enable();
});
home.js
let isSending = false;
let intervalId = null;
let email = window.localStorage.getItem("user_email");
let token = window.localStorage.getItem("token");
let path = window.localStorage.getItem("api_url");
let onMapSuccess = function (position) {
let latitude = position.coords.latitude;
let longitude = position.coords.longitude;
if (!isSending) {
$.ajax({
type: "GET",
url: path + "/geoTransportista/" + email + "/" + latitude + "/" + longitude,
headers: {
Authorization: "Bearer " + token,
"Content-type": "application/json",
},
beforeSend: function() {
isSending = true;
}
}).done((res) => {
if (res.state == "successful") console.log("ENVIO EXITOSO");
}).fail((err) => {
console.log(err);
}).always(() => {
isSending = false;
});
}
};
let onMapError = function (error) {
isSending = false;
}
let getLocation = () => {
navigator.geolocation.getCurrentPosition(onMapSuccess, onMapError, {
enableHighAccuracy: true,
});
return getLocation;
}
document.addEventListener('deviceready', function (e) {
intervalId = setInterval(getLocation(), 30000);
cordova.plugins.backgroundMode.on('activate', function (e) {
cordova.plugins.backgroundMode.disableWebViewOptimizations();
if (intervalId) clearInterval(intervalId);
intervalId = setInterval(getLocation(), 30000);
});
cordova.plugins.backgroundMode.on('deactivate', function (e) {
if (intervalId) clearInterval(intervalId);
intervalId = setInterval(getLocation(), 30000);
});
});
#justin is wrong it works on Cordova 10+ but it does not support GPS however you can recall GPS function when you resume to app. I'm on Cordova 11.0.0 and its working fine. Also you can take a look a cordova-plugin-advanced-background-mode
cordova-plugin-background-mode does not work on Cordova 10. You can try downgrade to Cordova 9. The repo seems inactive for a while now, not sure if the author will ever fix it.

Ionic reading data from SQLite during login in Android

Im facing a problem reading the already set data from previous login after user abruptly switches from my App into another or restarts the phone. The data I've set after successful login does get saved in the SQLite database.
.controller('LoginCtrl', function($scope, $ionicPopup, $state,$http,ServerEndPoint,localStorageService,$cordovaGeolocation,$ionicActionSheet,dataShare,$ionicPush,loading,$rootScope,$cordovaSQLite) {
$scope.data = {};
//Does not work
$scope.init = function()
{
$scope.load();
};
if(localStorageService.get("tradie_id") !== null && localStorageService.get("phone_no") !== null) {
$state.go('menu.map');
}
//This is called from login form submit button click
$scope.authenticateUser = function(loginForm){
//Authenticating user from the server, after successful login
//This one works
$scope.addInfo(res.data.user_id,res.data.first_name,res.data.phone_no,status);
$state.go('menu.map');
}
$scope.addInfo = function(user_id,first_name,phone_no,status){
var query = "INSERT INTO user_data(user_id,first_name,phone_no,status) VALUES(?,?,?,?)";
$cordovaSQLite.execute(db,query,[user_id,first_name,phone_no,status]);
$scope.load();
}
$scope.load = function(){
$scope.alldata = [];
$cordovaSQLite.execute(db,"SELECT * FROM user_data").then(function(result){
if(result.rows.length)
{
for(var i=0;i<result.rows.length;i++)
{
$scope.alldata.push(result.rows.item(i));
}
localStorageService.set("user_id", $scope.alldata[0].tradie_id);
localStorageService.set("first_name", $scope.alldata[0].first_name);
localStorageService.set("phone_no", $scope.alldata[0].phone_no);
}else
{
console.log("No data found");
}
},function(error){
console.log("error "+err);
})
}
})
Any suggestions or pointers to a sample source code is highly appreciated. I'm using ionic version 1.
I think you didn't create or open the db when app ready first:
var db = $cordovaSQLite.openDB({ name: "my.db" });

Geolocation reporting in Ionic app Background

I intend to get users geolocation even when the app sits dormant in the background and store the same in the database.
I'm using katzer's Cordova Background Plug-in,
When I try to access navigator.geolocation.getCurrentPosition inside backgroundMode.onactivate function, nothing happens, Whereas when I try passing hard coded values api is called, data is stored in database.
following is my code
document.addEventListener('deviceready', function() {
// Android customization
cordova.plugins.backgroundMode.setDefaults({
text: 'Doing heavy tasks.'
});
// Enable background mode
cordova.plugins.backgroundMode.enable();
// Called when background mode has been activated
cordova.plugins.backgroundMode.onactivate = function() {
console.log('inside background')
a();
}
var a = function() {
console.log('a called')
navigator.geolocation.getCurrentPosition(function(pos) {
console.log('inside navigate');
var data = {
Lati: '123456',
Longi: '132456',
//LoginID: JSON.parse(window.localStorage.getItem('LoginId'))
EmpCode: localStorage.getItem('LoginId')
};
$http.post("https://app.sbismart.com/bo/ContactManagerApi/UpdateEmployeeLoc", data).success(function(rsdata, status) {
console.log('inside rsdata');
console.log(data.Lati + "," + data.Longi);
})
}, function(error) {
alert('Unable to get location: ' + error.message);
});
}
}, false);
cordova.plugins.backgroundMode.onfailure = function(errorCode) {
console.log(errorCode)
};`
and check as to why is it failing....then again u need to run the locationService function in a timeout function in the background to get updated about the location and check the location from previously got location.
Something like this...
cordova.plugins.backgroundMode.onactivate = function () {
setTimeout(function () {
a();
}, 5000);
}
Hope this helps.

Camera not working using phonegap build

I'm making an app capable of take photos and upload them to a server. The phone will save the id generated.
I made a class abstractApp that creates an App object with a couple of helpers and variables. I'm using Framework7.
var App;
document.addEventListener("deviceready", function() {
App = new abstractApp();
var i;
App.f7Ref = new Framework7({init: false});
for (i = 0; i < App.constants.views.length; i++)
{
if (i==0)
App.mainView = App.f7Ref.addView (
App.constants.views[i].selector,
App.constants.views[i].settings );
else
App.f7Ref.addView (
App.constants.views[i].selector,
App.constants.views[i].settings );
}
// Checks if there exists register of remote photos
if ( App.local.get('remotephotos', false) == null || App.local.get('remotephotos', false) == '' )
{
App.remotephotos = [];
App.local.set('remotephotos', []);
}
else
{
App.remotephotos = App.local.get('remotephotos');
}
// Checks if there exists register of local photos
if ( App.local.get('localphotos', false) == null || App.local.get('localphotos', false) == '' )
{
App.localphotos = [];
App.local.set('localphotos', []);
}
else
{
App.localphotos = App.local.get('localphotos');
}
for (i = 0; i < appControllers.length; i++)
{
appControllers[i].apply(App);
}
console.log(App);
}, false);
In appControllers I'm saving functions related to each page (so it is a bit more organized). With only index and new-photo controllers I have no problem, I can attach events to elements and navigate between views. The problem is calling the camera object.
window.appControllers.push(function()
{
var $$ = Dom7;
var Ref = this.f7Ref;
var server = new serverInterface();
var photos = this.remotephotos;
var App = this;
Ref.onPageInit('new', function (page) {
Ref.alert('entra', 'entra');
$$('.capture').on('click', function () {
Ref.alert('Click', 'Click detected');
navigator.camera.getPicture(onSuccess, onFail,
{
quality: 20,
destinationType: destinationType.FILE_URI
});
function onSuccess(imageURI) {
Ref.alert('Photo captured.', 'Bien');
}
function onFail(message) {
Ref.alert('There was a problem.', 'Ups');
}
});
});
});
So, I enter the new page and I click the button with cass capture and the alert (click detected) appears, but it doesn't show the camera to take the photo.
I'm using Phonegap Build and an android phone, do you have any idea of what's happening?
Thank you very much in advance
The problem wasn't the javascript code I quoted.
I was loading the camera plugin in the config.xml like this
<gap:plugin name="org.apache.cordova.camera" />
But it should be loaded this way:
<plugin name="cordova-plugin-camera" />
If the plugin is not loaded correctly, in Phonegap Build appears: version n/a installed. In this case, when it is correctly loaded, appears: version 2.1.0 installed.
More information about this thread can be found here: http://phonegap.com/blog/2015/11/19/config_xml_changes_part_two/
Hope it helps someone else too
Regards

Android InAppBrowser virtual keyboard closes on executeScript(). [phonegap]

I copied my code from the following link. It's a workaround for Passing Data From an InAppBrowser back to the app.
blogs.telerik.com/appbuilder/posts/13-12-23/cross-window-communication-with-cordova's-inappbrowser
The problem is that after each executescript() the Keyboard disappears.
This issue status here is "won't fix". So I'm wondering if there is an alternative solution. I only see a reference to KitKat users, but that would only represent a limited amount.
https://issues.apache.org/jira/browse/CB-5449
Suggestions?
setName: function() {
var win = window.open( "http://jsfiddle.net/tj_vantoll/K2yqc/show", "_blank",
"EnableViewPortScale=yes" );
win.addEventListener( "loadstop", function() {
win.executeScript({ code: "localStorage.setItem( 'name', '' );" });
var loop = setInterval(function() {
win.executeScript(
{
code: "localStorage.getItem( 'name' )"
},
function( values ) {
var name = values[ 0 ];
if ( name ) {
clearInterval( loop );
win.close();
$( "h1" ).html( "Welcome " + name + "!" );
}
}
);
});
});
}
Depending on your use case, it might be a feasible workaround to check if the keyboard is currently visible and avoid calling executeScript in that case.
Try using the com.ionic.keyboard plugin to get cordova.plugins.Keyboard.isVisible and use that in your setInterval function.

Categories

Resources