phonegap WFS proxy issue - android

I encountered a problem when I try to package my sencha-touch app using phonegap. Everything works fine except accessing WFS in phonegap. (And the app has no problem running in browser, WFS access is OK)
My phonegap version is 2.9; openlayer version is 2.13
Here I present my simple code. You can also check the example codes in the following site: http://openlayers.org/dev/examples/wfs-filter.html
var rootUrl = window.location.protocol + "//" + window.location.host + '/';
var map;
function init() {
map = new OpenLayers.Map({
div: "map",
layers: [
new OpenLayers.Layer.WMS(
"Natural Earth",
"http://demo.opengeo.org/geoserver/wms",
{ layers: "topp:naturalearth" }
),
new OpenLayers.Layer.Vector("WFS", {
strategies: [new OpenLayers.Strategy.BBOX()],
protocol: new OpenLayers.Protocol.WFS({
url: rootUrl + 'proxy.py?url=http://demo.opengeo.org/geoserver/wfs',
featureType: "tasmania_roads",
featureNS: "http://www.openplans.org/topp"
}),
styleMap: new OpenLayers.StyleMap({
strokeWidth: 3,
strokeColor: "#333333"
}),
})
],
center: new OpenLayers.LonLat(146.7, -41.8),
zoom: 6
});
}
In phonegap there's no problem accessing WMS, but when I try WFS, it never work.
Comparing to the link I showed you before, there's a road displayed in the map, and it is obtained through WFS. In my phonegap app, the road will not be displayed.
I'm wondering whether it is a WFS issue, or phonegap issue. Something is blocking my access to WFS in my phonegap app.
Please give me some suggestions and hints, guys! I will really appreciate it.
function getLayerList() {
$.ajax({ url: rootUrl + 'proxy.py?url=http://192.168.0.23/LBEService/Service1.svc/GetEventList',
//async: false,
data: JSON.stringify({}),
type: "POST",
dataType: "json",
contentType: "application/json; charset=utf-8",
success: function (result) {
console.log(result);
$("#demo").html(result[0].event_NAME);
},
error: function (xhr, ajaxOptions, thrownError) {
alert(xhr.status);
alert(thrownError);
}
}).done(function () {
});
}

Have you added the domain that is hosting the WFS to the white list?
http://docs.phonegap.com/en/1.9.0/guide_whitelist_index.md.html

