I'm building a small web app in Flash. Is there a solution to get the geo-location of a user?
The easiest way is to interface with a JavaScript function.
In your HTML:
<script>
function getGEO()
{
// First check if your browser supports the geolocation API
if (navigator.geolocation)
{
//alert("HTML 5 is getting your location");
// Get the current position
navigator.geolocation.getCurrentPosition(function(position)
{
lat = position.coords.latitude
long = position.coords.longitude;
// Pass the coordinates to Flash
passGEOToSWF(lat, long);
});
} else {
//alert("Sorry... your browser does not support the HTML5 GeoLocation API");
}
}
function passGEOToSWF(lat,long)
{
//alert("HTML 5 is sending your location to Flash");
// Pass the coordinates to mySWF using ExternalInterface
document.getElementById("index").passGEOToSWF(lat,long);
}
</script>
Then, in your Application, once your map is ready, put this in a function:
//for getting a user's location
if (ExternalInterface.available)
{
//check if external interface is available
try
{
// add Callback for the passGEOToSWF Javascript function
ExternalInterface.addCallback("passGEOToSWF", onPassGEOToSWF);
}
catch (error:SecurityError)
{
// Alert the user of a SecurityError
}
catch (error:Error)
{
// Alert the user of an Error
}
}
Finally, have a private function ready to catch the callback.
private function onPassGEOToSWF(lat:*,long:*):void
{
userLoc = new LatLng(lat,long);
map.setCenter(userLoc);
}
Related
Usually in a plain javascript site, I can use the following script to reference google maps api and set the callback function with initMap.
<script async defer src="https://maps.googleapis.com/maps/api/js?callback=initMap"></script>
What I observed is the initMap function in the plain javascript site is under the window scope, and it can be referenced in the script parameter settings - ?callback=initMap, but once I write a component in angular2 with a component method called initMap, the initMap will be under the scope of my component. Then the async loading script I set up in the index will not be able to catch my component initMap method.
Specifically, I 'd like to know how to achieve the same thing in Angular2?
PS: I know there is an angular2-google-maps component available in alpha via npm, but it currently is shipped with limited capability, so I 'd like to know how to load it in an easier way without using another component so I can just use google maps api to implement my project.
I see you don't want another component, but polymer has components that work well with google apis. I have angular2 code that uses the polymer youtube data api. I had help getting it setup. Here is the plunker that got me started. I think the hardpart is getting setup for that callback, I'm sure you can do it without polymer. The example shows the tricky part an angular service is used to hook everything up.
const url = 'https://apis.google.com/js/client.js?onload=__onGoogleLoaded'
export class GoogleAPI {
loadAPI: Promise<any>
constructor(){
this.loadAPI = new Promise((resolve) => {
window['__onGoogleLoaded'] = (ev) => {
console.log('gapi loaded')
resolve(window.gapi);
}
this.loadScript()
});
}
doSomethingGoogley(){
return this.loadAPI.then((gapi) => {
console.log(gapi);
});
}
loadScript(){
console.log('loading..')
let node = document.createElement('script');
node.src = url;
node.type = 'text/javascript';
document.getElementsByTagName('head')[0].appendChild(node);
}
}
I came across this while trying to develop a progressive web app, i.e. where there was a possibility of not being online. There was an error in the code examples: onload in the google maps script should be callback. So my modification of user2467174 led to
map-loader.service.ts
const url = 'http://maps.googleapis.com/maps/api/js?key=xxxxx&callback=__onGoogleLoaded';
#Injectable()
export class GoogleMapsLoader {
private static promise;
public static load() {
// First time 'load' is called?
if (!GoogleMapsLoader.promise) {
// Make promise to load
GoogleMapsLoader.promise = new Promise( resolve => {
// Set callback for when google maps is loaded.
window['__onGoogleLoaded'] = (ev) => {
resolve('google maps api loaded');
};
let node = document.createElement('script');
node.src = url;
node.type = 'text/javascript';
document.getElementsByTagName('head')[0].appendChild(node);
});
}
// Always return promise. When 'load' is called many times, the promise is already resolved.
return GoogleMapsLoader.promise;
}
}
And then I have a component with
import { GoogleMapsLoader } from './map/map-loader.service';
constructor() {
GoogleMapsLoader.load()
.then(res => {
console.log('GoogleMapsLoader.load.then', res);
this.mapReady = true;
})
And a template
<app-map *ngIf='mapReady'></app-map>
This way the map div is only put into the dom if online.
And then in the map.component.ts we can wait until the component is placed into the DOM before loading the map itself.
ngOnInit() {
if (typeof google !== 'undefined') {
console.log('MapComponent.ngOnInit');
this.loadMap();
}
}
Just in case you'd like to make it a static function, which always returns a promise, but only gets the api once.
const url = 'https://maps.googleapis.com/maps/api/js?callback=__onGoogleMapsLoaded&ey=YOUR_API_KEY';
export class GoogleMapsLoader {
private static promise;
public static load() {
// First time 'load' is called?
if (!GoogleMapsLoader.promise) {
// Make promise to load
GoogleMapsLoader.promise = new Promise((resolve) => {
// Set callback for when google maps is loaded.
window['__onGoogleMapsLoaded'] = (ev) => {
console.log('google maps api loaded');
resolve(window['google']['maps']);
};
// Add script tag to load google maps, which then triggers the callback, which resolves the promise with windows.google.maps.
console.log('loading..');
let node = document.createElement('script');
node.src = url;
node.type = 'text/javascript';
document.getElementsByTagName('head')[0].appendChild(node);
});
}
// Always return promise. When 'load' is called many times, the promise is already resolved.
return GoogleMapsLoader.promise;
}
}
This is how you can get the api in other scripts:
GoogleMapsLoader.load()
.then((_mapsApi) => {
debugger;
this.geocoder = new _mapsApi.Geocoder();
this.geocoderStatus = _mapsApi.GeocoderStatus;
});
This is what I'm currently using:
loadMapsScript(): Promise<void> {
return new Promise(resolve => {
if (document.querySelectorAll(`[src="${mapsScriptUrl}"]`).length) {
resolve();
} else {
document.body.appendChild(Object.assign(document.createElement('script'), {
type: 'text/javascript',
src: mapsScriptUrl,
onload: doMapInitLogic();
}));
}
});
}
See my more comprehensive instructions here
i have developed a cordova plugin for optical character recognition. I send image to android and the image processing part is done by the plugin and after processing the plugin returns the JSON object back to Cordova. The plugin is working fine for the first time only the data is received correctly but when i tried to process an image for second time the data returned by the plugin is correct but on cordova side the Json object is not updated it shows previous data.
try {
if (ACTION.equals(action))
{
Log.d("action name", action);
Log.d("json object", args.getString(0));
//JSONObject arg_object = args.getJSONObject(0);
this.callbackContext = callbackContext;
if(ACTION_CAMERA.equals(args.getString(0))){
Log.d("action name", "camera");
cordova.getThreadPool().execute(new Runnable() {
public void run() {
camera();
callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.OK, json)); // Thread-safe.
}
});
}
/*
* sending the JSON object containing OCR results and BASE64 encoded string to javaScript
*/
//callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.OK, json));
result = true;
Log.d("after results", "after results");
}
else{
callbackContext.error("Invalid action");
result = false;
}
return result;
}
catch(Exception e)
{
System.err.println("Exception: " + e.getMessage());
callbackContext.error(e.getMessage());
return false;
}
}
and my cordova code is
function onPhotoURISuccess(obj) {
alert(obj['all']);
// clear image div contents
$("#base64Image").empty();
$("#base64Image").attr('src', '');
var image = new Image();
image.src = 'data:image/png;base64,' + obj['imageBase64'];
$("#base64Image").append(image);
$('#base64Image').width();
}
// A button will call this function
function capturePhoto() {
var success = function(message) {
onPhotoURISuccess(message);
}
var failure = function() {
alert("Error calling OCR 1 Plugin");
}
OCRPlugin.greet("camera", success, failure);
}
I am using AJAX and i have four URLS of HTML. I want to fetch this four urls using AJAX and want to load them in four different divs dynamically. Although i have written code to access one url. Code is here...
function load(url)
{
if (window.XMLHttpRequest) {
try {
req = new XMLHttpRequest();
} catch (e) {req = false;}
} else if (window.ActiveXObject) {
// For Internet Explorer on Windows
try {
req = new ActiveXObject("Msxml2.XMLHTTP");
} catch (e) {
try {
req = new ActiveXObject("Microsoft.XMLHTTP");
} catch (e) {
req = false;
}
}
}
if(req) {
req.open('GET', url, false);
req.send(null);
}
}
load('<%=request.getScheme()%>://${domain}/car-rental/html/global/${siteLanguage}/terms/PrefMbrGlobalTermsMiddle-text.html');
function display(id)
{
var element = document.getElementById(id);
if (element && req)
{
// Synchronous request, wait till we have it all
element.innerHTML = req.responseText;
}
}
I want to do same type of logic to load four urls .. Please help me out...
What I understood from your code is load function you are using to make an ajax call. So what can do call load function as:
load("url1","target-div1");
load("url2","target-div2");
load("url3","target-div3");
load("url4","target-div4");
inside load on successful of AJAX set the content target-div with AJAX response.
I'm trying to use the html5 geolocation api with Meteor.
I'm using:
navigator.geolocation.getCurrentPosition(handle_geolocation_query); in my js but it doesn't seem to work - I think it may be related to the timer ( http://docs.meteor.com/#timers ) restrictions Meteor has. Any thoughts?
Thanks #lashleigh it was a loading problem
Here is the code that worked for me (I'm using Modernizr.js to detect geo-location)
if (Meteor.is_client) {
Session.set('loc','?');
//alert(Modernizr.geolocation);
function foundLocation(location) {
console.log(location);
Session.set('loc','lat: '+location.coords.latitude+', lan: '+ location.coords.longitude);
}
function noLocation() {
alert('no location');
}
Template.hello.greeting = function () {
var output;
if (Modernizr.geolocation) {
navigator.geolocation.getCurrentPosition(foundLocation, noLocation);
outpout = Session.get('loc');
}
return Session.get('loc');
};
}
i have used this code to get camera access how i can load it on page load
private function startVideo():void
{
if (true) // TODO: Recognize no video settings
{
var camera:Camera = Camera.getCamera(cameraIndex.toString());
if (camera)
{
vidMe.attachCamera(camera);
if (outgoingStream)
{
outgoingStream.attachCamera(camera);
}
}
}
else
{
vidMe.attachCamera(null);
if (outgoingStream)
{
outgoingStream.attachCamera(null);
}
}
}
Flash shows the camera request dialog the first time you call attachCamera(). To have a user be asked upfront, before your flash application reaches any functionality, I would suggest adding it upfront in our constructor.
This dummy function puts together a fake NetConnection, and connects it to no server. Going through this upfront will present a user with the camera use dialog while your flash application is loading, thus happening on page refresh or initial load.
private function ensurePermissions() : void {
var unusedNetConnection : NetConnection = new NetConnection()
unusedNetConnection.connect( null );
var ensureCamPermissions : NetStream = new NetStream( unusedNetConnection );
ensureCamPermissions.attachCamera( myCamera );
try {
ensureCamPermissions.close();
unusedNetConnection.close();
} catch( error:Error ) {
// Ignore any errors here
} finally {
ensureCamPermissions = null;
unusedNetConnection = null;
}
}