Archiv für Kategorie Google
Floats im GWT
Ich behebe gerade in unserer GWT-Applikation die letzten Bugs und muss feststellen, dass in der kompilierten Fassung alle float-Values falsch dargestellt werden.
So ergibt Java-Server-seitig die Zahl 0.3f auf dem Client 0.30000000…
Ich bin nicht der einzige, dem das aufgefallen ist: http://code.google.com/p/google-web-toolkit/issues/detail?id=2897 *grummel*
Google Chrome
Gestern wurde Google Chrome als Beta veröffentlicht und so musste ich den kommenden Webbrowser von Google gleich mal antesten.
Die Installation lässt komischerweise keine Wahl, wohin man den Browser installieren möchte und auch der Import der Firefox-Daten funktioniert (noch) nicht.
Vom Browser selbst bin ich an sich recht begeistert. wap.ecw.de lässt sich mit Chrome um den Faktor 4 in Relation zum Firefox schneller laden.
Mein Firefox ist zwar auch mit vielen Plugin-Ins zugemüllt, aber ausschlaggebend ist meines Erachtens der dp.SyntaxHighlighter, der den Quellcode farbig hervorhebt.
Gut gefällt mir, dass standardmäßig die deutsche Rechtschreibprüfung aktiviert ist – muss man beim Firefox nachinstallieren und braucht ziemlich viel Ressourcen.
HTML-textarea-Elemente lassen sich übrigens in der Größe ändern, was ich auch ganz nett finde.
Sobald die ersten Erweiterungen (Mouse Gesture, Firebug, LiveHeader) für Chrome erscheinen sollten, werde ich eine Wechsel in Betracht ziehen.
Google Mobile Maps Reverse Lookup
Der Reverse Lookup von CIDs und LACs von Google Mobile Maps funktioniert
Google Mobile Map API für PHP
Verfasst von Schakko unter Google, Handy, Location Based Services, Mobil am 20. August 2008
Von http://www.witracks.com.br/gmaps.txt
<?php
$data =
"\x00\x0e". // Function Code?
"\x00\x00\x00\x00\x00\x00\x00\x00". //Session ID?
"\x00\x00". // Contry Code
"\x00\x00". // Client descriptor
"\x00\x00". // Version
"\x1b". // Op Code?
"\x00\x00\x00\x00". // MNC
"\x00\x00\x00\x00". // MCC
"\x00\x00\x00\x03".
"\x00\x00".
"\x00\x00\x00\x00". //CID
"\x00\x00\x00\x00". //LAC
"\x00\x00\x00\x00". //MNC
"\x00\x00\x00\x00". //MCC
"\xff\xff\xff\xff". // ??
"\x00\x00\x00\x00" // Rx Level?
;
if ($_REQUEST["myl"] != "") {
$temp = split(":", $_REQUEST["myl"]);
$mcc = substr("00000000".dechex($temp[0]),-8);
$mnc = substr("00000000".dechex($temp[1]),-8);
$lac = substr("00000000".dechex($temp[2]),-8);
$cid = substr("00000000".dechex($temp[3]),-8);
} else {
$mcc = substr("00000000".$_REQUEST["mcc"],-8);
$mnc = substr("00000000".$_REQUEST["mnc"],-8);
$lac = substr("00000000".$_REQUEST["lac"],-8);
$cid = substr("00000000".$_REQUEST["cid"],-8);
}
$init_pos = strlen($data);
$data[$init_pos - 38]= pack("H*",substr($mnc,0,2));
$data[$init_pos - 37]= pack("H*",substr($mnc,2,2));
$data[$init_pos - 36]= pack("H*",substr($mnc,4,2));
$data[$init_pos - 35]= pack("H*",substr($mnc,6,2));
$data[$init_pos - 34]= pack("H*",substr($mcc,0,2));
$data[$init_pos - 33]= pack("H*",substr($mcc,2,2));
$data[$init_pos - 32]= pack("H*",substr($mcc,4,2));
$data[$init_pos - 31]= pack("H*",substr($mcc,6,2));
$data[$init_pos - 24]= pack("H*",substr($cid,0,2));
$data[$init_pos - 23]= pack("H*",substr($cid,2,2));
$data[$init_pos - 22]= pack("H*",substr($cid,4,2));
$data[$init_pos - 21]= pack("H*",substr($cid,6,2));
$data[$init_pos - 20]= pack("H*",substr($lac,0,2));
$data[$init_pos - 19]= pack("H*",substr($lac,2,2));
$data[$init_pos - 18]= pack("H*",substr($lac,4,2));
$data[$init_pos - 17]= pack("H*",substr($lac,6,2));
$data[$init_pos - 16]= pack("H*",substr($mnc,0,2));
$data[$init_pos - 15]= pack("H*",substr($mnc,2,2));
$data[$init_pos - 14]= pack("H*",substr($mnc,4,2));
$data[$init_pos - 13]= pack("H*",substr($mnc,6,2));
$data[$init_pos - 12]= pack("H*",substr($mcc,0,2));
$data[$init_pos - 11]= pack("H*",substr($mcc,2,2));
$data[$init_pos - 10]= pack("H*",substr($mcc,4,2));
$data[$init_pos - 9]= pack("H*",substr($mcc,6,2));
if ((hexdec($cid) > 0xffff) && ($mcc != "00000000") && ($mnc != "00000000")) {
$data[$init_pos - 27] = chr(5);
} else {
$data[$init_pos - 24]= chr(0);
$data[$init_pos - 23]= chr(0);
}
$context = array (
'http' => array (
'method' => 'POST',
'header'=> "Content-type: application/binary\r\n"
. "Content-Length: " . strlen($data) . "\r\n",
'content' => $data
)
);
$xcontext = stream_context_create($context);
$str=file_get_contents("http://www.google.com/glm/mmap",FALSE,$xcontext);
if (strlen($str) > 10) {
$lat_tmp = unpack("l",$str[10].$str[9].$str[8].$str[7]);
$lat = $lat_tmp[1]/1000000;
$lon_tmp = unpack("l",$str[14].$str[13].$str[12].$str[11]);
$lon = $lon_tmp[1]/1000000;
echo "Lat=$lat <br> Lon=$lon";
} else {
echo "Not found!";
}
?>
API für Google Mobile Maps
Verfasst von Schakko unter Entwicklung, Google, Location Based Services, Mobil am 20. August 2008
Nach einigem Suchen bin ich endlich fündig geworden. Neil Young hat die Pakete mit Wireshark analysiert und heraus kam folgender C#-Code:
using System;
using System.Collections.Generic;
using System.Text;
using System.Net;
using System.IO;
using System.Diagnostics;
/*
* Sample code to obtain geo codes from a cell info
* "GSM/UMTS" setting revealed by smuraro, thanks!
*/
/* (c) "Neil Young" (neil.young@freenet.de)
*
* This script/program is provided "as is".
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* GNU General Public License, see <http://www.gnu.org/licenses/>.
*/
namespace GMM {
class Program {
static byte[] PostData(int MCC, int MNC, int LAC, int CID, bool shortCID) {
/* The shortCID parameter follows heuristic experiences:
* Sometimes UMTS CIDs are build up from the original GSM CID (lower 4 hex digits)
* and the RNC-ID left shifted into the upper 4 digits.
*/
byte[] pd = new byte[] {
0x00, 0x0e,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00,
0x00, 0x00,
0x00, 0x00,
0x1b,
0x00, 0x00, 0x00, 0x00, // Offset 0x11
0x00, 0x00, 0x00, 0x00, // Offset 0x15
0x00, 0x00, 0x00, 0x00, // Offset 0x19
0x00, 0x00,
0x00, 0x00, 0x00, 0x00, // Offset 0x1f
0x00, 0x00, 0x00, 0x00, // Offset 0x23
0x00, 0x00, 0x00, 0x00, // Offset 0x27
0x00, 0x00, 0x00, 0x00, // Offset 0x2b
0xff, 0xff, 0xff, 0xff,
0x00, 0x00, 0x00, 0x00
};
bool isUMTSCell = ((Int64)CID > 65535);
if (isUMTSCell)
Console.WriteLine("UMTS CID. {0}", shortCID ? "Using short CID to resolve." : "");
else
Console.WriteLine("GSM CID given.");
if (shortCID)
CID &= 0xFFFF; /* Attempt to resolve the cell using the GSM CID part */
if ((Int64)CID > 65536) /* GSM: 4 hex digits, UTMS: 6 hex digits */
pd[0x1c] = 5;
else
pd[0x1c] = 3;
pd[0x11] = (byte)((MNC >> 24) & 0xFF);
pd[0x12] = (byte)((MNC >> 16) & 0xFF);
pd[0x13] = (byte)((MNC >>
& 0xFF);
pd[0x14] = (byte)((MNC >> 0) & 0xFF);
pd[0x15] = (byte)((MCC >> 24) & 0xFF);
pd[0x16] = (byte)((MCC >> 16) & 0xFF);
pd[0x17] = (byte)((MCC >>
& 0xFF);
pd[0x18] = (byte)((MCC >> 0) & 0xFF);
pd[0x27] = (byte)((MNC >> 24) & 0xFF);
pd[0x28] = (byte)((MNC >> 16) & 0xFF);
pd[0x29] = (byte)((MNC >>
& 0xFF);
pd[0x2a] = (byte)((MNC >> 0) & 0xFF);
pd[0x2b] = (byte)((MCC >> 24) & 0xFF);
pd[0x2c] = (byte)((MCC >> 16) & 0xFF);
pd[0x2d] = (byte)((MCC >>
& 0xFF);
pd[0x2e] = (byte)((MCC >> 0) & 0xFF);
pd[0x1f] = (byte)((CID >> 24) & 0xFF);
pd[0x20] = (byte)((CID >> 16) & 0xFF);
pd[0x21] = (byte)((CID >>
& 0xFF);
pd[0x22] = (byte)((CID >> 0) & 0xFF);
pd[0x23] = (byte)((LAC >> 24) & 0xFF);
pd[0x24] = (byte)((LAC >> 16) & 0xFF);
pd[0x25] = (byte)((LAC >>
& 0xFF);
pd[0x26] = (byte)((LAC >> 0) & 0xFF);
return pd;
}
static void Main(string[] args) {
if (args.Length < 4) {
Console.WriteLine("Usage: gmm MCC MNC LAC CID [\"shortcid\"]");
return;
}
string shortCID = ""; /* Default, no change at all */
if (args.Length == 5)
shortCID = args[4].ToLower();
try {
String url = "http://www.google.com/glm/mmap";
HttpWebRequest req = (HttpWebRequest)WebRequest.Create(new Uri(url));
req.Method = "POST";
int MCC = Convert.ToInt32(args[0]);
int MNC = Convert.ToInt32(args[1]);
int LAC = Convert.ToInt32(args[2]);
int CID = Convert.ToInt32(args[3]);
byte[] pd = PostData(MCC, MNC, LAC, CID, shortCID == "shortcid");
req.ContentLength = pd.Length;
req.ContentType = "application/binary";
Stream outputStream = req.GetRequestStream();
outputStream.Write(pd, 0, pd.Length);
outputStream.Close();
HttpWebResponse res = (HttpWebResponse)req.GetResponse();
byte[] ps = new byte[res.ContentLength];
int totalBytesRead = 0;
while (totalBytesRead < ps.Length) {
totalBytesRead += res.GetResponseStream().Read(ps, totalBytesRead, ps.Length - totalBytesRead);
}
if (res.StatusCode == HttpStatusCode.OK) {
short opcode1 = (short)(ps[0] << 8 | ps[1]);
byte opcode2 = ps[2];
System.Diagnostics.Debug.Assert(opcode1 == 0x0e);
System.Diagnostics.Debug.Assert(opcode2 == 0x1b);
int ret_code = (int)((ps[3] << 24) | (ps[4] << 16) | (ps[5] <<
| (ps[6]));
if (ret_code == 0) {
double lat = ((double)((ps[7] << 24) | (ps[8] << 16) | (ps[9] <<
| (ps[10]))) / 1000000;
double lon = ((double)((ps[11] << 24) | (ps[12] << 16) | (ps[13] <<
| (ps[14]))) / 1000000;
Console.WriteLine("Latitude: {0}, Longitude: {1}", lat, lon);
Process p = new Process();
p.StartInfo.FileName = "iexplore";
Console.WriteLine("\nClose map window to exit\n");
p.StartInfo.Arguments = String.Format(
"http://maps.google.de/maps?f=q&hl=de&q={0},{1}&ie=UTF8&z=15",
lat.ToString().Replace(',','.'), lon.ToString().Replace(',','.'));
p.Start();
p.WaitForExit();
}
else
Console.WriteLine("Error {0}", ret_code);
}
else
Console.WriteLine("HTTP Status {0} {1}", res.StatusCode, res.StatusDescription);
}
catch (Exception) {
throw;
}
}
}
}
Sehr gute Arbeit!
Die Beschreibung des Hexdumps gibt es unter http://maps.alphadex.de/datafiles/fct0e1b117823ccc1a.txt, der Blog von Neil ist unter http://foreverneilyoung.blogspot.com/ zu finden.
Weitere Infos: Anleitung zum Schreiben einer eigenen Anwendung mit GMM-API in Java
Google Maps Mobile API in Python.
Google zensiert gnadenlos
In meinem letzten Post berichtete ich über Google Maps Mobile und heute musste ich feststellen, dass in den Google Groups alle Beiträge, die irgendetwas mit der Google Mobile Maps API zu tun haben, gnadenlos gelöscht wurden.
Google hat offensichtlich keine Lust, die API der Öffentlichkeit zur Verfügung zu stellen. Ich finde diese Art der Zensur mehr als dreist.
Analyse der Google Mobile Maps API
Verfasst von Schakko unter Ajax, Google, Handy, Location Based Services am 19. August 2008
Den heutigen Abend war ich damit beschäftigt, mich um das Thema GPS-Lokalisierung zu kümmern. Dabei kamen dann einige interessante Dinge zu Tage. Zum einen wusste ich gar nicht, dass o2 einen Handy-Lokalisierungsdienst für lau anbietet. Nachdem man sich in das o2-Portal eingeloggt hat, kann man dort sein Handy lokalisieren. Nach einigen Sekunden erscheint in einer -billig gemachten- Karte der ungefähre Bestimmungsort des Handys. Mein Handy wurde ca. 1.6 Kilometer zu weit nördlich angezeigt, aber das bleibt nun mal nicht aus.
Meine andere Erkenntnis war, das man mit Google Maps Mobile http://www.google.com/gmm/tour.html?hl=de sich ebenfalls den Standort des Handys anzeigen lassen kann. Die J2ME-Applikation sucht sich die Cell ID des Betreibers heraus, in dem das Handy eingeloggt ist. Google hat wohl mit den großen Handynetz-Betreibern Verträge geschlossen, so dass sie auf die Zell-Datenbanken zugreifen können.
Leider konnte ich die J2ME-Anwendung auf meinem P910i nicht installieren. Ich schaute deshalb nach, ob man eventuell die Demo benutzen kann, um die API mit anderen Tools zu benutzen.
Nachdem ich die passende JAR-Datei heruntergeladen habe, musste ich leider feststellen, dass über die Sourcen ein Obfuscator gejagt wurde – ok ich hätte das wohl auch so gemacht
Ich baute mir ein kurzes Shellscript:
#!/bin/bash
find -name "*class" | sed 's/\.class//g' | sed 's/\.\///g' >> files.txt
for clazz in `cat files.txt`;
do
echo "FILE $clazz" >> code.txt
javap -c $clazz >> code.txt
done
Und hatte somit von den allen Klassen den dekompilierten Byte-Code. Viel anfangen konnte ich damit leider nicht, ich stellte nämlich fest, dass die komplette Verbindung zwischen J2ME-Client und Google Maps Mobile im Binärformat abgewickelt wird.
Frontcontroller der Server-API ist http://www.google.com/glm/mmap – und das war es auch schon. Also leider nix mit REST o.ä.
Der Client stellt eine Anfrage über POST als Client “MobileRunner” im Binärformat, der Server sendet die Antwort ebenfalls als Binary zurück.
Tja, leider blöd gelaufen. Ich hätte gerne ein paar Anwendungen geschrieben, die auf die Google Mobile Maps-API setzen würden.
Sag was!