On android PhoneGap window.location.protocol is 'file:' and window.location.hostname is "", so your app will probably be looking for file://proxy.py? which doesn't exist on your device.
To solve this issue I test the protocol, and set up OpenLayers.Proxy accordingly, thus:
if( location.protocol == 'file:' ) {
OpenLayers.ProxyHost = "";
} else {
OpenLayers.ProxyHost = "/cgi-bin/proxy.cgi?url=";
}
So in your case, if protocol is 'file:', I think you need to drop 'proxy.py?'
Tip: debug your android app using Chrome on your PC (chrome://inspect/#devices) and you'll see the request that android is making.

Related

Adding Back Tracks Does Not Work on WebRTC

We create an app with React Native WebRTC and Janus Gateway. It works as wanted. Our app is based on push to talk. So when an users in listen mode need to break microphone for other apps. And take back when anyone press to speak button.
Breaking Mic:
if (!globalTrack) {
globalTracks = config.myStream.getTracks();
}
config.myStream.getTracks().forEach(t => {
config.myStream.removeTrack(t);
});
Get Back the Tracks:
globalTracks.forEach(t => {
config.myStream.addTrack(t);
});
pluginHandle.createOffer({
media: { addVideo: true },
success: function(jsep) {
Janus.debug(jsep);
pluginHandle.send({message: {audio: true, video: false}, "jsep": jsep });
},
error: function(error) {
console.log("WebRTC error... " + JSON.stringify(error));
}
});
// also I have try this:
devices = await mediaDevices.getUserMedia({audio: true, video: false})
// devices output https://pastebin.ubuntu.com/p/KQqBq2QRy3/
devices._tracks.forEach(t => {
config.myStream.addTrack(t);
});
pluginHandle.createOffer({
media: {audio: {deviceId: devices._tracks[0]['id']}, replaceAudio: true},
success: function(jsep) {
pluginHandle.send({message: {audio: true, video: false}, "jsep": jsep});
},
error: function(error) {
console.log(("WebRTC error... " + JSON.stringify(error));
}
});
Problem:
Problem: E.g: when a call came to the phone and answered it. The user's voice does not pass anymore even after restarting the app.
On Janus Gateway every things is normal. I think problem is about renegotiation.
Problem occurred only on Android phones. And works after force stopping the app.
Janus Gateway Log which when I speak at room:
There's a message for JANUS AudioBridge plugin
Setting muted property: true (room 20, user 2301490876606211)
Notifying participant 329012611897879 (kardan)
Sending event to transport...
>> 0 (Success)
We can not find a generic solution.
For now restarting app is works with react-native-restart

Ionic 2 / Ionic 3 : How to get current location of a device

None of the answers on stackoverflow worked for me. A lot of them are for Ionic 1 or those answers are deprecated or they are not working for android device.
I have seen a lot of solutions on stackoverflow about getting current location of device but non of them seems to be working for Android .
what i have tried:-
using geolocation.getCurrentPosition() , which is working for IOS and browser but not for Android.
using this.geolocation.watchPosition() , which is working for IOS and browser but not for Android.
using navigator.geolocation.getCurrentPosition(),which is working for IOS and browser but not for Android.
using fiddle solution provided by this question getCurrentPosition() and watchPosition() are deprecated on insecure origins
Anyway , all of these are deprecated by google due to :-
getCurrentPosition() and watchPosition() are deprecated on insecure
origins, and support will be removed in the future. You should
consider switching your application to a secure origin, such as HTTPS.
See goo.gl/rStTGz for more details.
what worked for me is (https://ionicframework.com/docs/native/background-geolocation/ ) & (https://www.joshmorony.com/adding-background-geolocation-to-an-ionic-2-application/ ) both of these are based on background-geolocation plugin but,it's taking almost 50-55 sec on Android device, again it's working fine for ios
The problem with joshmorony(https://www.joshmorony.com/adding-background-geolocation-to-an-ionic-2-application/ ) solution is foreground is not working for Android physical devices but working fine for browser and ios. Background tracking is working fine , which is taking almost 50 sec to give lat & lng for the first time.
Please help me with this. I want a way to get current location in minimum time. For your info, I am using google javascript map sdk / api .
I tried every solution provided by all of you and others also on internet. Finally i found a solution.You can try this plugin cordova-plugin-advanced-geolocation (https://github.com/Esri/cordova-plugin-advanced-geolocation ) from ESRI . But this plugin will work for Android not IOS. For ios you can go with same old approach . i.e - using this.geolocation.getCurrentPosition(...) or this.geolocation.watchPosition(..).
Add cordova-plugin-advanced-geolocation Plugin Like this :-
cordova plugin add https://github.com/esri/cordova-plugin-advanced-geolocation.git
then Add below line at the top of Class / Component
declare var AdvancedGeolocation:any; //at the top of class
Now add these lines inside relevant function of component ( P.S. - I have included code for both Android & IOS)
//**For Android**
if (this.platform.is('android')) {
this.platform.ready().then(() => {
AdvancedGeolocation.start((success) => {
//loading.dismiss();
// this.refreshCurrentUserLocation();
try {
var jsonObject = JSON.parse(success);
console.log("Provider " + JSON.stringify(jsonObject));
switch (jsonObject.provider) {
case "gps":
console.log("setting gps ====<<>>" + jsonObject.latitude);
this.currentLat = jsonObject.latitude;
this.currentLng = jsonObject.longitude;
break;
case "network":
console.log("setting network ====<<>>" + jsonObject.latitude);
this.currentLat = jsonObject.latitude;
this.currentLng = jsonObject.longitude;
break;
case "satellite":
//TODO
break;
case "cell_info":
//TODO
break;
case "cell_location":
//TODO
break;
case "signal_strength":
//TODO
break;
}
}
catch (exc) {
console.log("Invalid JSON: " + exc);
}
},
function (error) {
console.log("ERROR! " + JSON.stringify(error));
},
{
"minTime": 500, // Min time interval between updates (ms)
"minDistance": 1, // Min distance between updates (meters)
"noWarn": true, // Native location provider warnings
"providers": "all", // Return GPS, NETWORK and CELL locations
"useCache": true, // Return GPS and NETWORK cached locations
"satelliteData": false, // Return of GPS satellite info
"buffer": false, // Buffer location data
"bufferSize": 0, // Max elements in buffer
"signalStrength": false // Return cell signal strength data
});
});
} else {
// **For IOS**
let options = {
frequency: 1000,
enableHighAccuracy: false
};
this.watch = this.geolocation.watchPosition(options).filter((p: any) => p.code === undefined).subscribe((position: Geoposition) => {
// loading.dismiss();
console.log("current location at login" + JSON.stringify(position));
// Run update inside of Angular's zone
this.zone.run(() => {
this.currentLat = position.coords.latitude;
this.currentLng = position.coords.longitude;
});
});
}
EDIT : First installation is always going fine. But Sometimes you might get errors for no reason in subsequent installations. To make this error (any error with this plugin ) go away.Follow these steps :
1. Remove this plugin from your project (including config.xml and package.json).
2. Delete/Remove android platform.
3. Delete plugins folder.
4. Now reinstall this plugin again, following the steps above.
I have gone through the problem and find the solution.
the best way to get geolocation of the user is to use this plugin https://ionicframework.com/docs/native/geolocation/
do not forget to add this is app.moudle.ts as its a provider.
by simply adding this code in app component i was able to get location( do not forget to import and add in constructor)
this.geolocation.getCurrentPosition({ enableHighAccuracy: true }).then((resp) => {
console.log(resp);
}, Error => {
console.log(Error);
}).catch(Error => {
console.log(Error);
})
i only have the same error while i was using ionic cordova run
android --livereload that is insecure origin
but when i use ionic serve i can see the response in browser and also after
using ionic cordova run android
just to confirm response in android i check the chrome debugger.
It works for me
import { Geolocation } from '#ionic-native/geolocation/ngx';
import { NativeGeocoder, NativeGeocoderOptions, NativeGeocoderResult } from '#ionic-native/native-geocoder/ngx';
geoencoderOptions: NativeGeocoderOptions = {
useLocale: true,
maxResults: 5
};
constructor(
private geolocation: Geolocation,
private nativeGeocoder: NativeGeocoder
) {
getCurrentLocation() {
this.geolocation.getCurrentPosition()
.then((resp) => {
this.getGeoencoder(resp.coords.latitude, resp.coords.longitude);
}).catch((error) => {
console.log('Error getting location', error);
});
}
//geocoder method to fetch address from coordinates passed as arguments
getGeoencoder(latitude, longitude) {
this.nativeGeocoder.reverseGeocode(latitude, longitude, this.geoencoderOptions)
.then((result: NativeGeocoderResult[]) => {
const address = this.generateAddress(result[0]);
})
.catch((error: any) => {
// alert('Error getting location' + JSON.stringify(error));
});
}
//Return Comma saperated address
generateAddress(addressObj) {
let obj = [];
let address = "";
for (let key in addressObj) {
obj.push(addressObj[key]);
}
obj.reverse();
for (let val in obj) {
if (obj[val].length)
address += obj[val] + ', ';
}
return address.slice(0, -2);
}
you need to provide the permission for Android app as follows:
<feature name="Geolocation">
<param name="android-package" value="org.apache.cordova.GeoBroker" />
</feature>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_LOCATION_EXTRA_COMMANDS" />
I ran into a similar problem. When I build from the terminal with the --prod flag, I no longer see this error since it is now requesting position over https.
Built without --prod flag
Built using the --prod flag
Edit: Sorry for the format, I hope that this makes a little more sense. I used the following function in a service that I could call from anywhere to get the latitude, longitude, accuracy, and timestamp. The key though is using the --prod flag in the terminal when building the app.
this.geolocation.getCurrentPosition().then(position => {
let locationObj = {
lat: position.coords.latitude,
lon: position.coords.longitude,
timestamp: position.timestamp,
accuracy: position.coords.accuracy
};
resolve(locationObj);
})
this method is working for bot android and browser
watchLocation() {
this.watchLocationUpdates = this.geolocation.watchPosition({ maximumAge: 60000, timeout: 25000, enableHighAccuracy: true })
.subscribe(resp => {
this.latitude = resp.coords.latitude;
this.longitude = resp.coords.longitude;
this.altitude = resp.coords.altitude;
this.accuracy = resp.coords.accuracy;
this.altAccuracy = resp.coords.altitudeAccuracy;
this.heading = resp.coords.heading;
this.speed = resp.coords.speed;
this.timestamp = new Date(resp.timestamp);
});
}
I found solution for me: use google api https://www.googleapis.com/geolocation/v1/geolocate?key={API_KEY}
If platform Android I use google api.

window.localStorage.setItem not working on mobile phone

I am working on HTML5 mobile app using jQuery mobile.
This is my code:
$(document).on("click","#send_mobile_number",function(){
var mobile = $('#mobile_number').val();
var user_id = sessionStorage.getItem("user_id");
$('.ui-loader').show();
$.ajax({
url: BASE_URL+'users/send_sms_code.php',
type: 'POST',
datatype: 'json',
data: "user_id="+user_id+"&mobile="+mobile+"&type=1",
async:false,
success: function (response) {
var data = jQuery.parseJSON(response);
$('.ui-loader').hide();
if(data.status == 'Fail') {
$('.very_mob_no_message').html('Sorry some error occurred,try again.');
}else{
$('#close_mob_popup').trigger('click');
setTimeout(function()
{
$('.click_mobile_verify').trigger('click');
}, 500);
$('#send_mobile_verify_span').hide();
$('#after_mobile_send_span').show();
$('#moble_number_div').hide();
$('#user_code_div').show();
$('#user_code').val(data.sms_code);
//alert(window.localStorage.getItem('mobile'));
//sessionStorage.setItem("mobile",mobile);
window.localStorage.setItem("mobile",mobile); // IT IS NOT WORKING
$('.very_mobile_message').html('Enter code which is <br/> sent to your mobile number.');
}
},
error: function (jqXHR, textStatus, errorThrown) {
//alert(jqXHR.status);
}
});
});
I want to store mobile number in session using window.localStorage.setItem("mobile",mobile);. It is working when I run on my browser but when I runt on mobile phone as APP it stop working. Why this happening. I am checking android phone.
Just use localStorage.mobile = "mobile". It's as simple as that. localStorage is a global object and can be accessed and manipulated as any other object. The only difference with regular objects is that it can store only strings.
You can then retrieve your value using alert( localStorage.mobile ); // will alert "mobile"
So finally found the solution, I need to set webSettings.setDomStorageEnabled(true); on android code and after this localstorage is working perfectlly.

How to login with Google OAuth2 using Angularjs inside Phonegap using ClientID and ClientSecret

I am trying to login from my Phonegap App using Angularjs (using the Ionic Framework) through Google OAuth2. Currently I am using the http://phonegap-tips.com/articles/google-api-oauth-with-phonegaps-inappbrowser.html for logging in. But it is creating really ugly looking code and quite a hard to understand code when I am using Angular-UI-Router for Ionic.
This issue seems to be spiralling around without any proper answers. I hope it should be solved now. The Google Angular Guys should help.
How to implement Google Auth in phonegap?
The closest topic is How to use Google Login API with Cordova/Phonegap, but this is not a solution for angularjs.
I had to transfer the javascript variable values using the following code:
var el = document.getElementById('test');
var scopeTest = angular.element(el).scope();
scopeTest.$apply(function(){
scopeTest.user = user;
scopeTest.logged_in = true;
scopeTest.name = user.name;
scopeTest.email = user.email;
});
I did the solution like this, where TestCtrl is the Controller where the Login Button resides. There is a mix of jquery based $.ajax calls, which I am going to change to the angualar way. The google_call function basically calls the google_api which is mentioned in the link mentioned above in phonegap-tips.
.controller('TestCtrl', function($scope,$ionicPopup) {
$scope.logged_in = false;
$scope.getMember = function(id) {
console.log(id);
};
$scope.test = function(){
$ionicPopup.alert({"title":"Clicked"});
}
$scope.call_google = function(){
googleapi.authorize({
client_id: 'CLIENT_ID',
client_secret: 'CLIENT_SECRET',
redirect_uri: 'http://localhost',
scope: 'https://www.googleapis.com/auth/plus.login https://www.googleapis.com/auth/userinfo.email'
}).done(function(data) {
accessToken=data.access_token;
// alert(accessToken);
// $loginStatus.html('Access Token: ' + data.access_token);
console.log(data.access_token);
//$ionicPopup.alert({"title":JSON.stringify(data)});
$scope.getDataProfile();
});
};
$scope.getDataProfile = function(){
var term=null;
// alert("getting user data="+accessToken);
$.ajax({
url:'https://www.googleapis.com/oauth2/v1/userinfo?alt=json&access_token='+accessToken,
type:'GET',
data:term,
dataType:'json',
error:function(jqXHR,text_status,strError){
},
success:function(data)
{
var item;
console.log(JSON.stringify(data));
// Save the userprofile data in your localStorage.
window.localStorage.gmailLogin="true";
window.localStorage.gmailID=data.id;
window.localStorage.gmailEmail=data.email;
window.localStorage.gmailFirstName=data.given_name;
window.localStorage.gmailLastName=data.family_name;
window.localStorage.gmailProfilePicture=data.picture;
window.localStorage.gmailGender=data.gender;
window.localStorage.gmailName=data.name;
$scope.email = data.email;
$scope.name = data.name;
}
});
//$scope.disconnectUser(); //This call can be done later.
};
$scope.disconnectUser = function() {
var revokeUrl = 'https://accounts.google.com/o/oauth2/revoke?token='+accessToken;
// Perform an asynchronous GET request.
$.ajax({
type: 'GET',
url: revokeUrl,
async: false,
contentType: "application/json",
dataType: 'jsonp',
success: function(nullResponse) {
// Do something now that user is disconnected
// The response is always undefined.
accessToken=null;
console.log(JSON.stringify(nullResponse));
console.log("-----signed out..!!----"+accessToken);
},
error: function(e) {
// Handle the error
// console.log(e);
// You could point users to manually disconnect if unsuccessful
// https://plus.google.com/apps
}
});
};
})
I am providing this answer for the newbies who faced similar problems like mine while trying to login using Google OAuth2. So asking for Upvotes shamelessly as I am new here too!

Android- Sharing local storage on multiple WebViews/Windows

I'm developping a mobile application, which should connect to a web server. The application is written with jQM and simply imported in an android web view. I tried to solve this problem using the jStorage plugin, but it seems that it's impossible to share the local storage between the different pages. So I tried to implement this, but it does not work and continues sending null.
Here are my code samples:
Javascript:
function getToken(authCode) {
var jsonUrl = mainUrl + "/auth/authorizeToken?grant_type=authorization_code&client_id=bc89fb879a64eb8e422b94d5c39&client_secret=b5c2974b78f7f3f7aee2bed182&redirect_uri=redirection&code="+authCode;
$.ajax({
url: jsonUrl,
type: "GET",
dataType: "jsonp",
success: function(data) {
localStorage.setItem( "access_token", data.access_token);
localStorage.setItem( "refresh_token", data.refresh_token);
localStorage.setItem( "logged", "true");
}
});
}
function valTokens() {
access_token = localStorage.getItem("access_token");
refresh_token = localStorage.getItem("refresh_token");
}
After that the values are set to null. The .java files are the same as in the sample from the link given.

Categories

Resources