/*------------------------------------------------------------------------------ ** Ident: Delivery Center Java ** Author: rene ** Copyright: (c) Jan 21, 2010 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. *------------------------------------------------------------------------------ */ package nl.sogeti.android.gpstracker.actions.utils; import java.io.BufferedOutputStream; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.Date; import nl.sogeti.android.gpstracker.R; import nl.sogeti.android.gpstracker.actions.ExportGPX; import nl.sogeti.android.gpstracker.db.GPStracking.Segments; import nl.sogeti.android.gpstracker.db.GPStracking.Tracks; import nl.sogeti.android.gpstracker.db.GPStracking.Waypoints; import org.xmlpull.v1.XmlSerializer; import android.content.ContentResolver; import android.content.Context; import android.content.Intent; import android.database.Cursor; import android.net.Uri; import android.os.Environment; import android.os.Looper; import android.util.Log; import android.util.Xml; import android.widget.Toast; public class GpxCreator extends Thread { private String mChosenFileName; private Intent mIntent; private GpxCreationProgressListener mProgressListener; private Context mContext; private int mProgress = 0; private int mGoal = 0; public GpxCreator(Context context, Intent intent, String chosenFileName, GpxCreationProgressListener listener) { mChosenFileName = chosenFileName; mContext = context; mIntent = intent; mProgressListener = listener; } public void run() { Looper.prepare(); Uri trackUri = mIntent.getData(); String fileName = "UntitledTrack"; if( mChosenFileName != null && !mChosenFileName.equals( "" )) { fileName = mChosenFileName; } else { Cursor trackCursor = null; ContentResolver resolver = mContext.getContentResolver(); try { trackCursor = resolver.query( trackUri, new String[] { Tracks.NAME }, null, null, null ); if( trackCursor.moveToLast() ) { fileName = trackCursor.getString( 0 ); } } finally { if( trackCursor != null ) { trackCursor.close(); } } } String filePath; if( !( fileName.endsWith( ".gpx" ) || fileName.endsWith( ".xml" ) ) ) { filePath = Environment.getExternalStorageDirectory() +"/OpenGPSTracker/"+fileName; fileName = fileName + ".gpx"; } else { filePath = Environment.getExternalStorageDirectory() +"/"+fileName.substring( 0, fileName.length()-4 ); } new File( filePath ).mkdirs(); filePath = filePath+"/"+fileName; if( mProgressListener != null ) { mProgressListener.startNotification( fileName ); mProgressListener.updateNotification( mProgress, mGoal ); } try { XmlSerializer serializer = Xml.newSerializer(); BufferedOutputStream buf = new BufferedOutputStream( new FileOutputStream( filePath ), 8192 ); serializer.setOutput( buf, "UTF-8" ); serializer.startDocument( "UTF-8", true ); serializer.setPrefix( "xsi", ExportGPX.NS_SCHEMA ); serializer.setPrefix( "gpx", ExportGPX.NS_GPX_11 ); serializer.startTag( "", "gpx" ); serializer.attribute( null, "version", "1.1" ); serializer.attribute( null, "creator", "nl.sogeti.android.gpstracker" ); serializer.attribute( ExportGPX.NS_SCHEMA, "schemaLocation", ExportGPX.NS_GPX_11 + " http://www.topografix.com/gpx/1/1/gpx.xsd" ); serializer.attribute( null, "xmlns", ExportGPX.NS_GPX_11 ); // Big header of the track String name = serializeTrack( mContext, serializer, trackUri ); serializer.text( "\n" ); serializer.startTag( "", "trk" ); serializer.text( "\n" ); serializer.startTag( "", "name" ); serializer.text( name ); serializer.endTag( "", "name" ); // The list of segments in the track serializeSegments( mContext, serializer, Uri.withAppendedPath( trackUri, "segments" ) ); serializer.text( "\n" ); serializer.endTag( "", "trk" ); serializer.text( "\n" ); serializer.endTag( "", "gpx" ); serializer.endDocument(); CharSequence text = mContext.getString( R.string.ticker_stored )+"\"" + fileName+"\""; Toast toast = Toast.makeText( mContext.getApplicationContext(), text, Toast.LENGTH_SHORT ); toast.show(); } catch (IllegalArgumentException e) { Log.e( ExportGPX.TAG, "Unable to save " + e ); CharSequence text = mContext.getString( R.string.ticker_failed )+"\"" + filePath+"\"" + mContext.getString( R.string.error_filename ); Toast toast = Toast.makeText( mContext.getApplicationContext(), text, Toast.LENGTH_LONG ); toast.show(); } catch (IllegalStateException e) { Log.e( ExportGPX.TAG, "Unable to save " + e ); CharSequence text = mContext.getString( R.string.ticker_failed )+"\"" + filePath+"\"" + mContext.getString( R.string.error_buildxml ); Toast toast = Toast.makeText( mContext.getApplicationContext(), text, Toast.LENGTH_LONG ); toast.show(); } catch (IOException e) { Log.e( ExportGPX.TAG, "Unable to save " + e ); CharSequence text = mContext.getString( R.string.ticker_failed )+"\"" + filePath+"\"" + mContext.getString( R.string.error_writesdcard ); Toast toast = Toast.makeText( mContext.getApplicationContext(), text, Toast.LENGTH_LONG ); toast.show(); } finally { if( mProgressListener != null ) { mProgressListener.endNotification( filePath ); } Looper.loop(); } } private String serializeTrack( Context context, XmlSerializer serializer, Uri trackUri ) throws IOException { ContentResolver resolver = context.getContentResolver(); Cursor trackCursor = null; String name = null; try { trackCursor = resolver.query( trackUri, new String[] { Tracks._ID, Tracks.NAME, Tracks.CREATION_TIME }, null, null, null ); if( trackCursor.moveToFirst() ) { name = trackCursor.getString( 1 ); serializer.startTag( "", "metadata" ); serializer.startTag( "", "time" ); Date time = new Date( trackCursor.getLong( 2 ) ); DateFormat formater = new SimpleDateFormat( ExportGPX.DATETIME ); serializer.text( formater.format( time ) ); serializer.endTag( "", "time" ); serializer.endTag( "", "metadata" ); } } finally { if( trackCursor != null ) { trackCursor.close(); } } return name; } private void serializeSegments( Context context, XmlSerializer serializer, Uri segments ) throws IOException { Cursor segmentCursor = null; ContentResolver resolver = context.getContentResolver(); try { segmentCursor = resolver.query( segments, new String[] { Segments._ID }, null, null, null ); if( segmentCursor.moveToFirst() ) { if( mProgressListener != null ) { mProgressListener.updateNotification( mProgress, mGoal ); } do { Uri waypoints = Uri.withAppendedPath( segments, "/" + segmentCursor.getLong( 0 ) + "/waypoints" ); serializer.text( "\n" ); serializer.startTag( "", "trkseg" ); serializeWaypoints( context, serializer, waypoints ); serializer.text( "\n" ); serializer.endTag( "", "trkseg" ); } while (segmentCursor.moveToNext()); } } finally { if( segmentCursor != null ) { segmentCursor.close(); } } } private void serializeWaypoints( Context context, XmlSerializer serializer, Uri waypoints ) throws IOException { Cursor waypointsCursor = null; ContentResolver resolver = context.getContentResolver(); try { waypointsCursor = resolver.query( waypoints, new String[] { Waypoints.LONGITUDE, Waypoints.LATITUDE, Waypoints.TIME, Waypoints.ALTITUDE, Waypoints.ACCURACY }, null, null, null ); if( waypointsCursor.moveToFirst() ) { mGoal += waypointsCursor.getCount(); do { mProgress++; if( mProgressListener != null ) { mProgressListener.updateNotification(mProgress, mGoal); } serializer.text( "\n" ); serializer.startTag( "", "trkpt" ); serializer.attribute( null, "lat", waypointsCursor.getString( 1 ) ); serializer.attribute( null, "lon", waypointsCursor.getString( 0 ) ); serializer.text( "\n" ); serializer.startTag( "", "ele" ); serializer.text( waypointsCursor.getString( 3 ) ); serializer.endTag( "", "ele" ); serializer.text( "\n" ); serializer.startTag( "", "time" ); Date time = new Date( waypointsCursor.getLong( 2 ) ); DateFormat formater = new SimpleDateFormat( ExportGPX.DATETIME ); serializer.text( formater.format( time ) ); serializer.endTag( "", "time" ); serializer.text( "\n" ); serializer.startTag( "", "name" ); serializer.text( "point_" + waypointsCursor.getPosition() ); serializer.endTag( "", "name" ); serializer.text( "\n" ); serializer.endTag( "", "trkpt" ); } while (waypointsCursor.moveToNext()); } } finally { if( waypointsCursor != null ) { waypointsCursor.close(); } } } }