You are on page 1of 33

http://www.android.

com/

LBS
Files
Google Maps API
Satellitbaserade
positioneringssystem
• http://sv.wikipedia.org/wiki/Geostation%C3%A4r_omloppsbana

559 km
ovanför jordytan

35790 km
ovanför jordytan
GPS
• Tänkt som ett militärt system från
början, störnings signal borta 2000
• Första satelliten skickades upp 1978
• 1994 hade alla 24 satelliter samt tre
reservsatelliter skickats upp
• För närvarande 24-32 satelliter
• Noggrannheten är ca: 10 m (stand alone)
• Inklination, 55 grader
– http://en.wikipedia.org/wiki/Global_Positioning_System
• Övriga satellitbaserade positionssystem
– Glonass (Rus), Galileo (EU), Compass (Chn)
Fix och PDOP
• 1D (no fix), 2D or 3D Fix
– At least 4 satellites is necessary to have a 3D position fix
• DOP = Mått på geometrisk spridning
– Diluton Of Precision
– HDOP, VDOP, PDOP, TDOP, GDOP…
– http://en.wikipedia.org/wiki/Dilution_of_precision_(GPS)
• Ju lägre DOP-tal-desto bättre geometrisk spridning
– PDOP (position 3D) bör inte överstiga 4 - 5
• Elevationsmask bör vara 10-15 grader
– 0 – 89 grader är teoretiskt
– En lägre elevationsmask ger fler
satelliter och ett bättre lägre
DOP värde
– Men ofta också ett högre
”brus”, reflektioner, atmosfär etc.
GPS devices & phones 1
• Built-in
– Qualcomm gpsOne and other proprietary solutions
– http://www.prisjakt.nu/kategori.php?k=v615
• Bluetooth (GPS chipsets)
– U-blox, SiRF, RFMD and MTK etc.
• Static navigation filter
– Bad for pedestrian mode
– http://etn.se/index.php?view=article&catid=27%3Aprodukt&id=47540%3Aantenn-fo
• Almanac
– En förutsägelse om alla satelliternas bana och position runt jorden
– Giltig uppemot flera månader
• Ephemeris
– Innehåller enskilda satellitens exakta positionsdata vid given tid och annan
information nödvändig för positionering, uppdateras var 30 sec.
– Max uppemot 2-4h timmar gammal, 30 minuter i praktiken
– http://www.satellitetrackingsystem.co.uk/satellite_tracking_software.htm
GPS devices & phones 2
GPS
• User plane vs. Control plane
• A-GPS (Assisted)
– Hjälper till med att få igång
positioneringen genom att ge bla.
aktuell GPS Almanac och
Ephemeris via nätet
– Mobilnäts data (almanac)
– Många fler parametrar kan ges:
http://en.wikipedia.org/wiki/GPS_
Phone PDE
• TTFF (Time To First Fix)
Position Determination Entity
• Cold start vs. warm start
• Super cold start
• EGPS (Enhanced)
– http://en.wikipedia.org/wiki/EGPS
Mobila Positioneringsmetoder
• Mobilbaserad positionering
– Mobilen tar emot signaler från positionssatta
basstationer och positionerar sig med hjälp av
informationen
– WiFi nätverk etc. kan även användas
• Nätverksbaserad positionering
– Mobilnätverket positionerar den för det mesta passiva
mobiltelefonen
• Mobilassisterad positionering
– Mobilen gör alla mätningarna själv och skickar endast
mätsignaler till nätverket för beräkning
CellID and WiFi positioning
• Basically both position modes works in a similar way
• WiFi uses the network cards hardware adress (MAC) instead of
the mobile networks LAC, MCC and MNC codes
Cell ID
• Med Cell ID menas täcknings-
området av basstationens
antenn/antenner (sektorer)
– Stort om den är rundstrålande
• CGI-TA
– Cell Global Identity-Timing Advance
– Del av sektor i basstationen vilka
för det mesta strålar 120 grader
– I GSM kan r2 - r1 som lägst
bli 550 m, om inte cellen är
mindre än 550 m
r1
• Angel of Arrival (AOA) r2
– Vinkel-radiell metod, kräver antenner
som strålar mycket snävt
Cell ID with TelephonyManager

Wi-Fi

The Android telephony API provides a way to monitor basic phone information, such as
the network type, connection state, and utilities for manipulating phone number strings
TelephonyManager tm = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
GsmCellLocation location = (GsmCellLocation) tm.getCellLocation();
// obtain the device's cell ID and LAC (Location Area Code)
cellID = location.getCid();
lac = location.getLac();
Files and SD Cards
• All of the usual Java file I/O routines from the java.io package are
available (Output/InputStreamReader, FileReader/Writer etc.)
• Every application can read and write from/to the SD card
(/sdcard/<filename>)
– Write needs the WRITE_EXTERNAL_STORAGE permission in your
AndroidManifest
• Some helper methods are provided by the Context class for the
private internal area and external SD Card
– Only internal access to /data/data/<packagename>/files subdirectory
with perhaps limited storage

// Delete a private file. Returns true if it worked, false otherwise.


Context.deleteFile();
//Return a list of all files in the application’s private area in a String array.
Context.fileList();
//Open a private file for reading. Returns a java.io.FileInputStream.
Context.openFileInput();
//Open a private file for writing. Returns a java.io.FileOutputStream.
Context.OpenFileOutput();
FileWriter (chars) example
• CellIDWriter class that writes the Cell ID, Location Area Code and
Mobile Country Code to a file on the SD card
public class CellIDWriter implements Runnable
{
private static boolean isWriteRunning = false; // call the class with something like
private static String uri = "/sdcard/"; // and it will do the work in a thread
private final String fname = "cellid.txt"; new CellIDWriter().write(String.valueOf(mcellid),
private String mCID, mLAC, mMCC; String.valueOf(mlac), "240");
public void run()
{
try{
FileWriter fw = new FileWriter(uri + fname, true);
StringBuilder sb = new StringBuilder();
Date dateTime = new Date(System.currentTimeMillis());
sb.append(mCID + "," + mLAC + "," + mMCC + "," + dateTime.toString() + "\r\n");
Log.v("CellID", sb.toString());

// append at end of file


// CellIDWriter class continues here
fw.append(sb.toString());
public void write(String CID, String LAC, String MCC)
// android does flush() in close()
fw.close(); {
} mCID = CID;
catch(Exception e){ mLAC = LAC;
System.err.println(e.toString() + mMCC = MCC;
" : " + e.getMessage());
e.printStackTrace(); if(!isWriteRunning){
} isWriteRunning = true;
new Thread(this).start();
finally{
}
isWriteRunning = false;
}
}
}
}
File IO (byte) streams
• FileInputStream, FileOutputStream, InputStream and OutputStream
// Writing to a File
DataOutputStream dos = new DataOutputStream(openFileOutput("file.dat", MODE_PRIVATE));
dos.writeUTF("Hello, I'm text in a file!")

// Reading from a File


try {
DataInputStream dis = new DataInputStream(openFileInput("file.dat"));
dis.readUTF(); //should return "Hello, I'm text in a file!" if the file has been written.
} catch (FileNotFoundException ex) {
//the file has not yet been written
}

// Example of how to serialize an object to a File:


FileOutputStream fos = context.openFileOutput(SAVENAME,
context.MODE_PRIVATE);
ObjectOutputStream oos = new ObjectOutputStream(fos);
oos.writeObject(this);
oos.close();

// How to inflate the object back from the file:


FileInputStream fis = context.openFileInput(SAVENAME);
ObjectInputStream ois = new ObjectInputStream(is);
Flow f = (Flow) ois.readObject();

// The files in the resources directories can also be opened. For example,
// to open myrawfile.txt located in the res/raw folder, use the following:
InputStream is = this.getResources().openRawResource(R.raw.myrawfile);
Mockup positions
• Via DDMS as either GPX or KML files
Location Based Services 1
• An application requires the following to access LBS from
Android
– LocationManager - Class providing access to Android system location
services, i.e. the Activity must be initialized with the Android
LOCATION_SERVICE
– LocationListener - Interface for receiving notifications from the
LocationManager when the location has changed, a callback the Activity
must implement
– Location - Class representing a geographic location determined at a
particular time, this is the result from the location service
• Different Criteras (android.location.Criteria) is possible to set as
power requirements, position accuracy and provider etc.
• Make sure you remove position updates to save battery!
• Permissions in AndroidManifest
// GPS
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
// other positioning methods as WiFi (WLAN) and cell towers
<uses-permission
android:name="android.permission.ACCESS_COARSE_LOCATION" />
Location Based Services 2
• Get last location, use the getLastKnownLocation(String provider) method
• minTime and minDistance = mininterval (ms and meters) for notifications
private void initLocation() {
// use the LocationManager class to obtain GPS locations
LocationManager lm = (LocationManager) getSystemService(Context.LOCATION_SERVICE);

// providers: GPS_PROVIDER or NETWORK_PROVIDER


Location loc = lm.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
// params for requestLocationUpdates(String provider, long minTime,
// float minDistance, LocationListener listener)
lm.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, MyLocationListener);
}

private final LocationListener MyLocationListener = new LocationListener()


@Override
public void onLocationChanged(Location loc) { // god practice is to set paused to true
if (loc != null) { // before calling the super method
// mPaused is used to pause/resume work
double lat = loc.getLatitude(); @Override
double lng = loc.getLongitude(); protected void onPause() {
// do more ... mPaused = true;
} super.onPause();
} }
// on resume set paused to false after
}; // calling the super method
@Override @Override
public void onPause() { protected void onResume() {
lm.removeUpdates(MyLocationListener); super.onResume();
super.onPause(); mPaused = false;
}
}
Other sensors
• The Android SDK supports many different types of sensor devices
– TYPE_ACCELEROMETER: Measures acceleration in the x-, y-, and z-axes
– TYPE_LIGHT: Tells you how bright your surrounding area is
– TYPE_MAGNETIC_FIELD: Returns magnetic attraction in the x-, y-, and z-axes
– TYPE_ORIENTATION: Measures the yaw, pitch, and roll of the device
– TYPE_PRESSURE: Senses the current atmospheric pressure
– TYPE_PROXIMITY: Provides the distance between the sensor and some object
– TYPE_TEMPERATURE: Measures the temperature of the surrounding area
private SensorManager mgr;
private final LinkedList<float[]> mFifo;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mgr = (SensorManager) getSystemService(SENSOR_SERVICE);
mgr.registerListener(mySensorListener, mgr.getDefaultSensor(Sensor.TYPE_ACCELEROMETER),
SensorManager.SENSOR_DELAY_GAME);
// ...
}
// can also be a class which implements SensorEventListener
private final SensorEventListener mySensorListener = new SensorEventListener() {
@Override
public void onSensorChanged(SensorEvent event) {
if (event.sensor.getType() != Sensor.TYPE_ACCELEROMETER)
return; Remember that do not
float[] val = new float[] { event.values[0], event.values[1],
event.values[2] };
spend to much time in
mFifo.add(val); callback methods or
}
}; receivers!
Using Google Maps API
• To use the MapView class which is a wrapper around the Google
Maps API your Activity should extend MapActivity
– Your AVD and project must include the Google API library
• Project properties > Java Build Path > Libraries tab
– Obtain a valid Maps API key to use the Maps web service
– Include <uses-library android:name="com.google.android.maps" />
in the androidmanifest file inside the <application> tags
– The default.properties file must also have a suitable SDK API version
target=Google Inc.:Google APIs:10
– Add at least the network permission (more if GPS etc. is to be used)
<uses-permission android:name="android.permission.INTERNET" />
– Include a MapView in the layout XML file as below

<com.google.android.maps.MapView
android:id="@+id/MapView1"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:clickable="true"
android:apiKey="Use your obtanied Maps API key here!" />
Simple MapView
public class MyLocation extends MapActivity {
LocationManager mLocationManager;
Location mLocation;
TextView mTV;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
MapView mapView = (MapView) findViewById(R.id.MapView1);
mTV = (TextView) findViewById(R.id.TextView1);
mLocationManager = (LocationManager)
getSystemService(Context.LOCATION_SERVICE);
Criteria criteria = new Criteria();
criteria.setAccuracy(Criteria.ACCURACY_FINE);
criteria.setPowerRequirement(Criteria.POWER_LOW);
String locationprovider =
mLocationManager.getBestProvider(criteria, true);
mLocation =
mLocationManager.getLastKnownLocation(locationprovider);
mTV.setText("Address: \nlatitude:" +
mLocation.getLatitude() + "\nlongitude:" +
mLocation.getLongitude());
}

@Override
protected boolean isRouteDisplayed() {
// this method is required
return false;
}
}
MapView with overlay
• MyLocationOverlay, MapController and getMyLocation
private MapView mapView;
private MapController mCtrl;
private MyLocationOverlay mOverlay;

// Find and initialize the map view


private void initMapView() {
mapView = (MapView) findViewById(R.id.MapView1);
mCtrl = mapView.getController();
mapView.setSatellite(true);
mapView.setBuiltInZoomControls(true);
}

// Start tracking the position on the map


private void initOverlay() {
mOverlay = new MyLocationOverlay(getApplicationContext(),
mapView);
mOverlay.enableCompass(); // does not work in emulator
// queued to be executed as soon as we have a location fix
mOverlay.runOnFirstFix(new Runnable() {
public void run() {
// Zoom in to current location
mCtrl.setZoom(mZoom);
mCtrl.animateTo(mOverlay.getMyLocation());
}
});
mapView.getOverlays().add(mOverlay);
// showSchoolOverlay();
}
MapView with ItemizedOverlay
• ItemizedOverlay class enable adding tap-able markers to the map
private List<Overlay> mMapOverlays;
private Drawable mDrawable;
private HelloItemizedOverlay mItemizedOverlay;
public class HelloItemizedOverlay extends ItemizedOverlay<OverlayItem> {

private ArrayList<OverlayItem> mOverlays = new ArrayList<OverlayItem>();

public HelloItemizedOverlay(Drawable defaultMarker, Context context) {


super(boundCenterBottom(defaultMarker));
mContext = context;
}
public void addOverlay(OverlayItem overlay) {
mOverlays.add(overlay);
populate();
}
@Override
Context
protected OverlayItem createItem(int i) {
return mOverlays.get(i);
}
@Override
public int size() {
return mOverlays.size();
}
}

private void showSchoolOverlay(){


mMapOverlays = mapView.getOverlays();
mDrawable = this.getResources().getDrawable(R.drawable.robot48);
mItemizedOverlay = new HelloItemizedOverlay(mDrawable, this);
GeoPoint point = new GeoPoint(60487521, 15409151);
OverlayItem overlayitem = new OverlayItem(point, "Title", "Text");
mItemizedOverlay.addOverlay(overlayitem);
mapOverlays.add(mItemizedOverlay);
}
Using an Alert Dialog box
• Up to three buttons with possible actions
private void showAlertDialog()
{
AlertDialog dialog = new AlertDialog.Builder(this).create();

dialog.setMessage("Your final score: " + mScore + "/" + PERFECT_SCORE);


dialog.setButton(DialogInterface.BUTTON_POSITIVE, "Try this level again",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
mScore = 0;
start_level();
}
});

dialog.setButton(DialogInterface.BUTTON_NEGATIVE, "Advance to next level",


new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
mLevel++;
start_level();
}
});

dialog.setButton(DialogInterface.BUTTON_NEUTRAL, "Back to the main menu",


new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
mLevel = 0;
finish(); // or dismiss(); to just remove dialog
}
});

dialog.show();
}
MapView with ItemizedOverlay
• ItemizedOverlay onTap method

@Override
protected boolean onTap(int index) {
OverlayItem item = mOverlays.get(index);

AlertDialog.Builder dialog = new


AlertDialog.Builder(mContext);

dialog.setTitle(item.getTitle());
dialog.setMessage(item.getSnippet());

dialog.setPositiveButton("Yes", new OnClickListener() {


@Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
}
});

dialog.show();
return true;
}
Geocooding 1
• You can translate an Address to a Location (Geocoding)
import java.util.List;
import java.util.Locale;
import android.location.Address;
import android.location.Geocoder;

// A class representing an Address, i.e, a set of Strings describing a location


List<Address> addresses;
String area = "Stockholm, Sweden";
Geocoder gc = new Geocoder(this);
try
{
// Returns an array of Addresses that are known to describe the named location
addresses = gc.getFromLocationName(area, 1);
if(addresses != null)
{
Address x = addresses.get(0);
StringBuilder mSB = new StringBuilder("Address:\n");

mSB.append("latitude: ").append(x.getLatitude()).append("\n")
.append("longitude: ").append(x.getLongitude());
Log.v(Consts.TAG, mSB.toString());
mTV.setText(mSB.toString());
}
else
Log.v(Consts.TAG, "addresses is null");
}
catch(IOException e){
mTV.setText(e.getMessage());
}
Geocooding 2
• You can translate a Location to an Address (Reverse
Geocoding)
• The emualtor may not work with Geo*** (a bug since 2.2)!
private void reverseGeoCode()
{
List<Address> addresses;
try {
Geocoder mGC = new Geocoder(this, Locale.ENGLISH);
// public List<Address> getFromLocation (double latitude, double longitude, int maxResults)
addresses = mGC.getFromLocation(mLocation.getLatitude(),
mLocation.getLongitude(), 1);
if(addresses != null) {
Address currentAddr = addresses.get(0);
StringBuilder mSB = new StringBuilder("Address:\n");

for(int i=0; i<currentAddr.getMaxAddressLineIndex(); i++)


mSB.append(currentAddr.getAddressLine(i)).append("\n");

mTV.setText(mSB.toString());
Toast.makeText(getApplicationContext(), mSB.toString(),
Toast.LENGTH_LONG).show();
}
else
Log.v(Consts.TAG, "addresses is null");
}
catch(IOException e) {
mTV.setText(e.getMessage());
}
}
Sampling GPS, NMEA 0183
• The National Marine ElectronicsAssociation (NMEA)
– http://en.wikipedia.org/wiki/NMEA_0183
• GGA - Essential fix data which provide 3D location and accuracy data
• GSA - GPS *DOP (dilution of precision) values and active satellites
• GSV - Satellites in view - 1 sentence data = max 4 satellites
• RMC - NMEA has its own version of essential GPS PVT (position,
velocity, time) data
– http://www.gpsinformation.org/dale/nmea.htm#nmea
• Draw a track on Google Map from a NMEA GPS log file
– http://franson.com/forum/topic.asp?TOPIC_ID=4058 (GPS Visualizer)
• Example, 1 sec
$GPGGA,133851.996,6046.3885,N,01501.1250,E,1,04,04.1,00172.3,M,30.0,M,,*63
$GPGSA,A,3,06,30,,02,,05,,,,,,,07.3,04.1,06.0*07
$GPGSV,3,1,11,06,71,206,39,30,52,136,43,25,46,270,20,02,29,051,35*7B
$GPGSV,3,2,11,23,15,340,30,05,22,127,35,21,12,181,35,10,11,093,*7B Max 12 sat.
$GPGSV,3,3,11,16,11,291,,01,08,259,,33,01,251,*44
$GPRMC,133851.996,A,6046.3885,N,01501.1250,E,064.7,194.4,131105,003.1,E*6ª
Sampling GPS
• Principle for sampling of GPS with at least the double
speed to ensure that a valid sample is obtained in the
software (sampling theorem)
– If read/Calc is done in one thread and GPS is a callback
• GPS problems?
– A number of!
• Solutions
– Prediction
– Dead reckoning (accelerometer/gyro, step counter, rotation
sensor)
– Magnetic electronic compass (not dependent of GPS)
Read/Calc Read/Calc Read/Calc Read/Calc

GPS GPS Time

1s 2s
Projections, reference systems
• WGS 84 (World Geodetic System 1984)
– Decimal Degrees
• Lat/Long: 60.483494,15.411272
– Degrees/Minutes/Seconds
• Lat/Long: N 60° 29' 0.58", E 15° 24' 40.58"
– Degrees/Decimalminutes To convert coordinates from degrees,
minutes, seconds format to decimal format,
• Lat/Long: 6029.3240,N,01523.3028,E use this formula:
degrees + (minutes/60) + (seconds/3600)
– UTM (meters)
• Cylindric map projection in 60 zones, SE=32-35
• http://en.wikipedia.org/wiki/Transverse_Mercator_projection
• http://sv.wikipedia.org/wiki/UTM
To convert coordinates from degrees,
• RT90 - Swedish grid decimal minutes format to decimal format,
– X= 6707377 , Y= 1478345 use this formula:
degrees + (decimal minutes/60)
• SWEREF 99 TM (använder UTM zon 33)
– SWEdish REference Frame 1999
– N: 6705329.393, E: 522604.151
• http://sv.wikipedia.org/wiki/WGS_84
Vector vs. Raster
• ShapeUp
– .shp

Run-length encoded raster


Google Maps API
• Sign up for API key etc.
– http://code.google.com/apis/maps/
– Maps JavaScript API currently in version 3
– Static Maps API

• Further reading
– http://googlemapsmania.blogspot.com/
– http://www.postneo.com/2007/09/10/google-maps-geoxml-crash-course

• Test Google API functions


– http://hobbiton.thisside.net/advmap.html
– http://koti.mbnet.fi/ojalesa/exam/index.html

5 decimals degrees (0.00001) give the precision


Long/X: 0,88 meters
Lat/Y: 1,11 meters
View on a map
View KML in Google
Maps and Mobile
http://code.google.com/apis/kml/documentation/whatiskml.html
KML (Keyhole Markup Language)
• Shape fil in XML format
– http://www.zonums.com/
– Shp2kml, kml2shp, online KML Toolbox
• http://code.google.com/apis/kml/documentation/
• http://en.wikipedia.org/wiki/Keyhole_Markup_Language
• KMZ = Zipped KML <?xml version="1.0" encoding="UTF-8"?>
• XML based file <kml xmlns="http://www.opengis.net/kml/2.2">
<Placemark>
– Placemark – point <name>New York City</name>
– Path – line <description>New York City</description>
<Point>
– Polygon <coordinates>-74.006393,40.714172,0</coordinates>
– Images (3D) </Point>
</Placemark>
– M.m. </kml>

You might also like