Geolocation does not work in google chrome - google-geolocation

Is geolocation google. Example took from here https://developers.google.com/maps/documentation/javascript/examples/map-geolocation?hl=ru . Copied JAVASCRIPT + HTML and placed on a virtual host http://test.ru on localhost.Created a browser key and added it. The map is loaded, but not running geolocation in google chrome. Tell me what the problem is. Here is the code:
// Note: This example requires that you consent to location sharing when
// prompted by your browser. If you see the error "The Geolocation service
// failed.", it means you probably did not give permission for the browser to
// locate you.
function initMap() {
var map = new google.maps.Map(document.getElementById('map'), {
center: {lat: -34.397, lng: 150.644},
zoom: 6
});
var infoWindow = new google.maps.InfoWindow({map: map});
// Try HTML5 geolocation.
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(function(position) {
var pos = {
lat: position.coords.latitude,
lng: position.coords.longitude
};
infoWindow.setPosition(pos);
infoWindow.setContent('Location found.');
map.setCenter(pos);
}, function() {
handleLocationError(true, infoWindow, map.getCenter());
});
} else {
// Browser doesn't support Geolocation
handleLocationError(false, infoWindow, map.getCenter());
}
}
function handleLocationError(browserHasGeolocation, infoWindow, pos) {
infoWindow.setPosition(pos);
infoWindow.setContent(browserHasGeolocation ?
'Error: The Geolocation service failed.' :
'Error: Your browser doesn\'t support geolocation.');
}`

the problem is that since chrome 50, a security update removes the posibility of geolocation without https protocol. since you are trying this url http://test.ru it will not work.
Google details
Hope it helps.
Regards.

Related

How to get a blob from selected files on GooglePicker

I am using GooglePicker with React, and the result I am getting is an array of objects...
[
{
"id": "1...m",
"serviceId": "docs",
"mimeType": "image/jpeg",
"name": "name.jpg",
"description": "",
"type": "photo",
"lastEditedUtc": 1575388407136,
"iconUrl": "https://drive-thirdparty.googleusercontent.com/16/type/image/jpeg",
"url": "https://drive.google.com/file/d/1...m/view?usp=drive_web",
"embedUrl": "https://drive.google.com/file/d/1...m/preview?usp=drive_web",
"sizeBytes": 111364,
"rotation": 0,
"rotationDegree": 0,
"parentId": "0...A"
}]
So I tried to access through https://www.googleapis.com/drive/v3/files and directly through file.url using
const fetchOptions = { headers: { Authorization: `Bearer ${accessToken}` } };
docs.forEach((file) => {
...
fetch(file.url, fetchOptions).then((res) => {
const blob = res.blob();
uploadFile(blob);
});
});
But I get 403 or CORS; I tried setting the relayUrl in the picker, but this broke the Picker.
Notes:
I have these 3 scopes in my auth2:
['https://www.googleapis.com/auth/drive.file',
'https://www.googleapis.com/auth/drive',
'https://www.googleapis.com/auth/drive.readonly']```
I have my computer's url with port and protocol set as Authorized JavaScript origins and Authorized redirect URIs
Any ideas?
Edit 1:
I also tried using Google API like this:
const FILE_URL = 'https://www.googleapis.com/drive/v3/files';
const url = isDoc
? `${FILE_URL}/${file.id}/export?mimeType=${mimeType}`
: `${FILE_URL}/${file.id}?alt=media`;
fetch(url, fetchOptions).then((res) => {
const blob = res.blob();
uploadFile(blob);
});
You'll need the Drive API
From your question it seems that you are trying to do everything with Google Picker. However, the picker will only get you limited metadata for the files, so you can open them with your account (i.e. see them in another window) or let you upload files. If you want to download the actual file, then you will need to use the Drive API.
Drive Quickstart for browser JavaScript
The flow might be:
let user pick file
get metadata object
extract file id from object
make a call to Drive API (get with alt='media')
If I have misunderstood and you are already using the Drive API, then it would be helpful to see the associated code with that.
Ref
Quickstart
get
export)
EDIT:
Here is an example of using the Picker API to feed into the Drive API with gapi using the same login client.
HTML
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta charset="utf-8" />
<title>Google Picker Example</title>
</head>
<body>
<button id="authorize_button" style="display: none;">Authorize</button>
<button id="signout_button" style="display: none;">Sign Out</button>
<div id="result"></div>
<script type="text/javascript" src="script.js"></script>
<script async defer src="https://apis.google.com/js/api.js"
onload="this.onload=function(){};handleClientLoad()"
onreadystatechange="if (this.readyState === 'complete') this.onload()">
</script>
</body>
</html>
JS
const API_KEY = 'AI...';
const CLIENT_ID = '44...';
const appId = "44...";
const SCOPES = ["https://www.googleapis.com/auth/drive"];
const DISCOVERY_DOCS = [
"https://www.googleapis.com/discovery/v1/apis/drive/v3/rest",
];
const authorizeButton = document.getElementById("authorize_button");
const signoutButton = document.getElementById("signout_button");
// Use the Google API Loader script to load the google.picker script.
function handleClientLoad() {
gapi.load("client:auth2:picker", initClient);
}
function initClient() {
gapi.client.init({
apiKey: API_KEY,
clientId: CLIENT_ID,
discoveryDocs: DISCOVERY_DOCS,
scope: SCOPES[0]
})
.then(
function () {
// Listen for sign-in state changes.
gapi.auth2.getAuthInstance().isSignedIn.listen(handleSignIn);
// Handle the initial sign-in state.
handleSignIn(gapi.auth2.getAuthInstance().isSignedIn.get());
authorizeButton.onclick = handleAuthClick;
signoutButton.onclick = handleSignoutClick;
},
function (error) {
appendPre(JSON.stringify(error, null, 2));
}
);
}
function handleSignIn(isSignedIn) {
if (isSignedIn) {
authorizeButton.style.display = "none";
signoutButton.style.display = "block";
createPicker();
} else {
authorizeButton.style.display = "block";
signoutButton.style.display = "none";
}
}
function handleAuthClick(event) {
gapi.auth2.getAuthInstance().signIn();
}
function handleSignoutClick(event) {
gapi.auth2.getAuthInstance().signOut();
}
function createPicker() {
const token = gapi.client.getToken().access_token
if (token) {
let view = new google.picker.View(google.picker.ViewId.DOCS);
view.setMimeTypes("image/png,image/jpeg,image/jpg");
let picker = new google.picker.PickerBuilder()
.enableFeature(google.picker.Feature.NAV_HIDDEN)
.enableFeature(google.picker.Feature.MULTISELECT_ENABLED)
.setAppId(appId)
.setOAuthToken(token)
.addView(view)
.addView(new google.picker.DocsUploadView())
.setDeveloperKey(API_KEY)
.setCallback(getFile)
.build();
picker.setVisible(true);
}
}
function getFile(pickerResp) {
gapi.client.drive.files
.get({
fileId: pickerResp.docs[0].id,
alt: 'media'
})
.then(resp => {
console.log("fetch response", resp.status)
let binary = resp.body
// EDIT - addition from Gabrielle vvvv
let l = binary.length
let array = new Uint8Array(l);
for (var i = 0; i<l; i++){
array[i] = binary,charCodeAt(i);
}
let blob = new Blob([array], {type: 'application/octet-stream'});
// EDIT - addition from Gabrielle ^^^^
}
This code is adapted from the Drive Quickstart and the Picker Quickstart.
Note - this does give an error in the console, but it does seem to work all the same. This does seem to be a bug with the Picker - https://issuetracker.google.com/177046274
EDIT from Gabrielle
Note - using get with alt = media is for binary files. To get sheets/docs/slides etc, you need to use the export end point.

Chromecast v3 receiver application not working

I ran the sample custom receiver. I am running it using ngrok but i see in the console that its not connecting to web socket. Any help is appreciated: Here is my receiver code and screenshot
const context = cast.framework.CastReceiverContext.getInstance();
const playerManager = context.getPlayerManager();
const playbackConfig = new cast.framework.PlaybackConfig();
// Customize the license url for playback
playbackConfig.licenseUrl = 'https://wv-keyos.licensekeyserver.com/';
playbackConfig.protectionSystem = cast.framework.ContentProtection.WIDEVINE;
playbackConfig.licenseRequestHandler = requestInfo => {
requestInfo.withCredentials = true;
requestInfo.headers = {
'customdata': '<custom data>'
};
};
// Update playback config licenseUrl according to provided value in load request.
context.getPlayerManager().setMediaPlaybackInfoHandler((loadRequest, playbackConfig) => {
if (loadRequest.media.customData && loadRequest.media.customData.licenseUrl) {
playbackConfig.licenseUrl = loadRequest.media.customData.licenseUrl;
}
return playbackConfig;
});
function makeRequest (method, url) {
return new Promise(function (resolve, reject) {
var xhr = new XMLHttpRequest();
xhr.open(method, url);
xhr.onload = function () {
if (this.status >= 200 && this.status < 300) {
resolve(JSON.parse(xhr.response));
} else {
reject({
status: this.status,
statusText: xhr.statusText
});
}
};
xhr.onerror = function () {
reject({
status: this.status,
statusText: xhr.statusText
});
};
xhr.send();
});
}
playerManager.setMessageInterceptor(
cast.framework.messages.MessageType.LOAD,
request => {
castDebugLogger.info('MyAPP.LOG', 'Intercepting LOAD request');
if (request.media && request.media.entity) {
request.media.contentId = request.media.entity;
}
return new Promise((resolve, reject) => {
if(request.media.contentType == 'video/mp4') {
return resolve(request);
}
// Fetch content repository by requested contentId
makeRequest('GET', 'https://tse-summit.firebaseio.com/content.json?orderBy=%22$key%22&equalTo=%22'+ request.media.contentId + '%22')
.then(function (data) {
var item = data[request.media.contentId];
if(!item) {
// Content could not be found in repository
castDebugLogger.error('MyAPP.LOG', 'Content not found');
reject();
} else {
// Adjusting request to make requested content playable
request.media.contentId = item.stream.hls;
request.media.contentType = 'application/x-mpegurl';
castDebugLogger.warn('MyAPP.LOG', 'Playable URL:', request.media.contentId);
// Add metadata
var metadata = new cast.framework.messages.MovieMediaMetadata();
metadata.metadataType = cast.framework.messages.MetadataType.MOVIE;
metadata.title = item.title;
metadata.subtitle = item.author;
request.media.metadata = metadata;
resolve(request);
}
});
});
});
/** Debug Logger **/
const castDebugLogger = cast.debug.CastDebugLogger.getInstance();
// Enable debug logger and show a warning on receiver
// NOTE: make sure it is disabled on production
castDebugLogger.setEnabled(true);
playerManager.addEventListener(
cast.framework.events.category.CORE,
event => {
castDebugLogger.info('ANALYTICS', 'CORE EVENT:', event);
});
// Set verbosity level for custom tags
castDebugLogger.loggerLevelByTags = {
'MyAPP.LOG': cast.framework.LoggerLevel.WARNING,
'ANALYTICS': cast.framework.LoggerLevel.INFO,
};
/** Optimizing for smart displays **/
const playerData = new cast.framework.ui.PlayerData();
const playerDataBinder = new cast.framework.ui.PlayerDataBinder(playerData);
const touchControls = cast.framework.ui.Controls.getInstance();
let browseItems = getBrwoseItems();
function getBrwoseItems() {
let data = '"video": { \
"author": "The Blender Project", \
"description": "Grumpy Bunny is grumpy", \
"poster": "https://storage.googleapis.com/tse-summit.appspot.com/bbb/poster.png", \
"prog": "https://storage.googleapis.com/tse-summit.appspot.com/bbb/bbb-prog.mp4", \
"stream": { \
"dash": "https://d8dbsji255dut.cloudfront.net/drm-test/4K-Gaming-Sample.mpd", \
"hls": "https://d8dbsji255dut.cloudfront.net/drm-test/4K-Gaming-Sample.m3u8" \
}, \
"title": "Big Buck Bunny" \
}';
let browseItems = [];
for (let key in data) {
let item = new cast.framework.ui.BrowseItem();
item.entity = key;
item.title = data[key].title;
item.subtitle = data[key].description;
item.image = new cast.framework.messages.Image(data[key].poster);
item.imageType = cast.framework.ui.BrowseImageType.MOVIE;
browseItems.push(item);
}
return browseItems;
}
let browseContent = new cast.framework.ui.BrowseContent();
browseContent.title = 'Up Next';
browseContent.items = browseItems;
browseContent.targetAspectRatio =
cast.framework.ui.BrowseImageAspectRatio.LANDSCAPE_16_TO_9;
playerDataBinder.addEventListener(
cast.framework.ui.PlayerDataEventType.MEDIA_CHANGED,
(e) => {
if (!e.value) return;
// Clear default buttons and re-assign
touchControls.clearDefaultSlotAssignments();
touchControls.assignButton(
cast.framework.ui.ControlsSlot.SLOT_1,
cast.framework.ui.ControlsButton.SEEK_BACKWARD_30
);
// Media browse
touchControls.setBrowseContent(browseContent);
});
// context.start({ touchScreenOptimizedApp: true });
context.start({playbackConfig: playbackConfig});
I have already registered for Google Cast SDK Developer Console and created a unpublished app and added my chrome cast device as well.
You are seeing these errors because you are loading the receiver through a web browser directly. The usual flow of a cast session is that a "sender" (web browser, iOS device, android device) will initiate a cast session with the hosted receiver, and thereby beginning the socket connection. Right now, you only have a receiver loading, nothing has initiated the session.
One way to test this is to plug in a Chromecast or cast enabled device (most Android TV's have Chromecast built-in too!), and use a valid sender to connect to your receiver.
Google have built an awesome tool to help with Chromecast development, it's a shame it's not publicised more. You can find it here: https://casttool-1287.appspot.com/cactesttool/index.html
If you're wanting to really nail down your Chromecast development skills, I personally recommend that you checkout:
Google Codelabs for Cast, these have some really helpful walkthroughs. https://codelabs.developers.google.com/?cat=Cast
The Google Cast github repo, has some great examples. https://github.com/googlecast
Note: This is by no means a detailed explanation of how cast sessions are actually initiated, some very smart people have done some digging into how Chromecast sessions work, and if you're interested checkout Romain Picard's writeup at https://blog.oakbits.com/google-cast-protocol-overview.html

Google maps - Javascript - How to enable click marker listener if is using a cellphone to active gps directions

I have a questions, currently I have in a webpage some markers that I get from a xml file using position of latitude and longitude.
So I would like to know how to enable to option of the marker listener to activate or show the option to send the user using the cellphone directions (gps). Like in android it I click on the marker it shows the option to activate gps directions, but on web I don't know how.
So for each direction if is clicked send the current position to the gps directions app of the cellphone.
Currlently I have this code:
function initMap() {
var map = new google.maps.Map(document.getElementById('map'), {
center: {lat: -34.397, lng: 150.644},
zoom: 12
});
var infoWindow = new google.maps.InfoWindow({map: map});
// Try HTML5 geolocation.
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(function(position) {
var pos = {
lat: position.coords.latitude,
lng: position.coords.longitude
};
infoWindow.setPosition(pos);
infoWindow.setContent('Location found.');
map.setCenter(pos);
}, function() {
handleLocationError(true, infoWindow, map.getCenter());
});
} else {
// Browser doesn't support Geolocation
handleLocationError(false, infoWindow, map.getCenter());
}
// Change this depending on the name of your PHP or XML file
downloadUrl('https://www.mysite/dataMaps.php', function(data) {
var xml = data.responseXML;
var markers = xml.documentElement.getElementsByTagName('marker');
Array.prototype.forEach.call(markers, function(markerElem) {
var name = markerElem.getAttribute('name');
var address = markerElem.getAttribute('address');
var type = markerElem.getAttribute('type');
var point = new google.maps.LatLng(
parseFloat(markerElem.getAttribute('lat')),
parseFloat(markerElem.getAttribute('lng')));
var infowincontent = document.createElement('div');
var strong = document.createElement('strong');
strong.textContent = name
infowincontent.appendChild(strong);
infowincontent.appendChild(document.createElement('br'));
var text = document.createElement('text');
text.textContent = address
infowincontent.appendChild(text);
var icon = customLabel[type] || {};
var marker = new google.maps.Marker({
map: map,
position: point,
label: icon.label
});
marker.addListener('click', function() {
infoWindow.setContent(infowincontent);
infoWindow.open(map, marker);
//map.setCenter(marker.getPosition());
});
});
});
}
And
I foun this in google site:
function displayRoute(origin, destination, service, display) {
service.route({
origin: origin,
destination: destination,
waypoints: [{location: 'Adelaide, SA'}, {location: 'Broken Hill, NSW'}],
travelMode: 'DRIVING',
avoidTolls: true
}, function(response, status) {
if (status === 'OK') {
display.setDirections(response);
} else {
alert('Could not display directions due to: ' + status);
}
});
}
But in waypoints: not sure how to send the latitude and longitude parameters and if it will work on mobile devices to trigger the gps directions app :S
Any suggestions?
Finally I saw how, in the infowindow you just need to add this:
nav
I found it here: Is there a way to invoke navigation from mobile browser?

Cordova - Insert to web page's database

I'm developing an app using Apache Cordova for Visual Studio. The purpose of this app is to take a picture using the phone and upload this picture alongside with some other user input data to our company's webpage, that uses a SQL-server Database to store it's data.
So, the question is: How can I insert data to this database so I can show it on the webpage, considering that the app will be used outside of our network? So it can't be a local connection to our database!
var pictureSource;
var destinationType;
document.addEventListener("deviceready", onDeviceReady, false);
On device ready
function onDeviceReady() {
pictureSource = navigator.camera.PictureSourceType;
destinationType = navigator.camera.DestinationType;
}
Clean Up
function clearCache() {
navigator.camera.cleanup();
}
var retries = 0;
Upload photo taken from camera
function onCapturePhoto(fileURI) {
document.getElementById('MyElement').innerHTML = 'Uploading....';
var win = function (r) {
clearCache();
retries = 0;
document.getElementById('MyElement').innerHTML = '';
alert('Image Uploaded! Successfully');
};
var fail = function (error) {
if (retries === 0) {
retries++;
setTimeout(function () {
document.getElementById('MyElement').innerHTML = '';
onCapturePhoto(fileURI);
}, 1000);
} else {
retries = 0;
clearCache();
document.getElementById('MyElement').innerHTML = '';
alert('Something went wrong..Try Again');
}
};
var options = new FileUploadOptions();
options.fileKey = "file";
options.fileName = fileURI.substr(fileURI.lastIndexOf('/') + 1);
options.mimeType = "image/jpeg";
options.params = {};
var ft = new FileTransfer();
ft.upload(fileURI, encodeURI("http://yourserver.com/phpfile.php"), win, fail, options);
}
function onFail(message) {
alert(message);
}
Function To Call The Camera
Take Picture
function capturePhoto() {
navigator.camera.getPicture(onCapturePhoto, onFail, {
quality: 100,
destinationType: destinationType.FILE_URI,
sourceType: Camera.PictureSourceType.CAMERA,
encodingType: Camera.EncodingType.JPEG
});
}
Php part
<?php
$sourcePath = $_FILES['file']['tmp_name'];
$targetPath = "images/".$_FILES['file']['name']; // save uploaded image to images folder
move_uploaded_file($sourcePath,$targetPath) ;
?>
You will need to set up a secure API that has access to that database. Then, you can make an http POST from your Cordova app to an endpoint that saves the image in the database. You could use base64 encoding to facilitate the transfer of the image data. Then, you could read the images from the database just like usual!
All that you need to do on the Cordova side of things would be send an http request with your image data to the API server. You could do that with vanilla JS ala XMLHttpRequest, or with a Cordova plugin like this https://github.com/wymsee/cordova-HTTP.
The server side will be a bit more complicated, as you will need to create an API endpoint that saves the image data into your MS-SQL server. You should check out this high-level explanation: https://technet.microsoft.com/en-us/library/aa258693(v=sql.80).aspx. There are also Node.js interfaces for MS-SQL servers if that is your fancy.

Firefox/Chrome addon socketio

I'm trying to port chrome extension to firefox. My Chrome extension uses backgroung page to init one socketio connection on plugin start. Then in content page I send events to background page to emit events through socketio. So i have 1 connection and it is used by many tabs.
Is there any possibily to create something like this in FF? May be it's possible to create one shared worker for addon and communicate with worker from tabs? Any suggestions?
Thanks in advance.
You can implement something a lot like a background-page in Firefox using the SDK's PageWorker api. Here's a really simple example:
index.js
var data = require("sdk/self").data;
var page = require("sdk/page-worker");
var re = new RegExp("^https://www.google.*");
let { ActionButton } = require("sdk/ui/button/action");
let button = ActionButton({
id: "my-button-id",
label: "Button Label",
icon: {
"16": "chrome://mozapps/skin/extensions/extensionGeneric.png",
"32": "chrome://mozapps/skin/extensions/extensionGeneric.png"
},
onClick: function(state) {
main();
}
});
var worker;
function main() {
let contentURL = 'https://www.google.ca/';
if (worker) {
worker.contentURL = contentURL;
}
worker = page.Page({
include: re,
contentURL: contentURL,
contentScriptWhen: "ready",
contentScriptFile: data.url('worker.js')
});
worker.port.on('fromWorker', (m) => {
console.log("got message", m);
worker.port.emit('toWorker', true)
});
}
worker.js
console.log("worker> attached...");
self.port.on('toWorker', function(message) {
console.log("worker>", message);
});
self.port.emit("fromWorker", "message from content worker: "+ [document.location, document.title].join(', '));
If you want to interact with scripts loaded into the page, you'll need to proxy through the content script into the page via postMessage, see these docs for more help.

Resources