/*------------------------------------------------------------------------------
** 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 edu.stanford.cs.sujogger.actions.utils;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.nio.channels.FileChannel;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
import org.xmlpull.v1.XmlSerializer;
import edu.stanford.cs.gaming.sdk.model.Obj;
import edu.stanford.cs.gaming.sdk.model.ObjProperty;
import edu.stanford.cs.gaming.sdk.service.GamingServiceConnection;
import edu.stanford.cs.sujogger.R;
import edu.stanford.cs.sujogger.db.GPStracking;
import edu.stanford.cs.sujogger.db.GPStracking.Media;
import edu.stanford.cs.sujogger.db.GPStracking.Segments;
import edu.stanford.cs.sujogger.db.GPStracking.Tracks;
import edu.stanford.cs.sujogger.db.GPStracking.Waypoints;
import edu.stanford.cs.sujogger.util.Constants;
import edu.stanford.cs.sujogger.viewer.TrackList;
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.provider.MediaStore.MediaColumns;
import android.util.Log;
import android.util.Xml;
import android.widget.Toast;
/**
* Create a GPX version of a stored track
*
* @version $Id: GpxCreator.java 474 2010-04-14 20:33:50Z rcgroot $
* @author rene (c) Mar 22, 2009, Sogeti B.V.
*/
public class GpxCreator extends XmlCreator
{
public static final String NS_SCHEMA = "http://www.w3.org/2001/XMLSchema-instance";
public static final String NS_GPX_11 = "http://www.topografix.com/GPX/1/1";
public static final String DATETIME = "yyyy-MM-dd'T'HH:mm:ss'Z'";
private String mChosenBaseFileName;
private Intent mIntent;
private XmlCreationProgressListener mProgressListener;
private Context mContext;
private boolean mPublish;
private String TAG = "OGT.GpxCreator";
private GamingServiceConnection mGamingServiceConn;
public GpxCreator(Context context, Intent intent, String chosenBaseFileName, XmlCreationProgressListener listener, GamingServiceConnection gamingServiceConn, boolean publish)
{
mChosenBaseFileName = chosenBaseFileName;
mContext = context;
mIntent = intent;
mProgressListener = listener;
mGamingServiceConn = gamingServiceConn;
mPublish = publish;
}
public void run()
{
Looper.prepare();
Uri trackUri = mIntent.getData();
int _id = 0;
int duration = 0;
double distance = 0;
String fileName = "UntitledTrack";
long creationTime = 0;
int userId = 0;
if( mChosenBaseFileName != null && !mChosenBaseFileName.equals( "" ) )
{
fileName = mChosenBaseFileName;
}
else
{
Cursor trackCursor = null;
ContentResolver resolver = mContext.getContentResolver();
try
{
trackCursor = resolver.query( trackUri, new String[] { Tracks.NAME, Tracks._ID, Tracks.DISTANCE, Tracks.DURATION }, null, null, null );
if( trackCursor.moveToLast() )
{
fileName = trackCursor.getString( 0 );
Log.d(TAG, "Name is: " + fileName);
_id = trackCursor.getInt(1);
Log.d(TAG, "ID is: " + _id);
distance = trackCursor.getDouble(2);
Log.d(TAG, "Distance is: " + distance);
duration = trackCursor.getInt(3);
Log.d(TAG, "Duration is: " + duration);
}
} catch (Exception e) {
e.printStackTrace();
}
finally
{
if( trackCursor != null )
{
trackCursor.close();
}
}
}
if (mPublish) {
Cursor trackCursor = null;
ContentResolver resolver = mContext.getContentResolver();
try
{
trackCursor = resolver.query( trackUri, new String[] { Tracks.NAME, Tracks._ID, Tracks.DISTANCE, Tracks.DURATION, Tracks.USER_ID, Tracks.CREATION_TIME }, null, null, null );
if( trackCursor.moveToLast() )
{
_id = trackCursor.getInt(1);
Log.d(TAG, "ID is: " + _id);
distance = trackCursor.getDouble(2);
Log.d(TAG, "Distance is: " + distance);
duration = trackCursor.getInt(3);
Log.d(TAG, "Duration is: " + duration);
userId = trackCursor.getInt(4);
creationTime = trackCursor.getLong(5);
}
} catch (Exception e) {
e.printStackTrace();
}
finally
{
if( trackCursor != null )
{
trackCursor.close();
}
}
try {
Log.d(TAG, "Object publishing to server");
if( mProgressListener != null )
{
mProgressListener.startNotification( fileName );
mProgressListener.updateNotification( getProgress(), getGoal() );
}
XmlSerializer serializer = Xml.newSerializer();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
BufferedOutputStream buf = new BufferedOutputStream(baos, 8192 );
serializer.setOutput( buf, "UTF-8" );
serializeTrack( trackUri, serializer );
Obj obj = new Obj();
obj.obj_type = "track";
obj.object_properties = new ObjProperty[8];
ObjProperty idProp = new ObjProperty();
idProp.name = "_id";
idProp.prop_type = GamingServiceConnection.OBJ_PROPERTIES_INT;
idProp.int_val = _id;
obj.object_properties[0] = idProp;
ObjProperty userProp = new ObjProperty();
userProp.name = "user_id";
userProp.prop_type = GamingServiceConnection.OBJ_PROPERTIES_INT;
userProp.int_val = userId;
obj.object_properties[1] = userProp;
ObjProperty timeProp = new ObjProperty();
timeProp.name = "creation_time";
timeProp.prop_type = GamingServiceConnection.OBJ_PROPERTIES_FLOAT;
timeProp.float_val = creationTime;
obj.object_properties[2] = timeProp;
ObjProperty nameProp = new ObjProperty();
nameProp.name = "name";
nameProp.prop_type = GamingServiceConnection.OBJ_PROPERTIES_STRING;
nameProp.string_val = fileName;
obj.object_properties[3] = nameProp;
ObjProperty trackUriProp = new ObjProperty();
trackUriProp.name = "trackUri";
trackUriProp.prop_type = GamingServiceConnection.OBJ_PROPERTIES_STRING;
trackUriProp.string_val = trackUri.toString();
obj.object_properties[4] = trackUriProp;
ObjProperty distanceProp = new ObjProperty();
distanceProp.name = "distance";
distanceProp.prop_type = GamingServiceConnection.OBJ_PROPERTIES_FLOAT;
// distanceProp.float_val = (float) distance;
// distanceProp.float_val = 3.0;
distanceProp.float_val = distance;
Log.d(TAG, "ASLAI DISTANCE IS: " + distanceProp.float_val);
obj.object_properties[5] = distanceProp;
ObjProperty durationProp = new ObjProperty();
durationProp.name = "duration";
durationProp.prop_type = GamingServiceConnection.OBJ_PROPERTIES_INT;
durationProp.int_val = duration;
Log.d(TAG, "ASLAI DURATION IS: " + durationProp.int_val);
obj.object_properties[6] = durationProp;
ObjProperty trackProp = new ObjProperty();
trackProp.name = "gpx";
trackProp.prop_type = GamingServiceConnection.OBJ_PROPERTIES_STRING;
trackProp.string_val = baos.toString();
obj.object_properties[7] = trackProp;
mGamingServiceConn.createObj(TrackList.PUBLISH_TRACK, obj);
Log.d(TAG, "Object published to server");
} catch (Exception e) {
e.printStackTrace();
} finally {
if( mProgressListener != null )
{
mProgressListener.endNotification( fileName );
}
Looper.loop();
}
} else {
if( !( fileName.endsWith( ".gpx" ) || fileName.endsWith( ".xml" ) ) )
{
setExportDirectoryPath( Environment.getExternalStorageDirectory() + Constants.EXTERNAL_DIR + fileName );
setXmlFileName( fileName + ".gpx" );
}
else
{
setExportDirectoryPath( Environment.getExternalStorageDirectory() + Constants.EXTERNAL_DIR + fileName.substring( 0, fileName.length() - 4 ) );
setXmlFileName( fileName );
}
new File( getExportDirectoryPath() ).mkdirs();
String xmlFilePath = getExportDirectoryPath() + "/" + getXmlFileName();
if( mProgressListener != null )
{
mProgressListener.startNotification( fileName );
mProgressListener.updateNotification( getProgress(), getGoal() );
}
String resultFilename = xmlFilePath;
try
{
XmlSerializer serializer = Xml.newSerializer();
BufferedOutputStream buf = new BufferedOutputStream( new FileOutputStream( xmlFilePath ), 8192 );
serializer.setOutput( buf, "UTF-8" );
serializeTrack( trackUri, serializer );
if( isNeedsBundling() )
{
resultFilename = bundlingMediaAndXml( fileName, ".zip" );
}
fileName = new File( resultFilename ).getName();
CharSequence text = mContext.getString( R.string.ticker_stored ) + "\"" + fileName + "\"";
Toast toast = Toast.makeText( mContext.getApplicationContext(), text, Toast.LENGTH_SHORT );
toast.show();
}
catch( FileNotFoundException e )
{
Log.e( TAG, "Unable to save " + e );
CharSequence text = mContext.getString( R.string.ticker_failed ) + "\"" + xmlFilePath + "\"" + mContext.getString( R.string.error_filenotfound );
Toast toast = Toast.makeText( mContext.getApplicationContext(), text, Toast.LENGTH_LONG );
toast.show();
}
catch( IllegalArgumentException e )
{
Log.e( TAG, "Unable to save " + e );
CharSequence text = mContext.getString( R.string.ticker_failed ) + "\"" + xmlFilePath + "\"" + mContext.getString( R.string.error_filename );
Toast toast = Toast.makeText( mContext.getApplicationContext(), text, Toast.LENGTH_LONG );
toast.show();
}
catch( IllegalStateException e )
{
Log.e( TAG, "Unable to save " + e );
CharSequence text = mContext.getString( R.string.ticker_failed ) + "\"" + xmlFilePath + "\"" + mContext.getString( R.string.error_buildxml );
Toast toast = Toast.makeText( mContext.getApplicationContext(), text, Toast.LENGTH_LONG );
toast.show();
}
catch( IOException e )
{
Log.e( TAG, "Unable to save " + e );
CharSequence text = mContext.getString( R.string.ticker_failed ) + "\"" + xmlFilePath + "\"" + mContext.getString( R.string.error_writesdcard );
Toast toast = Toast.makeText( mContext.getApplicationContext(), text, Toast.LENGTH_LONG );
toast.show();
}
finally
{
if( mProgressListener != null )
{
mProgressListener.endNotification( resultFilename );
}
Looper.loop();
}
}
}
private void serializeTrack( Uri trackUri, XmlSerializer serializer ) throws IllegalArgumentException, IllegalStateException, IOException
{
serializer.startDocument( "UTF-8", true );
serializer.setPrefix( "xsi", NS_SCHEMA );
serializer.setPrefix( "gpx", NS_GPX_11 );
serializer.text( "\n" );
serializer.startTag( "", "gpx" );
serializer.attribute( null, "version", "1.1" );
serializer.attribute( null, "creator", "edu.stanford.cs.sujogger" );
serializer.attribute( NS_SCHEMA, "schemaLocation", NS_GPX_11 + " http://www.topografix.com/gpx/1/1/gpx.xsd" );
serializer.attribute( null, "xmlns", NS_GPX_11 );
// Big header of the track
String name = serializeTrackHeader( 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( serializer, Uri.withAppendedPath( trackUri, "segments" ) );
serializer.text( "\n" );
serializer.endTag( "", "trk" );
serializer.text( "\n" );
serializer.endTag( "", "gpx" );
serializer.endDocument();
}
private String serializeTrackHeader( 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.text( "\n" );
serializer.startTag( "", "metadata" );
serializer.text( "\n" );
serializer.startTag( "", "time" );
Date time = new Date( trackCursor.getLong( 2 ) );
DateFormat formater = new SimpleDateFormat( DATETIME );
serializer.text( formater.format( time ) );
serializer.endTag( "", "time" );
serializer.text( "\n" );
serializer.endTag( "", "metadata" );
}
}
finally
{
if( trackCursor != null )
{
trackCursor.close();
}
}
return name;
}
private void serializeSegments( XmlSerializer serializer, Uri segments ) throws IOException
{
Cursor segmentCursor = null;
ContentResolver resolver = mContext.getContentResolver();
try
{
segmentCursor = resolver.query( segments, new String[] { Segments._ID }, null, null, null );
if( segmentCursor.moveToFirst() )
{
if( mProgressListener != null )
{
mProgressListener.updateNotification( getProgress(), getGoal() );
}
do
{
Uri waypoints = Uri.withAppendedPath( segments, segmentCursor.getLong( 0 ) + "/waypoints" );
serializer.text( "\n" );
serializer.startTag( "", "trkseg" );
serializeWaypoints( serializer, waypoints );
serializer.text( "\n" );
serializer.endTag( "", "trkseg" );
}
while( segmentCursor.moveToNext() );
}
}
finally
{
if( segmentCursor != null )
{
segmentCursor.close();
}
}
}
private void serializeWaypoints( XmlSerializer serializer, Uri waypoints ) throws IOException
{
Cursor waypointsCursor = null;
ContentResolver resolver = mContext.getContentResolver();
try
{
waypointsCursor = resolver.query( waypoints, new String[] { Waypoints.LONGITUDE, Waypoints.LATITUDE, Waypoints.TIME, Waypoints.ALTITUDE, Waypoints._ID }, null, null, null );
if( waypointsCursor.moveToFirst() )
{
increaseGoal( waypointsCursor.getCount() );
do
{
increaseProgress( 1 );
if( mProgressListener != null )
{
mProgressListener.updateNotification( getProgress(), getGoal() );
}
serializer.text( "\n" );
serializer.startTag( "", "trkpt" );
serializer.attribute( null, "lat", Double.toString( waypointsCursor.getDouble( 1 ) ) );
serializer.attribute( null, "lon", Double.toString( waypointsCursor.getDouble( 0 ) ) );
serializer.text( "\n" );
serializer.startTag( "", "ele" );
serializer.text( Double.toString( waypointsCursor.getDouble( 3 ) ) );
serializer.endTag( "", "ele" );
serializer.text( "\n" );
serializer.startTag( "", "time" );
Date time = new Date( waypointsCursor.getLong( 2 ) );
DateFormat formater = new SimpleDateFormat( DATETIME );
serializer.text( formater.format( time ) );
serializer.endTag( "", "time" );
serializeWaypointDescription( mContext, serializer, Uri.withAppendedPath( waypoints, waypointsCursor.getLong( 4 ) + "/media" ) );
serializer.text( "\n" );
serializer.endTag( "", "trkpt" );
}
while( waypointsCursor.moveToNext() );
}
}
finally
{
if( waypointsCursor != null )
{
waypointsCursor.close();
}
}
}
private void serializeWaypointDescription( Context context, XmlSerializer serializer, Uri media ) throws IOException
{
String mediaPathPrefix = Environment.getExternalStorageDirectory().getAbsolutePath() + Constants.EXTERNAL_DIR;
Cursor mediaCursor = null;
ContentResolver resolver = context.getContentResolver();
try
{
mediaCursor = resolver.query( media, new String[] { Media.URI }, null, null, null );
if( mediaCursor.moveToFirst() )
{
do
{
Uri mediaUri = Uri.parse( mediaCursor.getString( 0 ) );
if( mediaUri.getScheme().equals( "file" ) )
{
if( mediaUri.getLastPathSegment().endsWith( "3gp" ) )
{
serializer.text( "\n" );
serializer.startTag( "", "link" );
serializer.attribute( null, "href", includeMediaFile( mediaPathPrefix + mediaUri.getLastPathSegment() ) );
serializer.startTag( "", "text" );
serializer.text( mediaUri.getLastPathSegment() );
serializer.endTag( "", "text" );
serializer.endTag( "", "link" );
}
else if( mediaUri.getLastPathSegment().endsWith( "jpg" ) )
{
serializer.text( "\n" );
serializer.startTag( "", "link" );
serializer.attribute( null, "href", includeMediaFile( mediaPathPrefix + mediaUri.getLastPathSegment() ) );
serializer.startTag( "", "text" );
serializer.text( mediaUri.getLastPathSegment() );
serializer.endTag( "", "text" );
serializer.endTag( "", "link" );
}
else if( mediaUri.getLastPathSegment().endsWith( "txt" ) )
{
serializer.text( "\n" );
serializer.startTag( "", "desc" );
BufferedReader buf = new BufferedReader( new FileReader( mediaUri.getEncodedPath() ) );
String line;
while( ( line = buf.readLine() ) != null )
{
serializer.text( line );
serializer.text( "\n" );
}
serializer.endTag( "", "desc" );
}
}
else if( mediaUri.getScheme().equals( "content" ) )
{
if( mediaUri.getAuthority().equals( GPStracking.AUTHORITY + ".string" ) )
{
serializer.text( "\n" );
serializer.startTag( "", "name" );
serializer.text( mediaUri.getLastPathSegment() );
serializer.endTag( "", "name" );
}
else if( mediaUri.getAuthority().equals( "media" ) )
{
Cursor mediaItemCursor = null;
try
{
mediaItemCursor = resolver.query( mediaUri, new String[] { MediaColumns.DATA, MediaColumns.DISPLAY_NAME }, null, null, null );
if( mediaItemCursor.moveToFirst() )
{
serializer.text( "\n" );
serializer.startTag( "", "link" );
serializer.attribute( null, "href", includeMediaFile( mediaItemCursor.getString( 0 ) ) );
serializer.startTag( "", "text" );
serializer.text( mediaItemCursor.getString( 1 ) );
serializer.endTag( "", "text" );
serializer.endTag( "", "link" );
}
}
finally
{
if( mediaItemCursor != null )
{
mediaItemCursor.close();
}
}
}
}
}
while( mediaCursor.moveToNext() );
}
}
finally
{
if( mediaCursor != null )
{
mediaCursor.close();
}
}
}
}