private void saveAndMoveCursor(final String fileName,final LogFile headerRecord,final Cursor cursor){
  try {
    cursor.moveToPrevious();
    File file=new File(fileName);
    Writer bw=new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file.getAbsoluteFile()),"UTF-8"),30 * 1024);
    bw.write(XML_HEADER);
    bw.write(logToXml(headerRecord.getManufacturer(),headerRecord.getModel(),headerRecord.getRevision(),headerRecord.getSwid(),headerRecord.getSwVersion(),mExportVersion));
    long previousBeginId=0;
    String previousEnd="";
    int i=0;
    while (i < CELLS_PER_FILE && cursor.moveToNext()) {
      final long beginId=Long.valueOf(cursor.getString(mColBeginPosId));
      final String currentBegin=positionToXml(cursor.getLong(mColReqTimestamp),cursor.getDouble(mColReqLon),cursor.getDouble(mColReqLat),cursor.getDouble(mColReqAlt),cursor.getDouble(mColReqHead),cursor.getDouble(mColReqSpeed),cursor.getDouble(mColReqAcc),"begin");
      final String currentEnd=positionToXml(cursor.getLong(mColLastTimestamp),cursor.getDouble(mColLastLon),cursor.getDouble(mColLastLat),cursor.getDouble(mColLastAlt),cursor.getDouble(mColLastHead),cursor.getDouble(mColLastSpeed),cursor.getDouble(mColLastAcc),"end");
      if (i == 0) {
        bw.write(scanToXml(cursor.getLong(mColTimestamp)));
        bw.write(currentBegin);
      }
 else {
        if (beginId != previousBeginId) {
          bw.write(previousEnd);
          bw.write(CLOSE_SCAN_TAG);
          bw.write(scanToXml(cursor.getLong(mColTimestamp)));
          bw.write(currentBegin);
        }
      }
      bw.write(cellToXML(cursor.getInt(mColIsServing),cursor.getInt(mColIsNeigbor),cursor.getString(mColMcc),cursor.getString(mColMnc),cursor.getString(mColLac),cursor.getString(mColLogicalCellId),cursor.getString(mColActualCellId),cursor.getString(mColUtranRnc),cursor.getString(mColStrengthDbm),cursor.getString(mColStrengthAsu),cursor.getInt(mColNetworkType),cursor.getString(mColPsc)));
      previousBeginId=beginId;
      previousEnd=currentEnd;
      i++;
    }
    bw.write(previousEnd);
    bw.write(CLOSE_SCAN_TAG);
    bw.write(CLOSE_LOGFILE);
    bw.close();
    file=null;
    bw=null;
  }
 catch (  final IOException ioe) {
    cursor.close();
    Log.e(TAG,ioe.toString(),ioe);
  }
}

private void saveAndMoveCursor ( final String fileName , final LogFile headerRecord , final Cursor cursor ) { try { cursor . moveToPrevious ( ) ; File file = new File ( fileName ) ; Writer bw = new BufferedWriter ( new OutputStreamWriter ( new FileOutputStream ( file . getAbsoluteFile ( ) ) , "UTF-8" ) , 30 * 1024 ) ; bw . write ( XML_HEADER ) ; bw . write ( logToXml ( headerRecord . getManufacturer ( ) , headerRecord . getModel ( ) , headerRecord . getRevision ( ) , headerRecord . getSwid ( ) , headerRecord . getSwVersion ( ) , mExportVersion ) ) ; long previousBeginId = 0 ; String previousEnd = "" ; int i = 0 ; while ( i < CELLS_PER_FILE && cursor . moveToNext ( ) ) { final long beginId = Long . valueOf ( cursor . getString ( mColBeginPosId ) ) ; final String currentBegin = positionToXml ( cursor . getLong ( mColReqTimestamp ) , cursor . getDouble ( mColReqLon ) , cursor . getDouble ( mColReqLat ) , cursor . getDouble ( mColReqAlt ) , cursor . getDouble ( mColReqHead ) , cursor . getDouble ( mColReqSpeed ) , cursor . getDouble ( mColReqAcc ) , "begin" ) ; final String currentEnd = positionToXml ( cursor . getLong ( mColLastTimestamp ) , cursor . getDouble ( mColLastLon ) , cursor . getDouble ( mColLastLat ) , cursor . getDouble ( mColLastAlt ) , cursor . getDouble ( mColLastHead ) , cursor . getDouble ( mColLastSpeed ) , cursor . getDouble ( mColLastAcc ) , "end" ) ; if ( i == 0 ) { bw . write ( scanToXml ( cursor . getLong ( mColTimestamp ) ) ) ; bw . write ( currentBegin ) ; } else { if ( beginId != previousBeginId ) { bw . write ( previousEnd ) ; bw . write ( CLOSE_SCAN_TAG ) ; bw . write ( scanToXml ( cursor . getLong ( mColTimestamp ) ) ) ; bw . write ( currentBegin ) ; } } bw . write ( cellToXML ( cursor . getInt ( mColIsServing ) , cursor . getInt ( mColIsNeigbor ) , cursor . getString ( mColMcc ) , cursor . getString ( mColMnc ) , cursor . getString ( mColLac ) , cursor . getString ( mColLogicalCellId ) , cursor . getString ( mColActualCellId ) , cursor . getString ( mColUtranRnc ) , cursor . getString ( mColStrengthDbm ) , cursor . getString ( mColStrengthAsu ) , cursor . getInt ( mColNetworkType ) , cursor . getString ( mColPsc ) ) ) ; previousBeginId = beginId ; previousEnd = currentEnd ; i ++ ; } bw . write ( previousEnd ) ; bw . write ( CLOSE_SCAN_TAG ) ; bw . write ( CLOSE_LOGFILE ) ; bw . close ( ) ; file = null ; bw = null ; } catch ( final IOException ioe ) { cursor . close ( ) ; Log . e ( TAG , ioe . toString ( ) , ioe ) ; } }
builds a valid cell log file . the number of records per file is limited ( chunk_size ) . once the limit is reached , a new file has to be created . the file is saved at the specific location . a log file file consists of an header with basic information on cell manufacturer and model , software id and version . below the log file header , scans are inserted . each scan can contain several wifis
