Creo en nosotros. Wikipedia.
ShareCode
Permalink: http://www.treeweb.es/u/974/ 01/02/2011

ShareCode

1 2 <!doctype html>3 <html lang="es">4 <head>5  <meta charset="utf-8">6  <meta name="viewport" content="width=device-width, initial-scale=1">7  <meta name="theme-color" content="#172b4d">8  <title>Prueba GPS con pantalla bloqueada</title>9  <style>10  :root {color-scheme:dark; font-family: system-ui, -apple-system, sans-serif}11  body {margin:0; background:#101826; color:#eaf1fb; padding:20px;}12  main {max-width:720px; margin:0 auto}13  h1 {font-size:1.55rem;margin:0 0 6px}14  p {color:#bac7db;line-height:1.5}15  .panel {background:#18243a; border:1px solid #34435a; border-radius:14px; padding:14px; margin:12px 0}16  .buttons {display:flex;flex-wrap:wrap; gap:9px}17  button {background:#479cff; color:#071524; border:0; border-radius:10px; padding:13px 16px; font-weight:700; font-size:1rem}18  button:disabled {opacity:.45}19  button.secondary {background:#34435a; color:#eaf1fb}20  .stats {display:grid; grid-template-columns:repeat(2,minmax(0,1fr)); gap:12px}21  .value {font-weight:750;font-size:1.35rem;overflow-wrap:anywhere}22  .name {font-size:.82rem; color:#a6bbd4}23  pre {font:12px/1.5 ui-monospace,SFMono-Regular,Consolas,monospace; white-space:pre-wrap; overflow-wrap:anywhere; background:#0d1420; padding:12px; border-radius:8px; max-height:360px;overflow-y:auto}24  .ok {color:#91f0bd}.bad {color:#ffb4b4}25  </style>26 </head>27 <body>28 <main>29  <h1>🛰️ Prueba GPS en segundo plano</h1>30  <p>Inicia la prueba, concede permiso de ubicación, espera a recibir coordenadas y <strong>bloquea la pantalla mientras caminas</strong>. Al desbloquear, mira si se han registrado posiciones durante el bloqueo.</p>31  <div class="panel">32  <div class="buttons">33  <button id="start">Iniciar GPS</button>34  <button class="secondary" id="stop" disabled>Detener</button>35  <button class="secondary" id="download">Descargar registro</button>36  <button class="secondary" id="clear">Borrar datos</button>37  </div>38  <p id="status" role="status">Sin iniciar.</p>39  </div>40  <div class="panel stats">41  <div><div class="name">Posiciones recibidas</div><div class="value" id="count">0</div></div>42  <div><div class="name">Última posición</div><div class="value" id="last">—</div></div>43  <div><div class="name">Separación entre posiciones</div><div class="value" id="gap">—</div></div>44  <div><div class="name">Precisión del GPS</div><div class="value" id="accuracy">—</div></div>45  <div><div class="name">Visibilidad de la página</div><div class="value" id="visibility">—</div></div>46  <div><div class="name">Conexión segura</div><div class="value" id="secure">—</div></div>47  </div>48  <div class="panel">49  <strong>Últimos eventos</strong>50  <pre id="events"></pre>51  </div>52  <p>Importante: esta prueba no fuerza al navegador a trabajar en segundo plano; solo registra si realmente recibe ubicaciones. Los datos se guardan en este dispositivo y no se envían a ningún servidor. Para permisos GPS fiables, abre la página desde una URL <strong>HTTPS</strong>.</p>53 </main>54 <script>55 'use strict';56 const KEY = 'gps-background-test-v1';57 const $ = id => document.getElementById(id);58 let records = [];59 try { const stored = JSON.parse(localStorage.getItem(KEY) || '[]'); if (Array.isArray(stored)) records = stored; } catch {}60 let watchId = null;61 let active = false;62 const when = timestamp => timestamp ? new Date(timestamp).toLocaleTimeString('es-ES',{hour12:false}) : '—';63 function save(event, fields={}) {64  const entry={event, time:Date.now(), visibility:document.visibilityState,...fields};65  records.push(entry);66  if(records.length>5000) records=records.slice(-5000);67  try {localStorage.setItem(KEY, JSON.stringify(records));} catch (e) { $('status').textContent='No se pudo guardar el registro: '+e.message;}68  render();69 }70 function render(){71  const positions=records.filter(r=>r.event==='position');72  const last=positions.at(-1);73  const prev=positions.at(-2);74  $('count').textContent=positions.length.toString();75  $('last').textContent=last?when(last.time):'—';76  $('gap').textContent=last&&prev?Math.round((last.time-prev.time)/1000)+' s':'—';77  $('accuracy').textContent=last?Math.round(last.accuracy)+' m':'—';78  $('visibility').textContent=document.visibilityState;79  $('secure').textContent=window.isSecureContext?'Sí':'No';80  $('events').textContent=records.slice(-45).reverse().map(r=>81  `${when(r.time)} ${r.visibility} ${r.event}`+82  (r.event==='position'?` | ${r.lat.toFixed(6)}, ${r.lon.toFixed(6)} | ±${Math.round(r.accuracy)} m | GPS ${when(r.gpsTime)}`:'')+83  (r.event==='error'?` | ${r.code}: ${r.message}`:'')84  ).join('n') || '(Aún no hay eventos)';85 }86 function setActive(value){active=value;$('start').disabled=value;$('stop').disabled=!value;}87 $('start').addEventListener('click',()=>{88  if(!navigator.geolocation){$('status').textContent='Geolocalización no disponible. Utiliza HTTPS en Chrome.'; save('unsupported');return;}89  if(active)return;90  setActive(true);91  $('status').textContent='Solicitando permiso / esperando la primera posición…';92  save('start',{userAgent:navigator.userAgent});93  watchId=navigator.geolocation.watchPosition(94  p=>{95  $('status').textContent='GPS activo: última posición '+when(Date.now());96  save('position',{gpsTime:p.timestamp,lat:p.coords.latitude,lon:p.coords.longitude,accuracy:p.coords.accuracy,speed:p.coords.speed,heading:p.coords.heading});97  },98  e=>{99  $('status').textContent='Error GPS ('+e.code+'): '+e.message;100  save('error',{code:e.code,message:e.message});101  if(e.code===1){setActive(false); watchId=null;}102  },103  {enableHighAccuracy:true,maximumAge:0,timeout:20000}104  );105 });106 $('stop').addEventListener('click',()=>{107  if(watchId!==null)navigator.geolocation.clearWatch(watchId);108  watchId=null;setActive(false);save('stop');$('status').textContent='Detenido.';109 });110 $('clear').addEventListener('click',()=>{111  records=[];localStorage.removeItem(KEY); render();$('status').textContent='Datos borrados.';112 });113 $('download').addEventListener('click',()=>{114  const blob=new Blob([JSON.stringify({exportedAt:new Date().toISOString(),records},null,2)],{type:'application/json'});115  const url=URL.createObjectURL(blob);116  const a=document.createElement('a');a.href=url;a.download='gps-test-'+new Date().toISOString().replace(/[:.]/g,'-')+'.json';117  document.body.append(a);a.click();a.remove();setTimeout(()=>URL.revokeObjectURL(url),1000);118 });119 document.addEventListener('visibilitychange',()=>save('visibilitychange'));120 window.addEventListener('pagehide',()=>save('pagehide'));121 window.addEventListener('pageshow',()=>{render();});122 render();123 </script>124 </body>125 </html>126 
Enlace
El enlace para compartir es: