/*------------------------------------------------------------------------------ ** Ident: Innovation en Inspiration > Google Android ** Author: rene ** Copyright: (c) Jan 22, 2009 Sogeti Nederland B.V. All Rights Reserved. **------------------------------------------------------------------------------ ** Sogeti Nederland B.V. | No part of this file may be reproduced ** Distributed Software Engineering | or transmitted in any form or by any ** Lange Dreef 17 | means, electronic or mechanical, for the ** 4131 NJ Vianen | purpose, without the express written ** The Netherlands | permission of the copyright holder. *------------------------------------------------------------------------------ * * This file is part of OpenGPSTracker. * * OpenGPSTracker 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. * * OpenGPSTracker 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. * * You should have received a copy of the GNU General Public License * along with OpenGPSTracker. If not, see <http://www.gnu.org/licenses/>. * */ package nl.sogeti.android.gpstracker.tests.utils; import java.io.IOException; import java.io.UnsupportedEncodingException; import java.util.ArrayList; import java.util.Calendar; import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; import android.content.Context; import android.content.res.XmlResourceParser; import android.util.Log; /** * Feeder of GPS-location information * * @version $Id: MockGPSLoggerDriver.java 770 2011-01-09 10:16:41Z rcgroot $ * @author Maarten van Berkel (maarten.van.berkel@sogeti.nl / +0586) */ public class MockGPSLoggerDriver implements Runnable { private static final String TAG = "MockGPSLoggerDriver"; private boolean running = true; private int mTimeout; private Context mContext; private TelnetPositionSender sender; private ArrayList<SimplePosition> positions; private int mRouteResource; /** * Constructor: create a new MockGPSLoggerDriver. * * @param context context of the test package * @param route resource identifier for the xml route * @param timeout time to idle between waypoints in miliseconds */ public MockGPSLoggerDriver(Context context, int route, int timeout) { this(); this.mTimeout = timeout; this.mRouteResource = route;// R.xml.denhaagdenbosch; this.mContext = context; } public MockGPSLoggerDriver() { this.sender = new TelnetPositionSender(); } public int getPositions() { return this.positions.size(); } private void prepareRun( int xmlResource ) { this.positions = new ArrayList<SimplePosition>(); XmlResourceParser xmlParser = this.mContext.getResources().getXml( xmlResource ); doUglyXMLParsing( this.positions, xmlParser ); xmlParser.close(); } public void run() { prepareRun( this.mRouteResource ); while( this.running && ( this.positions.size() > 0 ) ) { SimplePosition position = this.positions.remove( 0 ); //String nmeaCommand = createGPGGALocationCommand(position.getLongitude(), position.getLatitude(), 0); String nmeaCommand = createGPRMCLocationCommand( position.lng, position.lat, 0, 0 ); String checksum = calulateChecksum( nmeaCommand ); this.sender.sendCommand( "geo nmea $" + nmeaCommand + "*" + checksum + "\r\n" ); try { Thread.sleep( this.mTimeout ); } catch( InterruptedException e ) { Log.w( TAG, "Interrupted" ); } } } public static String calulateChecksum( String nmeaCommand ) { byte[] chars = null; try { chars = nmeaCommand.getBytes( "ASCII" ); } catch( UnsupportedEncodingException e ) { e.printStackTrace(); } byte xor = 0; for( int i = 0; i < chars.length; i++ ) { xor ^= chars[i]; } return Integer.toHexString( (int) xor ).toUpperCase(); } public void stop() { this.running = false; } private void doUglyXMLParsing( ArrayList<SimplePosition> positions, XmlResourceParser xmlParser ) { int eventType; try { eventType = xmlParser.getEventType(); SimplePosition lastPosition = null; boolean speed = false; while( eventType != XmlPullParser.END_DOCUMENT ) { if( eventType == XmlPullParser.START_TAG ) { if( xmlParser.getName().equals( "trkpt" ) || xmlParser.getName().equals( "rtept" ) || xmlParser.getName().equals( "wpt" ) ) { lastPosition = new SimplePosition( xmlParser.getAttributeFloatValue( 0, 12.3456F ), xmlParser.getAttributeFloatValue( 1, 12.3456F ) ); positions.add( lastPosition ); } if( xmlParser.getName().equals( "speed" ) ) { speed = true; } } else if( eventType == XmlPullParser.END_TAG ) { if( xmlParser.getName().equals( "speed" ) ) { speed = false; } } else if( eventType == XmlPullParser.TEXT ) { if( lastPosition != null && speed ) { lastPosition.speed = Float.parseFloat( xmlParser.getText() ); } } eventType = xmlParser.next(); } } catch( XmlPullParserException e ) { /* ignore */ } catch( IOException e ) {/* ignore */ } } /** * Create a NMEA GPRMC sentence * * @param longitude * @param latitude * @param elevation * @param speed in mps * @return */ public static String createGPRMCLocationCommand( double longitude, double latitude, double elevation, double speed ) { speed *= 0.51; // from m/s to knots final String COMMAND_GPS = "GPRMC," + "%1$02d" + // hh c.get(Calendar.HOUR_OF_DAY) "%2$02d" + // mm c.get(Calendar.MINUTE) "%3$02d." + // ss. c.get(Calendar.SECOND) "%4$03d,A," + // ss, c.get(Calendar.MILLISECOND) "%5$03d" + // llll latDegree "%6$09.6f," + // latMinute "%7$c," + // latDirection (N or S) "%8$03d" + // longDegree "%9$09.6f," + // longMinutett "%10$c," + // longDirection (E or W) "%14$.2f," + // Speed over ground in knot "0," + // Track made good in degrees True "%11$02d" + // dd "%12$02d" + // mm "%13$02d," + // yy "0," + // Magnetic variation degrees (Easterly var. subtracts from true course) "E," + // East/West "mode"; // Just as workaround.... Calendar c = Calendar.getInstance(); double absLong = Math.abs( longitude ); int longDegree = (int) Math.floor( absLong ); char longDirection = 'E'; if( longitude < 0 ) { longDirection = 'W'; } double longMinute = ( absLong - Math.floor( absLong ) ) * 60; double absLat = Math.abs( latitude ); int latDegree = (int) Math.floor( absLat ); char latDirection = 'N'; if( latitude < 0 ) { latDirection = 'S'; } double latMinute = ( absLat - Math.floor( absLat ) ) * 60; String command = String.format( COMMAND_GPS, c.get( Calendar.HOUR_OF_DAY ), c.get( Calendar.MINUTE ), c.get( Calendar.SECOND ), c.get( Calendar.MILLISECOND ), latDegree, latMinute, latDirection, longDegree, longMinute, longDirection, c.get( Calendar.DAY_OF_MONTH ), c.get( Calendar.MONTH ), c.get( Calendar.YEAR ) - 2000 , speed); return command; } public static String createGPGGALocationCommand( double longitude, double latitude, double elevation ) { final String COMMAND_GPS = "GPGGA," + // $--GGA, "%1$02d" + // hh c.get(Calendar.HOUR_OF_DAY) "%2$02d" + // mm c.get(Calendar.MINUTE) "%3$02d." + // ss. c.get(Calendar.SECOND) "%4$03d," + // sss, c.get(Calendar.MILLISECOND) "%5$03d" + // llll latDegree "%6$09.6f," + // latMinute "%7$c," + // latDirection "%8$03d" + // longDegree "%9$09.6f," + // longMinutett "%10$c," + // longDirection "1,05,02.1,00545.5,M,-26.0,M,,"; Calendar c = Calendar.getInstance(); double absLong = Math.abs( longitude ); int longDegree = (int) Math.floor( absLong ); char longDirection = 'E'; if( longitude < 0 ) { longDirection = 'W'; } double longMinute = ( absLong - Math.floor( absLong ) ) * 60; double absLat = Math.abs( latitude ); int latDegree = (int) Math.floor( absLat ); char latDirection = 'N'; if( latitude < 0 ) { latDirection = 'S'; } double latMinute = ( absLat - Math.floor( absLat ) ) * 60; String command = String.format( COMMAND_GPS, c.get( Calendar.HOUR_OF_DAY ), c.get( Calendar.MINUTE ), c.get( Calendar.SECOND ), c.get( Calendar.MILLISECOND ), latDegree, latMinute, latDirection, longDegree, longMinute, longDirection ); return command; } class SimplePosition { public float speed; public double lat, lng; public SimplePosition(float latitude, float longtitude) { this.lat = latitude; this.lng = longtitude; } } public void sendSMS( String string ) { this.sender.sendCommand( "sms send 31886606607 " + string + "\r\n" ); } }